Hallo allerseits,
ich bin seit einigen Tagen wieder an einem älteren Projekt. Es soll eine
universelle Steuerungsplatine mit Funkmodul, Relais, Zeitschaltuhr usw.
werden (bzw. ist es bereits).
Nun, das Problem ist, dass gerade für Zeiteinstellungen ein Display
unerlässlich ist. Verbaut ist ein LCD, welches über I2C angesteuert
wird. Nach unzähligen fehlgeschlagenen Versuchen habe ich dieses erstmal
"ignoriert" und ein paralleles LCD angeschlossen. Es handelt sich dabei
um das Modell "DMC16202 NYU-LY" (2x16) mit einem HD44780-Controller.
Ich möchte es gerne im 4-Bit-Modus betreiben und habe es gemäss den
unzähligen Anleitungen im Internet angeschlossen (DB4-DB7 als
Datenleitungen, RW/EN&RS als Steuerleitungen). Nun bin ich seit einigen
Tagen am testen, doch leider funktioniert immer noch nichts. Die
Initialisierung klappt nicht.
Ich weiss, dass es schon zu viele Threads über dieses Thema gibt, aber
ich habe das Gefühl, dass ich jeden einzelnen durchgekämmt habe. Ist ja
im Prinzip auch nicht schwierig, deshalb verstehe ich ja auch nicht,
warum es bei mir nicht funktionieren will.
Das Display zeigt nach der Initialisierung einen blinkenden Cursor an
zufälliger Position auf der 1. Zeile an. Der Kontrast ist über ein Poti
eingestellt (1. Zeile noch leichte schwarze Flächen, 2. Zeile nichts,
obwohl in Initialisierung auf 2-zeilig eingestellt wird).
Die Initialisierungs-Routine habe ich aus dem Datenblatt übernommen
(http://www.kyocera-display.com/pdf/Dmcman_full.pdf)
Es wäre wirklich nett, wenn sich jemand den Code anschauen könnte. Die
Funktionen habe ich aus Projekten aus der Schule adaptiert. Die main.c
habe ich nicht angehängt, mache noch nichts anderes als die
Initialisierung.
Vielen Dank schonmal!
Herr Vorragend
Vielen Dank für deine Antwort!
lcd_send_data und lcd_send_command sind beide in display_44780.h als
Makros festgelegt. Sie greifen beide auf die lcd_send Funktion zu.
Sollte doch funktionieren so oder nicht?
mfg
Herr Vorragend
Also, nun sieht es folgendermassen aus:
-50ms abwarten
-RW, RS & EN auf 0, Datenpins gemäss Initialisierung HD44780
-25ms abwarten
-EN auf 1 (pos. Flanke)
-25ms abwarten
-EN auf 0 (oberes Nibble senden)
-50ms abwarten
-gleicher Ablauf mit unterem Nibble
Ergebnis: Immer noch genau gleich, Cursor blinkt (an ca. 4. Stelle) auf
1. Zeile, zweite Zeile funktioniert nicht. Der Cursor kann auch nicht
verschoben werden, also muss das Problem ja immer noch in der
Initialisierung liegen...
Noch irgendwelche Ratschläge oder Tipps?
#define lcd_send_command(command) lcd_send(command)
Also ist das ein und das selbe (wozu soll das gut sein???)
Mit dieser Routine sendest du immer oberes UND unteres Nibble eines
Byte.
Nur werden die ersten 4 Initialisierungsschritte im 8-Bit-Mode
durchgeführt bei dem nur die Bits <D7:D4> übertragen werden - das untere
Nibble <D3:D0> nicht.
Siehe in deinem DB Seite 33 !!!
vielen Dank Chris für die Antwort, ich habe nun neue Routinen
geschrieben, bzw. die Vorlage vom Tutorial zur LCD-Ansteuerung
angepasst.
Da ich die Pins des Displays nicht alle auf dem selben Port habe, musste
ich vorallem die "lcd_out"-Routine anpassen. Leider funktioniert die
Initialisierung immer noch nicht.
Funktioniert die Routine so?
1
staticvoidtlcd_out(unsignedchardata)//Sendet eine 4-bit Ausgabeoperation an das LCD
Du brauchst doch nur von deiner ursprüngliche <lcd_send> eine 2. Version
für den 8-Bit-Mode bei der Initialisation wo der Teil mit dem Lower
Nibble wegfällt z.B:
void lcd_send_m8 (unsigned char value){
LCD_EN = _ON;//1; //Pos. Flanke am Enable-Pin
LCD_D7 = bit_test(value,7); //Oberes Daten-Nibble anlegen
LCD_D6 = bit_test(value,6); //
LCD_D5 = bit_test(value,5); //
LCD_D4 = bit_test(value,4); //
delay_ms(1);
LCD_EN = _OFF;//0; //Oberes Nibble senden
delay_us(30); //Maximaler Zeitbedarf einer Übertragung
(blocking)
}
und die ersten 4 Initaliserungsschritte ersetzen durch
lcd_send_m8(0b0011/**/0000); //Auf 8-Bit setzen #1
delay_ms(250);
lcd_send_m8(0b0011/**/0000); // " #2
delay_ms(250);
lcd_send_m8(0b0011/**/0000); // " #3
delay_ms(250);
lcd_send_m8(0b0010/**/0000); //Auf 4-Bit setzen
delay_ms(100);
>Funktioniert die Routine so?
Ich würde sagen: Nein.
checkbit() liefert dir kein Bit zurück sondern ein
unsigned char. Einfach mal Beispiel rechnen:
> LCD_D4 = checkbit(4,data);
checkbit(4,data); liefert 0x00 oder 0x10 zurück.
0x10 passt nicht in ein Bit. In LCD_D4
wird nur das unterste Bit geschrieben, und das ist Null.
Dito für die anderen Aufrufe.
Besser wäre wohl: