Forum: Mikrocontroller und Digitale Elektronik LCD - komme nicht weiter


von g1o (Gast)


Angehängte Dateien:

Lesenswert?

hallo

ich hab vor ein paar tagen schon einmal geschrieben...
also nochmal von vorne:
ich hab ein LCD Display ANAG VISION 4*20 Zeichen (Datenblatt im
anhang)
soweit ich das gesehen habe läuft es im 4-bit modus.
ich habe das tutorial hier auf der seite durchgearbeitet, aber das
display zeigt nur die 1. und 3. zeile schwarz an (was heißt dass es
funktioniert, strom bekommt etc, aber eine daten empfängt)

http://www.mikrocontroller.net/forum/read-1-212877.html
hier habe ich auch mal reingeschaut und bin zu dem entschluss gekommen,
dass das timing nicht stimmt !
aber ich weiß nicht wie ich das ändern muss.
ich habe einen ATMega16, der mit 7,3728 MHZ läuft.
kann mir jemand sagen wie ich jetzt das timing für den
initialisierungsprozess ändern muss ? am besten anhand des codes der im
toturial verwendet wird.

grüße g1o

von AVRli (Gast)


Lesenswert?

Ich weiß nun leider nicht welche Taktfrequenz im Tutorial verwendet
wurde, es könnte sein das Du die Wartezeiten anpassen mußt.

Kannst du überprüfen ob die richtigen Daten auch anliegen an den
entsprechenden PIN's?

Gruß AVRli...

von Stefan (Gast)


Lesenswert?

Welches Timing möchtest du denn verwenden?

Aus dem von dir beigelegten PDF geht nicht hervor, welches Timing man
verwenden muss. Einmal könnte das das Timing für den KS0066 Controller
sein oder für einen KS0066 äquivalenten Controller. Kannst du am
Display ausmachen, welcher Controller konkret verbaut ist?

Der Anschluss ist OK? Vgl. mit 3.
http://www.dst-gmbh.de/avkat/userman.htm
Wie sind die unbenutzten Eingänge D0-D3 beschaltet?

Die Initialisierung ist OK? Vgl. mit Figure 2
http://www.dst-gmbh.de/avkat/init.htm

Die Kommandos sind OK und die Ausführungszeiten werden beachtet bzw.
das Busyflag wird abgefragt? Vgl. mit
http://www.dst-gmbh.de/avkat/commands.htm

von g1o (Gast)


Lesenswert?

also richtig angeschlossen ist das lcd meiner meinung nach.

im tutorial wurde ein 4mhz atmega 8  verwendet.

leider kann ich am lcd display nicht erkennen welcher controller
verwendet ist.
aber da wo ich das datenblatt her habe stand controller:
KSS0066

wie muss ich den code aus dem tutorial nun verändern, damit er zu
meinem 7,3728 MHZ chip passt ?


grüße g1o

von g1o (Gast)


Lesenswert?

@Stefan: also:
Der Anschluss ist OK? Ja
Die Initialisierung ist OK? Nein

ich denke auch da liegt der fehler. wie gesagt, ich weiß nicht wie das
timing aussehen muss.

von Karl heinz B. (kbucheg)


Lesenswert?

Mit einem zu langem Timing liegst du nie falsch.
Also wenn du sonst nichts anderes hast: Mach die Warteschleifen
mal um einen Faktor 3 bis 5 länger.
Läuft es dann an, dann kannst du das Timing immer noch verkürzen

von Stefan (Gast)


Lesenswert?

Im Tutorial für 4 MHz betriebene AVR sind diese Warteroutinen drin:
1
 ;Pause nach jeder Übertragung
2
delay50us:                              ;50us Pause
3
           ldi  temp1, $42
4
delay50us_:dec  temp1
5
           brne delay50us_
6
           ret                          ;wieder zurück
7
8
 ;Längere Pause für manche Befehle
9
delay5ms:                               ;5ms Pause
10
           ldi  temp1, $21
11
WGLOOP0:   ldi  temp2, $C9
12
WGLOOP1:   dec  temp2
13
           brne WGLOOP1
14
           dec  temp1
15
           brne WGLOOP0
16
           ret

Es handelt sich um einfache Warteschleifen (Däumchendreher).

Wenn die 50µs Wartezeit bei 4 MHz $42 (66) Schleifen erfordern,
brauchen sie bei 7,3728 MHz genau ($42/4)*7,3728 Schleifen. Das sind
ungefähr 122 bzw. $7A.

