www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Störrisches LCD


Autor: Wiesi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe hier ein LCD, das ich aus einem Xerox Drucker
ausgebaut habe. Es hat den HD44780 Controller.

Das Problem ist, das ich es einfach nicht dazu bekomme einen
Text auszugeben.

Das Problem fängt schon bei der Initialisierung an. Stelle ich den
Cursor komplett ab, so ist er nach der Initialisierung weg. OK.

Schalte ich den Cursor ohne Blinken ein, so ist er nicht da.

Schalte ich den Cursor mit Blinken ein, so ist er da und blinkt,
rutscht aber 1 Zeichen von der 0,0 Position nach rechts.

Ich denk mal ich hab irgendwo ein Brett worm Kopf.

Weiß irgendjemand woran das liegen kann?

   Wiesi

Autor: Michael Frangenberg (startrekmichi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nur so als Tipp, weil ich den Fehler vorhin auch gemacht hab:
Das teil braucht ne Weile, um Befehle abzuarbeiten. D.h. man muss
entweder lange genug warten oder das busy-flag lesen. (siehe
Datenblatt) Wenn man sich nicht fran hält, kommt müll raus.

(ich hab meine lcd-routinen von nem früheren Projekt übernommen, nur
das jetzige läuft bei doppelter Frequenz aber die timings waren die
alten^^).

Autor: Wiesi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Delay hab ich drin, bis das busy flag verwendbar ist.

Hier die Init:

void lcd_init(void)
{
  unsigned char c1, c2;

  L_RS = 0;
  L_RW = 0;
  L_E  = 0;

  L_DB4 = 0;
  L_DB5 = 0;
  L_DB6 = 0;
  L_DB7 = 0;

  LT_RS = OUT;
  LT_RW = OUT;
  LT_E  = OUT;

  LT_DB4 = OUT;
  LT_DB5 = OUT;
  LT_DB6 = OUT;
  LT_DB7 = OUT;

  // After power up we have to wait
  // (This gives roughly 100ms @ 20MHz)
  for(c1 = 0; c1 < 222; c1++) {
    for(c2 = 0; c2 < 255; c2++)
      ;
  }

  lcd_put_cmd8(0x30);

  // Wait again (shorter)
  for(c1 = 0; c1 < 22; c1++) {
    for(c2 = 0; c2 < 255; c2++)
      ;
  }

  lcd_put_cmd8(0x30);

  // Wait once again (shorter, too)
  for(c1 = 0; c1 < 255; c1++)
    ;

  lcd_put_cmd8(0x30);

  // And again
  for(c1 = 0; c1 < 255; c1++)
    ;

  lcd_put_cmd8(0x20);

  // And again
  for(c1 = 0; c1 < 255; c1++)
    ;

  lcd_put_cmd(0x20);  // Lines = 1
  //lcd_put_cmd(0x20 | 0x80);  // Lines = 2

  lcd_put_cmd(0x08);  // Display off
  lcd_put_cmd(0x01);  // Clear LCD, cursor home
  lcd_put_cmd(0x04 | 0x02);  // Entry mode increment, disable display
shift

  lcd_put_cmd(0x0C | 0x02 | 0x01);  // Display on

}

Die I/O Routinen:

void lcd_data_setup(unsigned char data)
{
  // Transfer high nibble
  L_DB4 = data & 0x10 > 0 ? 1 : 0;
  L_DB5 = data & 0x20 > 0 ? 1 : 0;
  L_DB6 = data & 0x40 > 0 ? 1 : 0;
  L_DB7 = data & 0x80 > 0 ? 1 : 0;
  L_E = 1;
  NOP();
  L_E = 0;

  // Transfer low nibble
  L_DB4 = data & 0x01;
  L_DB5 = data & 0x02 > 0 ? 1 : 0;
  L_DB6 = data & 0x04 > 0 ? 1 : 0;
  L_DB7 = data & 0x08 > 0 ? 1 : 0;
  L_E = 1;
  NOP();
  L_E = 0;
}

void lcd_put_cmd(unsigned char cmd)
{
  // Put LCD into Instruction mode
  L_RS = 0;
  L_RW = 0;

  lcd_busy();
  lcd_data_setup(cmd);
}

// 8 Bit mode, no busy flag checking
void lcd_put_cmd8(unsigned char cmd)
{
  // Put LCD into Instruction mode
  L_RS = 0;
  L_RW = 0;

  // Transfer high nibble only
  L_DB4 = cmd & 0x10 > 0 ? 1 : 0;
  L_DB5 = cmd & 0x20 > 0 ? 1 : 0;
  L_DB6 = cmd & 0x40 > 0 ? 1 : 0;
  L_DB7 = cmd & 0x80 > 0 ? 1 : 0;
  L_E = 1;
  NOP();
  L_E = 0;
}

Autor: Marco S (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Wiesi

Wie sind denn L_xy definiert? Wenn z.B. L_DB4 = L_DB5 = L_DB6 = L_DB7 =
PORTB ist, dann werden die Bits mit

#define L_DB PORTB
#define L_BIT4 4
#define L_BIT5 5
L_DB |= (1<<L_BIT4) gesetzt und mit
L_DB &= ~(1<<L_BIT5) gelöscht.

Mir scheint, du schreibst immer eine 0x00 oder eine 0x01 auf den
kompletten Port.

Gruß
Marco
-

Autor: Wiesi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Marco,

die sind so definiert:

#define L_RS  RB1
#define L_RW  RB2
#define L_E    RB3

#define L_DB4  RB4
#define L_DB5  RB5
#define L_DB6  RB6
#define L_DB7  RB7

Beim dem HI-Tech Pic-Compiler ist ein bitweiser Zugriff auf den
Port möglich (z.B. RB1 = 1; RB4 = 0; usw.).

Weil als aber keine beisammenliegenden Portleitungen sein müssen,
Werte ich die Bits einzeln aus und gebe sie aus.

    Wiesi

Autor: Marco S (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe gedacht, es handelt sich um avr-gcc. Mit Hi-Tech und PIC kenn ich
mich garnicht aus.

Der bitweise Zugriff mit RB4 = 0 ist ja sehr bequem. Könntest du mir
auch noch verraten, wie RB1 definiert ist?

Nun mal eine Codezeile:

L_DB7 = cmd & 0x80 > 0 ? 1 : 0;

Wenn ich den Ausdruck auswerte, wird L_DB7 das, was rechts vom = steht
zugewiesen. Gehen wir die Prioritätenliste hinauf, so folgt der ternäre
Operator. Dieser gibt 0 oder 1 zurück, je nachdem wie der Ausdruck
zwischen dem = und dem ? ist. Hier steht "cmd & 0x80 > 0". Auch
dieser Ausdruck wird ausgewertet. Das Operatorsymbol mit der höchsten
Priorität ist das >. Also wird zu "cmd & 1" vereinfacht. Kann es
sein, dass du den Port-Bits immer nur das niederwertigste Bit von cmd
aufzwingst, oder habe ich das falsch verstanden? Ich würde

L_DB7 = cmd & 0x80 ? 1 : 0;

schreiben.


Gruß
Marco
-

Autor: Wiesi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Marco

Danke für den Tipp, es ist mir auch gerade aufgefallen, dass es
so heißen muss:

L_DB7 = (cmd & 0x80) > 0 ? 1 : 0;

Dann kommt auch das richtige raus (beim Port).

Jetzt kann ich schon den Cursor so einstellen wie ich es haben
will, was mir sagt, dass die Kommunikation so weit funktioniert.

Leider wird das Display immer nocht leer, wenn ich ein Zeichen
ausgeben will oder dir DDRAM Adresse ändere.

Bei einem LCD werden ja meist nach dem Einschalten alle Pixel
etwas dunkler als im ausgeschalteten Zustand.
Das ausgebaute Modul hat 1x16 Zeichen. Dunkler werden aber nur
die ertsen 8. Ich denke da hat´s was.

Das Problem ist, das ich von dem Modul keine Anschlussbelegung/
Datenblatt habe.
Es hat 22 Anschlüsse und ich hab 9 davon rausgesucht indem ich
den Durchgang zwischen Controller und Kontaktleiste gemessen
hab. (7 Steuer + 2 Versorgung).

   Wiesi

Autor: Wiesi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm. Wenn ich es als 2 zeiliges initialisiere, bleiben alle hell.
Cursor ist aber da.

Komisch

   Wiesi

Autor: Benedikt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei einem zweizeiligem muss die Kontrastspannung höher eingestellt
werden als bei einem einzigen.

Autor: Wiesi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Benedikt danke.

Cursor hin- und herschieben geht auch schon. Jetzt muss ich nur noch
was ausgeben können...

   Wiesi

Autor: Wiesi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So. Jetzt funktioniert alles.
Danke für eure Hilfe.

   Wiesi

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.