Forum: Mikrocontroller und Digitale Elektronik AVR Tutorial Problem mit Uhr Programm


von Jens N. (naumstar)


Lesenswert?

Abend zusammen.

Ich bin gerade dran das Avr Tutorial durch zu arbeiten, und bin bei dem 
Programm Uhr http://www.mikrocontroller.net/articles/AVR-Tutorial:_Uhr
auf folgendes Problem gestoßen:
Dass Display zeigt gar nichts an, es wird nur ein schwarzer Balgen 
angezeigt, als wäre das Display nicht Initialisiert. Ich habe dass 
Programm schon durch den Avr Simulator laufen lassen, und es scheint 
alles zu funktionieren, soweit ich dass beurteilen kann.
Das Display ist dieses 
Hier:http://www.reichelt.de/Hintergrund-gruen/LCD-162F-LED/3/index.html?&ACTION=3&LA=2&ARTICLE=31655&GROUPID=3005&artnr=LCD+162F+LED

Ich nutze noch folgende Dinge:
Eigenbau Board streng nach Tutorial mit ATmega 8
Original Atmel ISP MK2
AVR Studio 4 (Das 6.1 hab ich auch, ist mir aber für den Anfang zu 
überfrachtet)


Was ich noch zu meinem Problem hinzufügen muss: Die anderen Test 
Programme liefen alle auf meinem Controller. Auch dass Programm aus dem 
LCD Tutorial lief einwandfrei, und auf meinem LCD erschien der Text 
TEST.

Wenn jemand eine Zündende Idee hat, wäre ich sehr dankbar.
Ich Suche da jetzt schon seit Wochen dran, und seh den Wald vor lauter 
Bäumen nicht mehr.

Gruss Jens

von holger (Gast)


Lesenswert?

>Eigenbau Board streng nach Tutorial mit ATmega 8

Welche Taktfrequenz?

>Dass Display zeigt gar nichts an, es wird nur ein schwarzer Balgen
>angezeigt, als wäre das Display nicht Initialisiert.

Dann sind entweder die delays fürs Display zu kurz
oder die Pinbelegung stimmt nicht.

von Jens N. (naumstar)


Lesenswert?

Mit 4MHZ, externer Oszillator. Den habe ich in den Fuses auch angewählt.

Kann die Pin belegung trotzdem falsch sein, obwohl das Display in einem 
anderen Programm funktioniert?

von holger (Gast)


Lesenswert?

>Kann die Pin belegung trotzdem falsch sein, obwohl das Display in einem
>anderen Programm funktioniert?

Sicher, dazu müsste man aber deine Pinbelegung wissen
und auch mal das komplette Programm sehen. Alles andere ist nur raten.

von Jens N. (naumstar)


Lesenswert?

Pinnummer
LCD   Bezeichnung   Anschluss
1   VSS   GND (beim TC1602E: VCC)
2   VCC   +5 V (beim TC1602E: Gnd)
3   VEE   GND oder Poti
4   RS   PD4 am AVR
5   RW   GND
6   E   PD5 am AVR
7   DB0   nicht angeschlossen
8   DB1   nicht angeschlossen
9   DB2   nicht angeschlossen
10   DB3   nicht angeschlossen
11   DB4   PD0 am AVR
12   DB5   PD1 am AVR
13   DB6   PD2 am AVR
14   DB7   PD3 am AVR
15   A   Vorsicht! Meistens nicht direkt an +5 V abschließbar,
sondern nur über einen Vorwiderstand, der an die Daten
der Hintergrundbeleuchtung angepasst werden muss.
16   K   GND

Dass ist die Pinbelegung die ich verwendet habe, ist die aus dem 
Tutorial und stimmt so weit ich gesehen habe exakt mit der aus dem 
Datenblatt des Displays über ein.

Dass Programm ist direkt in dem ersten Link den ich im Startpost 
gepostet habe.

von Karl H. (kbuchegg)


Lesenswert?

Jens Naumann schrieb:

> Dass ist die Pinbelegung die ich verwendet habe, ist die aus dem
> Tutorial und stimmt so weit ich gesehen habe exakt mit der aus dem
> Datenblatt des Displays über ein.

Gemeint ist wohl eher, an welche AVR Pins du das LCD angeschlossen hast 
und ob das mit der im Programm verwendeten übereinstimmt.

Wenn du ein Testprogramm hast, in dem das LCD funktioniert, dann sehe 
ich 2 gute Möglichkeiten