Wenn die 5ms Wartezeit bei 4 MHz eine doppelte Schleife mit $C9 (201)
in der inneren Schleife und $21 (33) in der äußeren Schleife benötigt,
sind es bei 7,3728 MHz 369 (*) und 61 ($3D). (*) ist ein Überlauf für
einen Bytewert, d.h. du musst die Schleife umbauen.

In erster Näherung würde ich für die innere Schleife 122 ($7A) nehmen
und für die äussere Schleife 100 ($64).
1
 ;Pause nach jeder Übertragung
2
delay50us:                              ;50us Pause
3
           ldi  temp1, $7A
4
delay50us_:dec  temp1
5
           brne delay50us_
6
           ret                          ;wieder zurück
7
8
 ;Längere Pause für manche Befehle
9
delay5ms:                               ;5ms Pause
10
           ldi  temp1, $64
11
WGLOOP0:   ldi  temp2, $7A
12
WGLOOP1:   dec  temp2
13
           brne WGLOOP1
14
           dec  temp1
15
           brne WGLOOP0
16
           ret

Dann geht es an die eigentliche Initialisierung. Im Tutorial ist das
dieser Abschnitt:
1
lcd_init:
2
           ldi  temp3,50
3
powerupwait:
4
           rcall  delay5ms
5
           dec  temp3
6
           brne powerupwait
7
           ldi temp1, 0b00000011        ;muss 3mal hintereinander
8
gesendet
9
           out PORTD, temp1             ;werden zur Initialisierung
10
           rcall lcd_enable             ;1
11
           rcall delay5ms
12
           rcall lcd_enable             ;2
13
           rcall delay5ms
14
           rcall lcd_enable             ;und 3!
15
           rcall delay5ms
16
           ldi temp1, 0b00000010        ;4bit-Modus einstellen
17
           out PORTD, temp1
18
           rcall lcd_enable
19
           rcall delay5ms
20
           ldi temp1, 0b00101000        ;noch was einstellen...
21
           rcall lcd_command
22
           ldi temp1, 0b00001100        ;...nochwas...
23
           rcall lcd_command
24
           ldi temp1, 0b00000100        ;endlich fertig
25
           rcall lcd_command
26
           ret

Dein Augenmerk sollte auf die Zeilen nach dem Kommentar "noch was
einstellen..." fallen.

In Figure 2 http://www.dst-gmbh.de/avkat/init.htm erkennt man, dass die
Anzahl der Displayzeilen und der Zeichensatz eingestellt werden müssen.
Bei deinem Display wären das nacheinander die Kommandos

0b00101000
0b00001000
0b00000001 <=====
0b000001xx

Die markierte Zeile ist in den Routinen aus dem Tutorial nicht dabei.
Sie löscht das Display. Mag sein, dass dies dafür verantwortlich ist,
dass du den schwarzen Balken beibehälst... In "neu" würde die
Initialisierung so aussehen:
1
lcd_init:
2
           ldi  temp3,50
3
powerupwait:
4
           rcall  delay5ms
5
           dec  temp3
6
           brne powerupwait
7
           ldi temp1, 0b00000011        ;muss 3mal hintereinander
8
gesendet
9
           out PORTD, temp1             ;werden zur Initialisierung
10
           rcall lcd_enable             ;1
11
           rcall delay5ms
12
           rcall lcd_enable             ;2
13
           rcall delay5ms
14
           rcall lcd_enable             ;und 3!
15
           rcall delay5ms
16
           ldi temp1, 0b00000010        ;4bit-Modus einstellen
17
           out PORTD, temp1
18
           rcall lcd_enable
19
           rcall delay5ms
20
           ldi temp1, 0b00101000        ;Display lines (2) and font
21
(5x7 dots)...
22
           rcall lcd_command
23
           ldi temp1, 0b00001100        ;...Display off...
24
           rcall lcd_command
25
           ldi temp1, 0b00000001        ;...und Display clear...
26
           rcall lcd_command
27
           ldi temp1, 0b00000100        ;...Entry mode set.
28
           rcall lcd_command
29
           ret

von g1o (Gast)


Lesenswert?

hab alles versucht und es klappt immernoch nicht :(

von g1o (Gast)


Lesenswert?

habe grad auch mal die 6 leitungen von port D durchgemessen. es kommen
alle am lcd display an, also denke ich liegt es an der software !

@ Stefan danke erstmal für die ausführung ! soweit hab ichs jetzt
verstanden, aber stimmt diese zeile ?

ldi temp1, 0b00101000 ;Display lines (2) and font (5x7 dots)...

es müssten doch 4 zeilen sein oder ? (4*20 zeichen)

von Stefan (Gast)


Lesenswert?

Obacht.

Die Anzeigezeilen sind nicht mit den Ansteuerzeilen zu verwechseln.
Logisch werden 2 Zeilen verwaltet, bloss anzeigemäßig sind die Zeilen
gegeneinander versetzt umgebrochen.

Die 1. Ansteuerzeile (DDRAM Adressen 00-27) ist die 1. und 3.
Anzeigezeile und die 2. Ansteuerzeile (DDRAM Adressen 40-67) ist die 2.
und 4. Anzeigezeile.

Siehe Grafik auf http://www.dst-gmbh.de/avkat/av2040.htm ganz unten und
vergleiche die Adressen.

von g1o (Gast)


Lesenswert?

achso ok.
aber woran kann es denn jetzt noch liegen ?
der controller KSS0066 ist doch kombatibel zum 4-bit modus oder ?

irgendwie flackert das display nichtmal beim initialisieren... (es wird
ja in den routinen ein und ausgeschaltet)

von g1o (Gast)


Lesenswert?

grade nochmal nachgesehen, es könnte auch sein das als controller ein
LSI KS0076B und als Segmenttreiber ein KS0063 eingebaut sind.
das display und die controller sind aber HD44780 kompatibel.

könnt ihr mir mit diesen infos weiterhelfen ?

von Stefan (Gast)


Lesenswert?

Das Display wird nur ein und ausgeschaltet, wenn von deinem ATMega16 die
richtigen Signale in der richtigen Reihenfolge und im richtigen Abstand
an dem Controller ankommen. Der KS0076B sollte kompatibel zum
beschriebenen KS0066 sein.

Back to the roots...

Bitte mache ein Schaltbild oder ein Foto, wie du den ATMega16 mit dem
Display physikalisch verbunden hast.

Hast du bereits eine oder mehrere der Leitungen statt mit dem LCD mit
einer Low-Current Spion-LED mit Vorwiderstand betrieben, d.h. du bist
sicher, dass das Programm im ATMega16 läuft?

von g1o (Gast)


Lesenswert?

also ich habe das display ohne jeglichen schnick schnack angeschlossen.
nur ein poti zwischen masse und vcc.
die restliche belegung sieht so aus:
erste spalte:display
zweite spalte: microcontroller

pin 1(Vss)   GND
pin 2(Vcc)   5V
pin 3(Vee)   Poti (zwischen GND und 5V)
pin 4(RS)    PortD 4
pin 5(RW)    GND
pin 6(E)     PortD 5
pin 7-10     GND
pin 11       PortD 0
pin 12       PortD 1
pin 13       PortD 2
pin 14       PortD 3

das ist genau wie im tutorial und auch wie es im datenblatt des
displays steht. also eigentlich kann hier der fehler nicht liegen,
sondern eher in der software oder ?

hab alles shcon mit nem durchlaufmesser getestet, kein leiterwiderstand
ist größer als 1 ohm.
und der atmega16 ist auch nicht defekt, er hat immer funktioniert.
(habe an jedem port einen pfostenstecker und an jedem port hab ich ne
test platine mit 8 leds angeschlossen und die leitungen auf ausgang
geschaltet. alle leds haben geleuchtet)


grüße g1o

von Stefan (Gast)


Lesenswert?

Ich bin mit meiner Ferndiagnose am Ende.

Die richtigen Portpins bei der Umsetzung der Verdrahtung vom ATMega8
auf den ATMega16 wirst du sicher gefunden haben und ob der µC
tatsächlich mit der eingestellten Taktrate läuft, merkt man
normalerweise auch.

Ich werde bei Gelegenheit hingehen und den Aufbau aus dem Tutorial auf
einem Experimentierbrett nachstellen.

von g1o (Gast)


Lesenswert?

jo wäre echt super, meld dich dann einfach bei mir.
{entfernt}
oder ist dir icq,skype oder msn lieber ?

von Stefan (Gast)


Lesenswert?

So einfach wie ich dachte, ist es mit dem selbst versuchen nicht. Auf
meinen zwei Basteldisplays ist jeweils ein anderer Controller drauf.

Aber ich habe ich Zeit genutzt und bin tiefer in die Datenblätter
eingestiegen. Zunächst ist es eine grosse *Controllerkonfusion*:

Die Sequenz aus dem AVR Tutorial (T) ist für den HD44780 Controller
oder kompatible Controller. Auf deinem Datenblatt (D) wird der KS0066
als Controller genannt und du hast auf dem Display den KS0076
identifiziert.

Die KS00.. Controller werden von Samsung gebaut. Eine besonders
zuverlässige Quelle müssten also die Datenblätter vom Hersteller (H)
sein. Diese gibt es z.B. auf http://www.pacificdisplay.com/lcd_ics.htm

Vergleicht man Tutorial (T) mit deinem Datenblatt (D), so sind die
Anweisungen nahezu identisch. Aber vergleicht man das mit den
Herstellerdatenblättern (H, S.27), so ist beim KS0066 schon ein
Unterschied zu sehen.


Tutorial    Datenblatt  Hersteller  Bedeutung
===================================================
250 ms      > 40 ms     > 30 ms     Hardware-Reset
            nach V=...  nach V=...  abwarten. Länger
                                    schadet nicht!

ENABLE... 1x Daten für D0-D3
0b****0011  0b****0011  ----------  * = irrelevant,
5 ms        > 4.1 ms                wird nicht
0b****0011  0b****0011  ----------  übertragen
5 ms        > 100 µs
0b****0011  0b****0011  ----------  Function Set 8-Bit
5 ms        > 40 µs
0b****0010  0b****0010  0b****0010  Function Set 4-Bit
5 ms        > 40 µS     > 39 µs

COMMAND... 2x Daten für D0-D3
0b00101000  0b0010NF**  0b0010NF**  N=1 F=0 = 0b00101000
50 µs       > 40 µS     > 39 µs     2 Zeilen 5x7 Font
0b00001100  0b00001000  0b00001DBC  Display on(T)/off(D)
50 µs       > 40 µs     > 39 µs
----------  0b00000001  0b00000001  Clear display
            82µs-1.64ms > 1.53 ms
0b00000100  0b00000100  0b00000100  Entry mode set
50 µs       > 40 µs     > 39 µs

Man erkennt: Alles ist anders ;-)

