Forum: Mikrocontroller und Digitale Elektronik LCD 8x2 (KS0066) ansteuern


von Alex B. (Firma: Ucore Fotografie www.ucore.de) (alex22) Benutzerseite


Lesenswert?

Hallo!
Dieses Thema wurde schon min. 1000x behandelt, jedoch bekomme ich das 
o.g. Display einfach nicht ans laufen... vielleicht seht ihr ja meinen 
Fehler und könnt mir helfen.
Zu den Randbedingungen: Ein "Anag Vision 0820"-Display mit 
KS0066-Controller ist an einen ATMega32 über 8-Bit-Interface 
angeschlossen.
Die Datenbits liegen an PORTC0-7. PORTB0 = Enable, PORTB1 = R/W, PORTB2 
= RS.

Der Quelltext, mit dem ich versuche das Display zu betreiben:
1
int main(void){
2
3
  //Initialization
4
5
  //Configure I/Os
6
  DDRA  = 0b00000000;
7
  PORTA = 0b00000000;
8
9
  DDRB  = 0b00000111;
10
  PORTB = 0b11111000;
11
12
  DDRC  = 0b11111111;
13
  PORTC = 0b00000000;
14
15
  DDRD  = 0b11111111;
16
  PORTD = 0b00000000;
17
18
  //Configure Timers
19
  TCCR0 = 0b00000101;
20
21
  pause(100);
22
23
  init_display();
24
25
  lcd_send(1, 0x66);
26
  lcd_send(1, 0x66);
27
  lcd_send(1, 0x66);
28
  lcd_send(1, 0x66);
29
    
30
  while(1){
31
  
32
  }
33
}
34
35
//Function definitions
36
37
//Initialize the LCD
38
void init_display(void){
39
  lcd_send(0, 0x30);
40
  lcd_send(0, 0x30);
41
  lcd_send(0, 0x30);
42
  lcd_send(0, 0x38);
43
  lcd_send(0, 0x08);
44
  lcd_send(0, 0x02);
45
  lcd_send(0, 0x0F);
46
  return;
47
}
48
49
//lcd send command
50
void lcd_send(int type, int value){
51
  PORTB |= 1;
52
  PORTB &= 0b11111001;
53
  if(type == 1)
54
    PORTB |= 0b100;
55
  PORTC = value;
56
  PORTB &= 0b11111110;
57
  pause(30);
58
  PORTB |= 1;
59
  pause(30);
60
61
  return;
62
}
63
64
//Pause
65
void pause(uint8_t length){
66
  uint8_t stop;
67
  stop = TCNT0 + length;
68
  while(TCNT0 < stop);
69
  return;
70
}

Ist es richtig, dass die "Enable"-Leitung des Displays immer high ist 
und zur Übernahme eines neuen Befehls auf low gezogen wird?
(=Ändern der Werte auf den Datenleitung bei EN = high?)

Was passiert ist folgendes: Beide Zeilen des Displays werden vollständig 
eingeschaltet. Es ist weder ein Zeichen noch ein Cursor sichtbar...

Kann mir vielleicht jemand helfen?

Das Tutorial habe ich mir durchgelesen. Da wird leider nur die 
Ansteuerung im 4-bit-Modus besprochen.
In Zahlreichen anderen Threads, bei denen es um das gleiche Problem 
ging, wurden keine Lösungen gefunden?! Irgendwann waren die Threads dann 
einfach tot...

Vielen Danke & schöne Grüße,
Alex

von spess53 (Gast)


Lesenswert?

Hi

<void init_display(void){
>  lcd_send(0, 0x30);
>  lcd_send(0, 0x30);
>  lcd_send(0, 0x30);
>  lcd_send(0, 0x38);
>  lcd_send(0, 0x08);
>  lcd_send(0, 0x02);
>  lcd_send(0, 0x0F);
>  return;
>}

Zur Initialisierung des Displays im 8-Bit-Mode bedarf es lediglich 4 
Befehle:

Function Mode Set
Display ON/OFF
Clear Display
Entry Mode Set

Die Beschreibung findest du im Datenblatt vom Display/KS0066

MfG Spess

von Alex B. (Firma: Ucore Fotografie www.ucore.de) (alex22) Benutzerseite


Lesenswert?

Hi Spess,

danke dass du dir die Sache mal angeschaut hast. Das war auch mein 
erster Ansatz (nur die 4 von dir erwähnten Schritte). Leider führt das 
zum gleichen Ergebnis...
In diversen anderen Foren/Beiträgen fand ich dann, dass manche Leute 4x 
diesen ersten Initialisierungsbefehl senden?!

Was ich noch vergessen habe zu erwähnen: der ATMega läuft mit 4MHz.

von spess53 (Gast)


Lesenswert?

Hi

>Leider führt das zum gleichen Ergebnis...

Es ist allerdings auch ein bestimmtes Timing notwendig:

     Power On
          |
  mindestens 30ms warten
          |
  Function Mode Set
          |
     > 39µs warten
          |
  Display ON/OFF
          |
     > 39µs warten
          |
  Clear Display
          |
     >1.53 ms warten
          |
  Entry Mode Set

Dein Programm wäre übrigens besser lesbar, wenn du statt

  PORTB |= 1;   so etwas wie   PORTB |= 1<<E;  benutzen würdest. Muss 
natürlich definiert werden.

MfG spess

von holger (Gast)


Lesenswert?

Als erstes sollte mal die pause() Routine bereinigt werden;)
Die funktioniert nicht immer richtig.

Einfache Lösung:

//Pause
void pause(uint8_t length){

  TCNT0 = 0;
  while(TCNT0 < length);
  return;
}

von Alex B. (Firma: Ucore Fotografie www.ucore.de) (alex22) Benutzerseite


Lesenswert?

OK, kurzer Zwischenbericht:

Das JTAG-Interface war (durch die Standard-Fuse-Einstellungen) enabled. 
Aus diesem Grund war PORTC5 (=Data-Bit5) immer HIGH -> Die Kommandos an 
das LCD wurden verfälscht.

Nachdem ich die JTAG-Fuse disabled habe blinkte spontan der Cursor :-)

Ich hoffe von nun an alleine weiter zu kommen!

Vielen Dank trotzdem für eure Mühen.

Falls es weitere Probleme gibt melde ich mich.

Viele Grüße,
Alex

von Alex B. (Firma: Ucore Fotografie www.ucore.de) (alex22) Benutzerseite


Lesenswert?

Vielen Dank noch Mal, nachdem ich den Fehler mit der alternativen 
Funktion von PortC-Pin5 (JTAG) entdeckt hatte, lief alles problemlos.

Der Thread ist damit für mich erstmal geschlossen.

von Alex Nitsche (Gast)


Lesenswert?

Alex Bürgel schrieb:
> Das JTAG-Interface war (durch die Standard-Fuse-Einstellungen) enabled.
> Aus diesem Grund war PORTC5 (=Data-Bit5) immer HIGH -> Die Kommandos an
> das LCD wurden verfälscht.

Danke für diesen Hinweis, hatte den selben Fehler und hab einfach nicht 
an die JTAG-Fuse gedacht und statt dessen 100 mal die 
Initialisierungsroutine umgeschrieben ;). Nochmals Danke :)

Schöne Grüße

Alex

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.