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
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...
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
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
@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.
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
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
|
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)
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.
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)
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 ?
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?
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
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.
jo wäre echt super, meld dich dann einfach bei mir. {entfernt} oder ist dir icq,skype oder msn lieber ?
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.
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
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
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
@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
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
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.
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
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
@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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.