Entweder vergleichen, worin sich die beiden in den LCD Routinen 
unterscheiden.
Oder aus dem funktionierenden Programm das Uhrenprogramm entwickeln. 
Letzters ist keine so schlechte Übung, denn mit Copy&Paste 
Programmierung und sich daran erfreuen, dass das Programm welches du 
gerade kopiert hast, lernst du sowieso nicht sehr viel. Wenn du hingegen 
das funktionierende Programm um die Timersachen und die andere Ausgabe 
erweiterst, musst du dich zumindest ein wenig mit dem Code beschäftigen, 
den du gerade kopierst.

von Jens N. (naumstar)


Lesenswert?

Die Lcd Routinen sind in beiden Programmen die gleiche, dass ist ja dass 
Komische.
Ich sehe nur im moment absolut nicht, wo der Fehler im Hauptprogramm 
liegen könnte, bzw wo da noch anpassungen notwendig sind.

Klar lerne ich nichts durch Copy und Paste, allerdings bekomme ich so 
ein wenig Routine im Umgang mit dem Avr Studio, und sehe so schon mal 
den Aufbau von einem funktionierenden Programm.

von Karl H. (kbuchegg)


Lesenswert?

Jens Naumann schrieb:
> Die Lcd Routinen sind in beiden Programmen die gleiche,

Irgendetwas MUSS aber anders sein.
Sonst würde es ja funktionieren.

von Karl H. (kbuchegg)


Lesenswert?

Fang halt mal mit diesem 'abgespeckten' Uhrenprogramm an
1
.include "m8def.inc"
2
 
3
.def temp1 = r16
4
.def temp2 = r17
5
.def temp3 = r18
6
.def flag  = r19
7
 
8
.def SubCount = r21
9
.def Sekunden = r22
10
.def Minuten  = r23
11
.def Stunden  = r24
12
 
13
.org 0x0000
14
        rjmp    main                ; Reset Handler
15
.org OVF0addr
16
        rjmp    timer0_overflow     ; Timer Overflow Handler
17
 
18
.include "lcd-routines.asm"
19
 
20
main:
21
        ldi     temp1, HIGH(RAMEND)
22
        out     SPH, temp1
23
        ldi     temp1, LOW(RAMEND)  ; Stackpointer initialisieren
24
        out     SPL, temp1
25
 
26
        rcall   lcd_init
27
        rcall   lcd_clear
28
29
loop:
30
        rjmp    loop
31
 
32
timer0_overflow:                    ; Timer 0 Overflow Handler
33
        reti

Initialisiert das LCD?

von Jens N. (naumstar)


Lesenswert?

Danke dir Karl Heinz,

mir ist aufgefallen, wenn ich in dein Programm oder das Uhren Programm, 
unter Main noch den Satz:

ldi temp1, 0xFF
out DDRD, temp1

Einfüge, funktioniert das Display.
Das Uhren Programm aus dem Tut funktioniert so auch, wenn ich den Satz 
noch einfüge. Es zählt so auch auch.
Einziges Problem:

Das Display gibt die Zahlen so aus: 0J:0J:0J

Das Display zählt aber trotzdem hoch. Nach zehn Sekunden steht drauf 
0J:0J:1J


Edit: Das Display zeigt jetzt richtig an, hat alles geklappt. Danke noch 
mal an Karl Heinz, dein Tipp die Programme zu vergleichen hat mich 
weiter gebracht. Manch mal denkt man vor lauter lauter nicht an die 
einfachsten Dinge.

Gruß Jens

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Jens Naumann schrieb:
> Danke dir Karl Heinz,
>
> mir ist aufgefallen, wenn ich in dein Programm oder das Uhren Programm,
> unter Main noch den Satz:
>
> ldi temp1, 0xFF
> out DDRD, temp1

Hmm.
Das sollte eigentlich nicht notwendig sein.
Denn lcd_init beginnt so
1
lcd_init:
2
           ldi   temp1, 0xFF            ; alle Pins am Ausgabeport auf Ausgang
3
           out   LCD_DDR, temp1
4
....
setzt sich also selbst die Pins auf Ausgang.

kontrollier mal in deinen LCD-Routinen ob am Anfang LCD_DDR richtig 
gesetzt ist.

: Bearbeitet durch User
von Jens N. (naumstar)


Lesenswert?

