Pollin LCD Displays

Gast #883270
Lesenswert?

Hab ein Problem mit einem Pollin LCD Dot Matrix 2 x 20 Display.

Ich sende dem Ding 3 mal 0x03, dann ein 0x02 (4 Bit Modus), dann ein 
0x28 und dann ein 0x0F, jetzt sollte der Cursor blinken und auf der 
ersten Stelle stehen oder ?

Jas manchmal macht er das auch, nur dann nehm ich die Spannung weg, dann 
macht  er das nicht mehr. Dann Spiel ich den Code neu rein, dann macht 
er es manchmal und manchmal auch nicht...

Ich bin am verzweifeln...

hatte noch nie Probleme mit den Displays von Reichelt
Gast #883436
Lesenswert?

"Gast" ist genauso unsinnig wie "Besucher".
Ich habe auch 500ms zwischen 2 Initialisierungsbefehlen. Das Display 
wird ja nur beim Programmstart initialisiert, da kann man auch mal eínen 
Moment warten.

MfG Paul
#883606
Lesenswert?

Paul Baumann wrote:
> "Gast" ist genauso unsinnig wie "Besucher".

Das ist wohl wahr...

> Ich habe auch 500ms zwischen 2 Initialisierungsbefehlen.

Nagut, ich nur vor dem ersten Init-Kommando.

> Das Display
> wird ja nur beim Programmstart initialisiert, da kann man auch mal eínen
> Moment warten.

Nein, warten??? Niemals nie nicht. Man muss unbedingt die höchstmögliche 
Taktfrequenz benutzen, oder besser noch übertakten, und dann überall das 
Timing hart am Limit dimensionieren. Höher, schneller, weiter, nix für 
Weicheier oder Warmduscher... ;-)

>
> MfG Paul

...
#884088
Lesenswert?

Ich kenn zwar das Datenblatt des Pollin-Displays nicht, aber die 
Ansteuerung von Characterdisplays ist quasistandardisiert.
Fehlermöglichkeiten gibt es viele :

Bei der Initialisierung müssen diese Einstellungen passen :
- die R/W-Leitung auf Low
- die Command/Data-Leitung auf Low
- die Enable-Leitung benötigt einen High-Impuls für Datenübernahme

Ansonsten ist ein beliebter Fahler, dass die Datenleitungen verdreht 
sind (MSB vs. LSB).
Gast #884792
Lesenswert?

Ich verwende eigentlich die Funktionen wie hier im Forum beschrieben, 
nur sind meine Datenports nicht an einem Port des Atmels sondern einer 
auf PORT C0 und die anderen auf Port D7 6 und 5. Somit habe ich folgende 
Umformung programmiert die wahrscheinlich nicht funktioniert. Kann da 
mal einer drüberschauen.

void LCD_write_in_ports(unsigned char data)
{
  unsigned char i = 0, data_temp=0;

  cbi(LCD_DATA_4_PORT,LCD_DATA_4_NR);
  cbi(LCD_DATA_5_PORT,LCD_DATA_5_NR);
  cbi(LCD_DATA_6_PORT,LCD_DATA_6_NR);
  cbi(LCD_DATA_7_PORT,LCD_DATA_7_NR);

  while(i < 4)
  {
    data_temp = data;

    if(i == 0) data_temp &= 0x01;
    if(i == 1) data_temp &= 0x02;
    if(i == 2) data_temp &= 0x04;
    if(i == 3) data_temp &= 0x08;

    if((data_temp) && (i == 0)) 
sbi(LCD_DATA_4_PORT,LCD_DATA_4_NR);
    else if((data_temp) && (i == 1)) 
sbi(LCD_DATA_5_PORT,LCD_DATA_5_NR);
    else if((data_temp) && (i == 2)) 
sbi(LCD_DATA_6_PORT,LCD_DATA_6_NR);
    else if((data_temp) && (i == 3)) 
sbi(LCD_DATA_7_PORT,LCD_DATA_7_NR);

    i++;
  }
}
Gast #884799
Lesenswert?

>    if((data_temp) && (i == 0))

Die Abfrage ist falsch. Da werden alle Bits von data_temp 
berücksichtigt.

   if((data_temp & 0x01) && (i == 0))

Allerdings kannst du ne Menge Code sparen wenn du keine Schleife nimmst 
;)
Gast #884845
Lesenswert?

Jetzt bin ich verwirrt. Ist die Funktion jetzt falsch bzw. arbeitet sie 
richtig oder gibt es einen Logik Fehler. Diese Funktion ist essentiell 
für mich, da Sie die 4 Data Ports mit den gewünschten Zuständen speist.
Gast #884852
Lesenswert?

Sieht schon richtig aus, wenn auch umständlich programmiert.

Kleiner Tip:

  cbi(LCD_DATA_4_PORT,LCD_DATA_4_NR);
  cbi(LCD_DATA_5_PORT,LCD_DATA_5_NR);
  cbi(LCD_DATA_6_PORT,LCD_DATA_6_NR);
  cbi(LCD_DATA_7_PORT,LCD_DATA_7_NR);

  if(data & 0x01) sbi(LCD_DATA_4_PORT,LCD_DATA_4_NR);
  if(data & 0x02) sbi(LCD_DATA_5_PORT,LCD_DATA_5_NR);
  if(data & 0x04) sbi(LCD_DATA_6_PORT,LCD_DATA_6_NR);
  if(data & 0x08) sbi(LCD_DATA_7_PORT,LCD_DATA_7_NR);
Gast #884856
Lesenswert?

Mache ich vielleicht bei der Initialsiserung etwas falsch wenn ich 
folgende Kombination schicke.

1.) 500 ms warten
2.) 3 mal 0x03 senden mit 10 ms Pause (RS Low)
3.) 0x02 senden
4.) 0x28 senden
5.) 0x0F senden
6.) 0x06 senden
7.9 LCD_clear();

aus. Ich habe ein 2x16 Zeichen Display von Pollin mit Blauem 
Hintergrund.

R/W liegt auf Masse.
#885911
Lesenswert?

Matthias wrote:
> Die erste Zeile wird immer mit schwarzen Kästchen gefüllt.

Hmmm... Schwarze Kästchen beim blauen LCD?

> Die
> Initialsierung klappt dann nicht oder.

Die pixelaktivierte erste Zeile ist ein Zeichen dafür, dass das LCD 
seinen Selbsttest überstanden hat, dass Spannung anliegt und der 
Kontrast halbwegs vernünftig eingestellt ist, dass aber noch keine 
Initialisierung vom Programm erfolgt ist.

Das kann folgende Ursachen haben (kein Anspruch auf Vollständigkeit):

- Anschlüsse vertauscht
- zu geringe Wartezeit vor dem ersten Zugriff
- falsches Timing zwischen den Zugriffen
- fehlerhafte Routinen
- Irrtum bei der Dimensionierung der Warteschleifen (Startwerte zu groß
  für den Datentyp, Abschneiden der oberen Bits aufgrund zu hoher
  Taktfrequenz)
- Irrtum beim Bestimmen der Taktfrequenz
- Irrtum bei der Zuordnung LCD zum Datenblatt (einige LCDs gleicher
  Bauart haben andere Taktfrequenzen, um z.B. Strom zu sparen, laufen
  sie langsamer)


> Hat keiner Erfahrung mit dem
> Display, was mach ich falsch

Ich besitze dieses LCD nicht, da ich nicht bereit bin, "Blau-Zuschlag" 
zu bezahlen. Wenn Du mir eins sponserst, schreibe ich Dir einen 
funktionierenden Treiber für AVR in ASM. Wenn nicht, auch gut, ich komme 
auch ohne das blaue LCD zurecht, ich habe genug Grüne.

...
Gast #885933
Lesenswert?

>Das kann folgende Ursachen haben (kein Anspruch auf Vollständigkeit):

+ falscher Controller

Könnte auch ein KS066, KS070 oder KS073 sein.

Kaufe kein Display bei Pollin wenn kein vernünftiges Datenblatt
vorhanden ist ;)

