Forum: Mikrocontroller und Digitale Elektronik Pollin LCD Displays


von Matthias (Gast)


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

von Frank L. (hermastersvoice)


Lesenswert?

dann benutz doch die Reichelt Displays.

von Matthias (Gast)


Lesenswert?

Danke :-(

von juppi (Gast)


Lesenswert?

@Matthias (Gast)

denke an die zeit bei Init.

MfG

von Matthias (Gast)


Lesenswert?

Und ich lass ihm meines Erachtens genug Zeit. 100 ms Warmup und dann 
zwischen den Enable Pulsen 1 ms

von Hannes L. (hannes)


Lesenswert?

Matthias wrote:
> Und ich lass ihm meines Erachtens genug Zeit. 100 ms Warmup

Das kann gelegentlich zu wenig sein. Ich nehme meist 500 ms.

> und dann
> zwischen den Enable Pulsen 1 ms

Das muss reichen.

...

von gast (Gast)


Lesenswert?

LCD Display ist genauso unsinnig wie HIV Virus
es heisst doch schon liquid crystal display

von Paul Baumann (Gast)


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

von Hannes L. (hannes)


Lesenswert?

gast wrote:
> LCD Display ist genauso unsinnig wie HIV Virus
> es heisst doch schon liquid crystal display

Wir wissen es...

...

von Hannes L. (hannes)


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

...

von Bernhard M. (boregard)


Lesenswert?

gast wrote:
> LCD Display ist genauso unsinnig wie HIV Virus
> es heisst doch schon liquid crystal display

Und ich dachte immer, es heisst "Liquid Crystal Device" ....

von Sven S. (stepp64) Benutzerseite


Lesenswert?

Um mal wieder zum Thema zu kommen: Um welches Display geht es denn (gibt 
ja derer zwei bei Pollin...).

Sven

von Pete K. (pete77)


Lesenswert?

Hast Du Abblock-Kondensatoren in Deiner Schaltung?

von M. H. (doktorgnadenlos)


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

von µluxx .. (uluxx) Benutzerseite


Lesenswert?

>Ich habe auch 500ms zwischen 2 Initialisierungsbefehlen.

Das würde ich mal lassen, es gibt Displays, die habens nicht gern wenn 
sie mit der initialisierung ewig warten müssen....

von Matthias (Gast)


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++;
  }
}

von holger (Gast)


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

von holger (Gast)


Lesenswert?

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

Quatsch meinerseits natürlich. Zum zweiten Teil steh ich aber noch.

von Matthias (Gast)


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.

von holger (Gast)


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

von Matthias (Gast)


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.

von Matthias (Gast)


Lesenswert?

Übrigens es ist ein Powertip  PC 1602 F Display

von Matthias (Gast)


Lesenswert?

Die erste Zeile wird immer mit schwarzen Kästchen gefüllt. Die 
Initialsierung klappt dann nicht oder. Hat keiner Erfahrung mit dem 
Display, was mach ich falsch

von Hannes L. (hannes)


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.

...

von holger (Gast)


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

von M. H. (doktorgnadenlos)


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

von Matthias (Gast)


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.

von Matthias (Gast)


Lesenswert?

Sry nicht 4 Ports sondern 4 Pins

von TheMason (Gast)


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)

von Matthias (Gast)


Lesenswert?

Die unteren 4 Bits sind offen, haben also keinen definierten Pegel.
Bei den Reichelt Displays musste ich das nicht machen ...

von TheMason (Gast)


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)

von TheMason (Gast)


Lesenswert?

quark

>damit zugange gebracht genau diesen fehler zu suchen.

meine : ... diesen fehler zu finden

von Matthias (Gast)


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...

von Stephan H. (stephan-)


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.

von Stephan H. (stephan-)


Lesenswert?

@Matthias,

0x28 als was ???? Befehl oder Daten ????
Drüber nachgedacht ???

von Matthias (Gast)


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

}

von Jupp (Gast)


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.

von Stephan H. (stephan-)


Lesenswert?

Sorry no Way !!!
"C" ist Chaos in "Clammern"
ich vertseh nix davon. Ich schreibe ASM.
Ist eben wesentlich einfacher. ABER schwerer zu verstehen.
Tut mir Leid, kann ich Dir nicht helfen.

von Jupp (Gast)


Lesenswert?

>"C" ist Chaos in "Clammern"
>Ich schreibe ASM. Ist eben wesentlich einfacher.

So einen Schmarren hab ich selten gelesen.

von Matthias (Gast)


Lesenswert?

>"C" ist Chaos in "Clammern"

Bull Shit

von Jupp (Gast)


Lesenswert?

Und geht's jetzt?

von Andreas K. (a-k)


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.

von ruediger (Gast)


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.

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.