Forum: Mikrocontroller und Digitale Elektronik LCD "PWB16202" an PIC18F65J50


von Max V. (herr_vorragend)


Angehängte Dateien:

Lesenswert?

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

von Max V. (herr_vorragend)


Lesenswert?

Kann mir niemand helfen?

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Max Vorragend schrieb:
> Kann mir niemand helfen?
1
>   default: lcd_send_data(get_spec_char(ch));  //Zeichen an LCD senden

 Und wo ist lcd_send_data und lcd_send_command ?

: Bearbeitet durch User
von Max V. (herr_vorragend)


Lesenswert?

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

von Max V. (herr_vorragend)


Lesenswert?

Oder liegt ein Missverständnis vor? Deine Frage war schon, wo die 
Funktionen definiert sind?

mfg
Herr Vorragend

von Max V. (herr_vorragend)


Lesenswert?

Bekomme ich keine Hilfe mehr hier?

von Marco S (Gast)


Lesenswert?

Möglicherweise ein Timingproblem.

LCD_EN = _OFF;//0;                 //Oberes Nibble senden
LCD_EN = _ON;//1;

ist vielleicht ein bisschen schnell. Warum nicht:

RS, RW, Dx setzen
t_as abwarten
E high setzen
PW_EH warten
E low setze
t_Cycle erfüllen.

von Max V. (herr_vorragend)


Lesenswert?

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?

von Chris B. (dekatz)


Lesenswert?

#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 !!!

von Max V. (herr_vorragend)


Lesenswert?

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
static void tlcd_out(unsigned char data) //Sendet eine 4-bit Ausgabeoperation an das LCD
2
{
3
    LCD_D4 = checkbit(4,data);
4
    LCD_D5 = checkbit(5,data);
5
    LCD_D6 = checkbit(6,data);
6
    LCD_D7 = checkbit(7,data);
7
8
    tlcd_enable();
9
}
1
unsigned char checkbit (unsigned char pos, unsigned char var)
2
{
3
    return ((1 << pos) & var);
4
}

Vielen Dank für die Hilfe!

von Chris B. (dekatz)


Lesenswert?

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);

von holger (Gast)


Lesenswert?

>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:
1
unsigned char checkbit (unsigned char pos, unsigned char var)
2
{
3
  if((1 << pos) & var) return 1;
4
  return 0;
5
}

Wobei variables schieben fast immer teuer ist.
Einfach nur:

 if(data & (1<<4)) LCD_D4 = 1;
 else LCD_D4 = 0;

würde es schneller tun.

von Max V. (herr_vorragend)


Lesenswert?

Vielen Dank Chris & Holger,

Mit der Vorlage aus dem Tutorial und Holgers Korrektur meiner 
Checkbit-Funktion läuft das Display nun endlich!

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.