Versuch es mal so für KS066
1.) 500 ms warten
3.) 0x02 senden
3.) 0x02 senden
3.) 0x0C senden
5.) 0x0F senden
6.) 0x06 senden
#886304
Lesenswert?

Und noch ein Hinweis :

Oben schreibst Du, dass Du das Display im 4-Bit-Modus betreibst. Da 
liegt die Fehlermöglichkeit der Nibblevertauschung nahe. Eh klar : 
Zuerst das High-Nibble, dann das Low-Nibble. Zwischen zwei 
4-Bit-Zugriffen muss typisch ein Delay von mindestens 40us liegen.

Dass Du es bei der Initialisierung in den 4-Bit-Modus bringst, sieht man 
am Wert 0x28 (Kommando SET FUNCTION).
Gast #887208
Lesenswert?

Ich nehme die Funktionen aus dem Forum, nur schreibe ich mit folgender 
Funktion

  cbi(LCD_DATA_4_PORT,LCD_DATA_4_NR);
  cbi(LCD_DATA_5_PORT,LCD_DATA_5_NR);
  cbi(LCD_DATA_6_PORT,LCD_DATA_6_NR);
  cbi(LCD_DATA_7_PORT,LCD_DATA_7_NR);

  if(data & 0x01) sbi(LCD_DATA_4_PORT,LCD_DATA_4_NR);
  if(data & 0x02) sbi(LCD_DATA_5_PORT,LCD_DATA_5_NR);
  if(data & 0x04) sbi(LCD_DATA_6_PORT,LCD_DATA_6_NR);
  if(data & 0x08) sbi(LCD_DATA_7_PORT,LCD_DATA_7_NR);

die 4 Ports und nict mit PORT_LCD = ....

Somit müsste die High und Low Bit Vertauschung ausgeschlossen sein.
Gast #887264
Lesenswert?

falls es ein hd47xxx (oder so ähnlich) ist :

hast du die 4 nicht benutzten bits auf einen festen pegel gelegt ?
sind es die 4 UNTEREN bits die auf diesem festen pegel liegen ?
über die beiden fehler bin ich auch schonmal gestolpert. hat was 
gedauert bis ichs gefunden habe. seit dem mach ichs IMMER, wenn ich 4 
bit mode nutze.
ansonsten evtl. mal größeres delay (nachdem du dem display gesagt hast 
das es auf 4 bit spielen soll)
Gast #887275
Lesenswert?

>Die unteren 4 Bits sind offen, haben also keinen definierten Pegel.

aua aua ...
das kann (!) die ursache dafür sein. wie gesagt habe einige stunden 
damit zugange gebracht genau diesen fehler zu suchen.
bei mir liegen die pins auf masse (obwohl es auch einige displays gibt 
die dort einen high pegel erwarten wenn ich mich nicht irre)
Gast #889382
Lesenswert?

Kann mir mal einer sagen ob das scheiss Ding nur im 8 Bit Modus geht, 
oder was ?

Ich dreh noch durch... wenn ich das 0x28 sende, springt der Cursor an 
die fünfte Spalte in der Ersten Zeile und wieder zurück....

Wenn ich aber über 0x0F den Cursor ein und über 0x0C ihn ausschalte geht 
das...
#889395
Lesenswert?

ich habe irgendiwe das Gefühl das das Tutorial zum LCD hier völlig 
Sinnlos ist. Offensichtlich schaut eh keiner rein.
D0 - D3 immer auf Low im 4 Bit Modus. Nicht benutzte TTL Eingänge werden 
ja auch auf Low gelegt.


Zum Timing:... wäre was für das Tutorial...

Ich benutze die Char. Display immer in der Timer ISR.
Die läuft konstant mit 6-7ms. Der längste Befehl im 44780 braucht 5,x 
ms.
Alle Befehle werden in der ISR gesendet. Auch das Display wird in der 
ISR
initialisiert und beschrieben. Das Display liegt 1:1 abgebildet im RAM.
Man muss in der Main nur den RAM beschreiben und sich sonst und das 
Display
überhaupt nicht kümmern.
Die Idee stammt nicht von mir, sondern von Andreas Roth.
8051 Kochbuch.
ABER es geht einfach nur. Keine Sorgen mit dem Timing für Anfänger.
Profis haben diese Sorgen eh nicht.
Also Tutorial lesen, Fusebits beachten, Trimmer für Kontrast 
prüfen..usw.
Gast #889405
Lesenswert?