Der KS0066 hat dat Zusatzkommando 'Clear Display' mit langer
Wartezeit und das fehlt in der Tutorialsource und in deinem Datenblatt.


Und nach dem Herstellerdatenblatt wird der KS0066 am Anfang nicht
dreimal mit 'Function Set 8-Bit Mode' gefüttert.

Statt Display ON wird bei (D) ein Display OFF verwendet und bei (H)
scheint das egal zu sein.

Für den KS0076 ist leider keine solche Initialisierungssequenz per
Instruktionen angegeben. Aus dem Datenblatt ist erkennbar, dass die
Befehle etwas länger dauern z.B. Clear Display > 1.64 ms.

Ich würde bei den nächsten Versuchen auf jeden Fall den Clear Display
Befehl in die Sequenz einfügen.

Und ich würde mal mit der Sequenz (H) starten ohne die 3x Function Set
8-Bit. Vielleicht verwirrt das den Controller, dass mit einer 8-Bit
Initialisierungssequenz gestartet wird, die dann nicht weitergeführt
wird.

von Michael U. (Gast)


Lesenswert?

Hallo,

habe jetzt nicht nach Unterschieden gesucht, aber mein KS0073 will etwa
20ms Pause nach PowerOn,
dann die 0x03 an die Daten, RS auf 0 (Control) dann
E-Clock, 5ms Pause,
E-Clock, 5ms Pause,
E-Clock, 5ms Pause

Hier nur einmal takten, das Display ist immernoch im 8Bit-Mode, also
NICHT beide Nibble senden!

Ab hier scheint das Senden beider Nibble richtig zu sein

Danach kommt die normale Initialisierung
        ldi     TEMP_A,$20                  ; 4Bit - Mode
        rcall   lcd_control

        ldi     TEMP_A,$2C                  ; Extension aktivieren
        rcall   lcd_control

        ldi     TEMP_A,$09                  ; 4 Zeilen
        rcall   lcd_control

        ldi     TEMP_A,$20                  ; Extension wieder aus
        rcall   lcd_control

        ldi     TEMP_A,$06                  ; Increment, Not Shiftet
        rcall   lcd_control

        ldi     TEMP_A,$10                  ; Cursor Move, Shift off
        rcall   lcd_control

        ldi     TEMP_A,$0C                  ; Display an, Cursor aus
        rcall   lcd_control

        ldi     TEMP_A,$01                  ; Display löschen
        rcall   lcd_control

Extension war bei mir nur wegen 4-Zeilen-Mode nötig.

Clock hat bei mir auch 3 nop drin, bei 8MHz wollte es schon manchmal
nicht, kann aber auch am Steckbrett gelegen haben...

Gruß aus Berlin
Michael

von Johannes A. (Gast)


Lesenswert?

Hi g1o,

hast Du es schon mal mit D4..D7 vom LCD probiert?

Immerhin liegt das Busbreiten-Umschaltbit auf D4, und im
KS0066-Datenblatt steht: "When interfacing data length are 4 bit, only
4 ports, from DB4 to DB7, are used as data bus."

Gruß Johannes

von Michael U. (Gast)


Lesenswert?

Hallo,

wenn seine Beschreibung oben nicht falsch ist, hat er D0-3 auf GND und
D4-7 an D0-3 vom AVR. Sollte also schon ok sein.

Gruß aus Berlin
Michael

von Benedikt W. (Gast)


Lesenswert?

@Michael U. und Stefan: euere posts les ich gleich !

@Johannes A.: ja es ist so wie Michael sagt 4-7 hängt am µC und 0-3
sind GND

von Benedikt W. (Gast)


Lesenswert?

also zu der sache mit den controllerunterschieden, bin ich mir nicht
sicher...
also im katalog stand dass KS0076 verbaut sind, aber würde eher dem
datenblatt trauen. nur dass ich ihn identifizieren konnte stimmt ja
nicht so ganz.
also eher der KS0066 ! also welche befehlsequenz war es jetzt für ihn
?
ich könnte die dann ja in den code einbauen  (also den
initialisierungsprozess) und als interrupts jeweils 300ms einbauen oder
kann ein interrupt zu lange sein ? auf jedenfall wäre dann der
risikofaktor timing ausgeschlossen.

grüße g1o

von Stefan (Gast)


Lesenswert?

Vorerst nix mit Interrupts machen, sondern bei dem Beispiel aus dem
Tutorial bleiben. Dort sind die Warteroutinen einfache Zählschleifen.
Interrupts sind im jetzigen Stadium viel zu kompiiziert.

Welche Routine nehmen? Beide, nacheinander. Wenn die eine (D) nicht
geht, dann auch die andere (H) probieren.

Was machst du eigentlich, wenn eine Testroutine nicht funktioniert hat?
Im Datenblatt vom Controller steht was, dass man nach dem Function Set
Befehl mit dem Setzen der Linien und des Fonts diesen Befehl per
Software nicht mehr schicken soll.

Ich interpretiere das so, dass dann vor dem nächsten
Initialisierungsversuch ein Hardware-Reset erforderlich ist. Und das
heisst bei unzugänglicher RESET-Leitung am LCD-Controller, dass man das
Display wohl stromlos machen muss.

von Johannes A. (Gast)


Lesenswert?

Ich hab unter
http://www.mikrocontroller.net/forum/read-1-432367.html#new
einen neuen Thread zum Thema angelegt.
Inkl. funktionierendem Code nebst Anmerkungen zur Portierung.

Gruß Johannes

von Karsten D. (karstendonat)


Lesenswert?

Hatte das Problem auch. Habs zu erst auch auf den Zeichensatz geschoben 
da ich ne Japanische Version eines Displays hab. Da ist der Zeichensatz 
anders aber es gibt auch lateinsiche Zeichen.

Es war aber einfach nur eine kalte Lötstelle. Einen Kurzschluss wirst du 
da nicht unbedingt rausklingeln. Mal alle nachlöten.

Ciao

Karsten

von norad (Gast)


Lesenswert?

@g1o!

Michael hat Recht.

/* LCD Ansteuerung in C im 4 -Bitmodus

  Es wird nur ein Port benötigt.
  Um ein Zeichen zum Display zu übertragen  wird zuerst das High-Nibble
  und danach Low-Nibble gesendet
  Es werden nur die Datenleitungen D4 - D7 sowie RS,R/W und EN vom  LCD 
- Display benötigt und
  müssen an einem Port des Mikrocontrollers angeschlossen werden.
  LCD      PORT (frei wählbar)
  D4    -    P0.0
  D5    -        P0.1
  D6       -    P0.2
  D7    -    P0.3
  EN    -    P0.4  Steursignal Enable damit wird ein Zeichen oder Befehl 
übertragen
  R/W    -    P0.5  Steursignal READ  WRITE Schreib  Lese befehl
  RS    -    P0.6  Steursignal  RS bestimmt ob Daten oder Instruktion 
gesendet wird



So habe ich es Damal gemacht. Vielleicht hilft es dir weiter

von Elektronikfan (Gast)


Lesenswert?

Hallo,

hatte auch massig Probleme bei der Inbetriebnahme. Falls Deine Software 
das Busy-bit abfrägt kann die Sache nicht laufen, da Du WR auf Masse 
liegen hast.
Dann kann man nicht lesen. WR benötigt ein PORT-bit am Prozessor (aber 
nur bei Programm mit Busybit-Abfrage).

Weiss jemand wie ich nicht am Anfang der Displayzeile was reinschreibe 
und anzeige? DDRAMadresse setzen und anschliessend Daten schreiben 
funktioniert nicht.

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.