Hallo Leute!
Ich bin neu hier im Forum und sitze seit ein paar Tagen an einem Problem
mit dem ich nicht weiter komme.
In Sachen Elektronik habe ich wenig Erfahrung, aber C/C++ ist mir nicht
völlig fremd.
Ziel ist es, ein LCD mit KS0066 kompatiblen Treiber im 4bit Modus mit
einem Atmel Atmega8 anzusteuern. Der Betrieb im 8bit Modus ist mir
bereits gelungen, aber warum die 4Pins opfern, wenns auch ohne geht.
Zur Hardware:
μC: Wie oben erwähnt, Atmel Atmega8-16PU
LCD: ANAG VISION AV1624 (Datenblatt hier:
http://www.produktinfo.conrad.com/datenblaetter/175000-199999/183342-da-01-ml-LCD_Modul_16x2_Zeichen_de_en.pdf)
Konfiguration: Die Pins E, RS und RW werden von PortC, Pins 5, 3 und 4
angesteuert. Die Datenleitungen 7, 6, 5, 4 liegen in gleicher
Reihenfolge an den Pins 7, 6, 5, 4 des PortD. Ich habe keine
Veränderungen zum 8bit Betrieb vorgenommen. Außer die überflüssigen
Datenleitungen zu entfernen.
Ich gehe davon aus, dass von der Hardware-Seite her alles in Ordnung
ist, da es ja im 8bit Modus schon funktionierte.
Zur Software:
IDE: Atmel Studio 6.1
C-Code: Siehe unten.
In der "lcd_init()"-Methode habe ich versucht das
Initialisierungsprotokoll aus dem Datenblatt (Seite 4, Figure 2)
umzusetzen. Leider finde ich meinen Fehler / meine Fehler nicht.
Vielleicht hat jemand einen Lösungsvorschlag?
Mir ist klar, dass ich einfach schon vorhandenen Code verwenden könnte.
(Sicher der leichte Weg.)Ich möchte es aber selbst umsetzten.
Vielen Dank für Eure Hilfe!
Grüße.
Das ist mir schon klar, aber das untere Nibble am Datenport hängt in der
Luft. (Es ist nichts am μC angeschlossen.) Deshalb kann ich ja einfach
mal alle Pins auf 1 setzen und 2x das Enable Signal senden.
An der Stelle war allerdings trotzdem ein Fehler. Ich habe zuerst die
Daten in den Datenport geschrieben und dann die "LCD_CheckBusy()"
Methode aufgerufen. Diese schaltet den Datenport aber von output auf
input und wieder zurück => Es steht irgendwas in diesem Register. Dieser
Fehler ist nun behoben. Die neue main() Methode siehe unten. Leider
funktioniert es immer noch nicht. Der Rest des Codes blieb unverändert.
1
intmain(void)
2
{
3
_delay_ms(100);
4
lcd_init();// init LCD in 4bit mode
5
6
/* print character 0x88 on LCD to verify correct init */
Du fragst in deiner Busy-Flag-Check-Funktion (schönes Wort ;-) ) das
falsche Register ab, nämlich PORTD (Zustand der Pullup-Widerstände) und
nicht PIND (High oder Low liegt am Eingang an).
Außerdem muss zur Abfrage des Busy-Flags immer am Enable-Anschluss
"gewackelt" werden und die Abfrage während des High-Pegels erfolgen:
http://www.ece.uidaho.edu/ee/classes/ECE341/datasheets/SamsungKS0066U.pdf
(Seite 19, Figure 5).
Die fehlenden Wartezeiten bzw. fehlenden Busy-Abfragen in der lcd_init()
nach dem Umschalten auf den 4-bit-Modus könnten noch ein Problem sein.
Auf Seite 2 des im Eingangspost verlinkten Datenblatts bzw. auf Seite 18
in der Samsung-Anleitung steht, wie lange die einzelnen Kommandos zur
Ausführung benötigen (Execution Time), und auf S. 4 des Datenblatts gibt
es den Hinweis, dass die Wartezeit länger als die Execution Time sein
oder man das Busy-Flag abfragen muss.
Spendiere doch zunächst in der lcd_init() mal testweise ein bisschen
Wartezeit (10ms), nachdem ein Kommando komplett übertragen worden ist,
damit der Controller die Befehle verarbeiten kann. Wenn damit alles
funktioniert, kannst du den Delay durch eine Busy-Flag-Abfrage ersetzen
und schauen, ob deine Routine richtig ist.
Es kann natürlich auch sein, dass nichts angezeigt wird, weil der Befehl
"Display off" (0x08) bzw. bei dir 0x00 gefolgt von 0x80 sowohl das
Display als auch den Cursor deaktiviert.
Was mir auch noch auffällt: Zwischen der Übertragung des oberen und
unteren Nibbles wird das Busy-Flag nicht abgefragt. Ein sehr
übersichtliches Schema für den 4-bit-Transfer gibt es in diesem PDF auf
Seite 22: https://www.sparkfun.com/datasheets/LCD/HD44780.pdf.
Vielen Dank für deine Hinweise Felix!
Mit der Abfrage des Busy-Flags zwischen den Nibbles und dem exakten
Timing aus dem Datenblatt läuft es jetzt. :-)