> ich habe irgendiwe das Gefühl das das Tutorial zum LCD hier völlig
> Sinnlos ist. Offensichtlich schaut eh keiner rein.
> D0 - D3 immer auf Low im 4 Bit Modus. Nicht benutzte TTL Eingänge werden
> ja auch auf Low gelegt.

hab ich gemacht...bringt nichts, hab neben mir eine zweite Schaltung mit 
einem Reichelt Display Pin 0 - 3 offen und das Ding geht eins a im 4 Bit 
Modus..soviel dazu

Ansonsten beachte ich wirklich alles... Das Scheiss Ding lässt sich 
einfach nicht korrekt Initialisieren. Jetzt schick ich mal den gesamten 
Code...

***********************************************


#include <avr/io.h>
#include "lcd.h"
#include "mydefs.h"
#include <util/delay.h>

// sendet ein Datenbyte an das LCD

void LCD_data(unsigned char temp1)
{
   unsigned char temp2 = temp1;

   LCD_rs_enable();              // RS auf 1 setzen

   temp1 = temp1 >> 4;
   temp1 = temp1 & 0x0F;

   LCD_write_in_ports(temp1);

   LCD_enable();

   temp2 = temp2 & 0x0F;

   LCD_write_in_ports(temp2);

   LCD_enable();

   _delay_ms(10);
}

// sendet einen Befehl an das LCD

void LCD_command(unsigned char temp1)
{
   unsigned char temp2 = temp1;

   LCD_rs_disable();            // RS auf 0 setzen

   temp1 = temp1 >> 4;              // oberes Nibble holen
   temp1 = temp1 & 0x0F;            // maskieren

   LCD_write_in_ports(temp1);

   LCD_enable();

   temp2 = temp2 & 0x0F;            // unteres Nibble holen und 
maskieren

   LCD_write_in_ports(temp2);

   LCD_enable();

   _delay_ms(10);
}

// erzeugt den Enable-Puls
void LCD_enable(void)
{
   // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers 
einfügen
   // Beitrag "Re: Bitte helft mir. Schon wieder AtMega16"
   sbi(LCD_EN_PORT,LCD_EN_NR);
    _delay_ms(10);                   // kurze Pause
   // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers 
verlängern
   // Beitrag "LCD -> Probleme mit Optimierungsgrad"
   cbi(LCD_EN_PORT,LCD_EN_NR);
}

// Initialisierung:
// Muss ganz am Anfang des Programms aufgerufen werden.

void LCD_init(void)
{

   // Alle LCD PORTS auf Ausgang schalten
   sbi(LCD_RS_DDR,LCD_RS_NR);
   sbi(LCD_EN_DDR,LCD_EN_NR);
   sbi(LCD_DATA_4_DDR,LCD_DATA_4_NR);
   sbi(LCD_DATA_5_DDR,LCD_DATA_5_NR);
   sbi(LCD_DATA_6_DDR,LCD_DATA_6_NR);
   sbi(LCD_DATA_7_DDR,LCD_DATA_7_NR);

   // muss 3mal hintereinander gesendet werden zur Initialisierung

   _delay_ms(200);

  LCD_rs_disable();

  /*
   LCD_command(0x03);

   LCD_enable();

   _delay_ms(100);
   LCD_enable();

   _delay_ms(100);
   LCD_enable();


  */
   // 4 Bit Modus aktivieren
   // LCD_write_in_ports(0x02);

   LCD_command(0x02);

   _delay_ms(10);
   LCD_enable();


   // 4Bit  2 Zeilen  5x7

   LCD_command(0x28);

   _delay_ms(10);
   LCD_enable();

   // Display ein  Cursor aus  kein Blinken

   LCD_command(0x0F);

   _delay_ms(10);
   LCD_enable();

   LCD_clear();
   // inkrement / kein Scrollen

   LCD_command(0x06);

   _delay_ms(10);
   LCD_enable();


}