Also ich habe diese Routine verwendet:
1
lcd_data:
2
           mov temp2, temp1             ; "Sicherungskopie" für
3
                                        ; die Übertragung des 2.Nibbles
4
           swap temp1                   ; Vertauschen
5
           andi temp1, 0b00001111       ; oberes Nibble auf Null setzen
6
           sbr temp1, 1<<4              ; entspricht 0b00010000 (Anm.1)
7
           out PORTD, temp1             ; ausgeben
8
           rcall lcd_enable             ; Enable-Routine aufrufen
9
                                        ; 2. Nibble, kein swap da es schon
10
                                        ; an der richtigen stelle ist
11
           andi temp2, 0b00001111       ; obere Hälfte auf Null setzen 
12
           sbr temp2, 1<<4              ; entspricht 0b00010000
13
           out PORTD, temp2             ; ausgeben
14
           rcall lcd_enable             ; Enable-Routine aufrufen
15
           rcall delay50us              ; Delay-Routine aufrufen
16
           ret                          ; zurück zum Hauptprogramm
17
 
18
 ; sendet einen Befehl an das LCD
19
lcd_command:                            ; wie lcd_data, nur RS=0
20
           mov temp2, temp1
21
           swap temp1
22
           andi temp1, 0b00001111
23
           out PORTD, temp1
24
           rcall lcd_enable
25
           andi temp2, 0b00001111
26
           out PORTD, temp2
27
           rcall lcd_enable
28
           rcall delay50us
29
           ret
30
 
31
 ; erzeugt den Enable-Puls
32
 ;
33
 ; Bei höherem Takt (>= 8 MHz) kann es notwendig sein, 
34
 ; vor dem Enable High 1-2 Wartetakte (nop) einzufügen. 
35
 ; Siehe dazu http://www.mikrocontroller.net/topic/81974#685882
36
lcd_enable:
37
           sbi PORTD, 5                 ; Enable high
38
           nop                          ; mindestens 3 Taktzyklen warten
39
           nop
40
           nop
41
           cbi PORTD, 5                 ; Enable wieder low
42
           ret                          ; Und wieder zurück                     
43
 
44
 ; Pause nach jeder Übertragung
45
delay50us:                              ; 50µs Pause (bei 4 MHz)
46
           ldi  temp1, $42
47
delay50us_:dec  temp1
48
           brne delay50us_
49
           ret                          ; wieder zurück
50
 
51
 ; Längere Pause für manche Befehle
52
delay5ms:                               ; 5ms Pause (bei 4 MHz)
53
           ldi  temp1, $21
54
WGLOOP0:   ldi  temp2, $C9
55
WGLOOP1:   dec  temp2
56
           brne WGLOOP1
57
           dec  temp1
58
           brne WGLOOP0
59
           ret                          ; wieder zurück
60
 
61
 ; Initialisierung: muss ganz am Anfang des Programms aufgerufen werden
62
lcd_init:
63
           ldi  temp3,50
64
powerupwait:
65
           rcall  delay5ms
66
           dec  temp3
67
           brne powerupwait
68
           ldi temp1, 0b00000011        ; muss 3mal hintereinander gesendet
69
           out PORTD, temp1             ; werden zur Initialisierung
70
           rcall lcd_enable             ; 1
71
           rcall delay5ms
72
           rcall lcd_enable             ; 2
73
           rcall delay5ms
74
           rcall lcd_enable             ; und 3!
75
           rcall delay5ms
76
           ldi temp1, 0b00000010        ; 4bit-Modus einstellen
77
           out PORTD, temp1
78
           rcall lcd_enable
79
           rcall delay5ms
80
           ldi temp1, 0b00101000        ; 4Bit / 2 Zeilen / 5x8
81
           rcall lcd_command
82
           ldi temp1, 0b00001100        ; Display ein / Cursor aus / kein Blinken
83
           rcall lcd_command
84
           ldi temp1, 0b00000100        ; inkrement / kein Scrollen
85
           rcall lcd_command
86
           ret
87
 
88
 ; Sendet den Befehl zur Löschung des Displays
89
lcd_clear:
90
           ldi temp1, 0b00000001   ; Display löschen
91
           rcall lcd_command
92
           rcall delay5ms
93
           ret
94
 
95
 ; Sendet den Befehl: Cursor Home
96
lcd_home:
97
           ldi temp1, 0b00000010   ; Cursor Home
98
           rcall lcd_command
99
           rcall delay5ms
100
           ret

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.