// Sendet den Befehl zur Löschung des Displays

void LCD_clear(void)
{
   LCD_command(CLEAR_DISPLAY);
   _delay_ms(100);
}

// Sendet den Befehl: Cursor Home

void LCD_home(void)
{
   LCD_command(CURSOR_HOME);
   _delay_ms(1);
}

// setzt den Cursor in Zeile y (1..4) Spalte x (0..15)

void LCD_set_cursor(unsigned char x, unsigned char y)
{
  unsigned char tmp;

  switch (y) {
    case 1: tmp=0x80+x; break;    // 1. Zeile
    case 2: tmp=0xC0+x; break;    // 2. Zeile
    case 3: tmp=0x94+x; break;    // 3. Zeile
    case 4: tmp=0xD4+x; break;    // 4. Zeile
  }
  LCD_command(tmp);
}

// Schreibt einen String auf das LCD

void LCD_string(char *data)
{
    while(*data) {
        LCD_data(*data);
        data++;
    }
}
void LCD_rs_enable(void)
{
  sbi(LCD_RS_PORT,LCD_RS_NR);
}
void LCD_rs_disable(void)
{
  cbi(LCD_RS_PORT,LCD_RS_NR);
}

void LCD_write_in_ports(unsigned char data)
{

  cbi(LCD_DATA_4_PORT,LCD_DATA_4_NR);
    cbi(LCD_DATA_5_PORT,LCD_DATA_5_NR);
    cbi(LCD_DATA_6_PORT,LCD_DATA_6_NR);
    cbi(LCD_DATA_7_PORT,LCD_DATA_7_NR);

    if(data & 0x01) sbi(LCD_DATA_4_PORT,LCD_DATA_4_NR);
    if(data & 0x02) sbi(LCD_DATA_5_PORT,LCD_DATA_5_NR);
    if(data & 0x04) sbi(LCD_DATA_6_PORT,LCD_DATA_6_NR);
    if(data & 0x08) sbi(LCD_DATA_7_PORT,LCD_DATA_7_NR);

}
Gast #889407
Lesenswert?

Vergiss erstmal die Ansteuerung.

Setze die Pins der Reihe nach High/Low und überprüfe mit dem Oszi, ob 
die Pegel korrekt ankommen, und zwar da - und nur da - wo sie sollen.

Das heisst auch die Nachbarpins checken. Evtl. ist irgendwo eine kleine 
Lötbrücke, die sieht man oft kaum.
#889762
Lesenswert?

Stephan Henning wrote:

> D0 - D3 immer auf Low im 4 Bit Modus. Nicht benutzte TTL Eingänge werden
> ja auch auf Low gelegt.

Bei echten TTL eher auf high, weil das deutlich weniger Strom kostete.

Aber bei den HD44780&Co LCDs sollte man das ausdrücklich nicht tun, 
sondern die Dinger offen lassen. Erstens hat der LCD-Controller genau 
deswegen interne Pullups. Zweitens führt das zum Kurzschluss wenn man 
Daten liest. Dieser Kurzschlusstrom ist zwar zu gering um Schaden 
anzurichten, ist aber trotzdem Unsinn.
Gast #890295
Lesenswert?

Matthias,

das ganze kann auch ein Reset Problem sein, je nachdem wie der 
Spannungsverlauf beim Ein- und Ausschalten ist.
Ich hatte ein Projekt mit LCD, ohne dass Probleme auftraten. In einem 
späteren verhielt sich das LCD ähnlich wie Du es beschreibst. Seitdem 
ich die Spannungsversorgung für das LCD getrennt einschalte (der µC kann 
die Spannung per Transistor schalten) funktionert es wunderbar.
In der Beschreibung zum HD44780 steht, wie die Initialisierung bei 
"schlechtem" Einschaltvorgang aussehen sollte. Das brachte bei mir keine 
Besserung.

Wie verhalten sich die Displays, wenn Du sie austauscht? Ich meine das 
Pollin-LCD in die alte Reichelt-Schaltung und umgekehrt?

Sag' bescheid, falls Du etwas erreichst.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren