Forum: Mikrocontroller und Digitale Elektronik LCD-Display AV1640 - Zeilenfehler


von M. B. (freiberger77)


Angehängte Dateien:

Lesenswert?

Hallo,
ich habe das Display von Conrad AV1640 ( 16 Buchstaben & 4 Zeilen) am 
ATTiny2313. (4Bit-Modus)
Angeschlossen ist alles richtig.
Wenn ich einen Text sende, wird er nur in Zeile 1 und 3 angezeigt (Zeile 
2 wird automatisch übersprungen).
Wie kann ich auf Zeile 2 und 4 zugreifen ?

Wenn ich den Text mehrfach sende, wird irgendwann Zeile 2 und 4 
beschrieben.
Die CLS-Funktion funktioniert auch nicht...

Im Anhang ist das Datenblatt und der Code.

von Hubert G. (hubertg)


Lesenswert?

Im Datenblatt 1.Seite ganz unten, siehst du die Adressen der einzelnen 
Zeilen. Du wirst da deinen Code anpassen müssen.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Wenn ich einen Text sende, wird er nur in Zeile 1 und 3 angezeigt (Zeile
> 2 wird automatisch übersprungen).
Der Code ist für ein Zweizeiliges Display geschrieben   :-o
Die LCD-Zeilen 1 und 3 entsprechen der Zeile 1 im Code.
Die LCD-Zeilen 2 und 4 entsprechen der Zeile 2 des Codes.

Wenn du 4 Zeilen willst, ist dort der Hebel, wo du ansetzen mußt:
1
// Zeilenwechsel
2
void lcd_gotoline (uint8_t zeile)    
3
{
4
  if (zeile == 1) lcd_write(0x80,0);   // B 1000 0000 => DD-RAM Adress Set   
5
  if (zeile == 2) lcd_write(0xC0,0);   // B 1100 0000 => DD-RAM Adress Set   
6
  if (zeile == 3) lcd_write(0x90,0);   // B 1001 0000 => DD-RAM Adress Set    
7
  if (zeile == 4) lcd_write(0xD0,0);   // B 1101 0000 => DD-RAM Adress Set 
8
}
und gleiches bei den Cursorpositionen...

von Michael S. (msk) Benutzerseite


Lesenswert?

Wie die Vorredner schon sagten, für die zweite und vierte Zeile musst Du 
die Cursor-Position entsprechend setzen. Wenn Du einfach hintereinander 
wegschreibst, ist die Reihenfolge:

1. Zeile
3. Zeile
2. Zeile
4. Zeile

Der Beginn der zweiten Zeile liegt bei den Displays, die ich bisher 
hatte, 0x40h hinter dem Beginn der ersten Zeile. Hier ein Stück 
Quelltext, mit dem Du die Position innerhalb des Displays auf jede 
beliebige Stelle setzen kannst:
1
switch (row) {
2
3
  case 1:           //1. row
4
    address = SET_DDRAM_ADDRESS | column;  //DB7=1 --> set DDRAM Address, DB0...DB6 --> Address
5
    break;
6
7
  case 2:           //2. row
8
    address = SET_DDRAM_ADDRESS | (DDRAM_OFFSET + column);   //DB7=1 --> set DDRAM Address, DB0...DB6 --> Address
9
    break;
10
11
  case 3:           //3. row
12
    address = SET_DDRAM_ADDRESS | (DISPLAY_NUMBER_COLUMNS + column);  //DB7=1 --> set DDRAM Address, DB0...DB6 --> Address
13
    break;
14
15
  case 4:           //4. row
16
    address = SET_DDRAM_ADDRESS | (DDRAM_OFFSET + DISPLAY_NUMBER_COLUMNS + column);  //DB7=1 --> set DDRAM Address, DB0...DB6 --> Address
17
    break;
18
19
  default:
20
    return;                   //do nothing if wrong row requested
21
  }

Row und Column sind von Dir dann entsprechend anzugeben. Die Funktion 
habe ich bewusst so geschrieben, dass man sie an möglichst viele 
Displays adaptieren kann. Für Dein Display müssten die Parameter 
folgendermaßen lauten:
1
#define SET_DDRAM_ADDRESS                0x80  //set DDRAM Address (DB0...DB6 transport address)
2
#define DISPLAY_NUMBER_COLUMNS             16  //number of display columns
3
#define DDRAM_OFFSET                     0x40  //address offset for 2. line (for 2-line-mode)

Die Adresse musst Du dann einfach als Kommando an das Display senden und 
damit ist die gewünschte Cursor-Position gesetzt.

Falls Bedarf besteht, kann ich auch mal meine Display-Routinen hier 
hochladen. Ich habe mir mal die Mühe gemacht, die so adaptierbar wie 
möglich zu machen (Anzahl Zeilen, Zeichen, Pin-Belegung etc.), die 
sollten also auch mit Deinem Display laufen.

von M. B. (freiberger77)


Lesenswert?

OK, ich versuche die Änderungen dann mal.
Hab leider das Prinzip noch nicht verstanden, wo ich welche Daten senden 
muß, zB für INIT und CLEAR usw.
Aus dem Datenblatt werde ich nicht schlau...

von M. B. (freiberger77)


Lesenswert?

die 4 Zeilen werden jetzt richtig angezeigt.
Aber Bildschirm löschen geht überhaupt nicht.
Obwohl die Bits dafür ja stimmen sollten...

von M. B. (freiberger77)


Lesenswert?

und warum läuft das Dasplay nur am Programmiergerät ?
Wenn ich die Schaltung an nem 9V-Block mit nem 7805 laufen lasse, 
leuchtet zwar das Display und der ATTiny (LED blinkt an Port B), aber 
auf dem Display bleiben die schwarzen Balken in Zeile 1 & 3...

von Michael S. (msk) Benutzerseite


Lesenswert?

Marco B. schrieb:
> die 4 Zeilen werden jetzt richtig angezeigt.
> Aber Bildschirm löschen geht überhaupt nicht.
> Obwohl die Bits dafür ja stimmen sollten...

Also der Clear-Befehl scheint mir bei Dir mit dem Cursor-Home-Befehl 
vertauscht zu sein - sollte aber nichts ausmachen. Prüfe mal, ob Du die 
RS-Leitung auch richtig setzt (auf LOW), damit das als Befehl 
interpretiert wird.

von Michael S. (msk) Benutzerseite


Lesenswert?

Marco B. schrieb:
> und warum läuft das Dasplay nur am Programmiergerät ?
> Wenn ich die Schaltung an nem 9V-Block mit nem 7805 laufen lasse,
> leuchtet zwar das Display und der ATTiny (LED blinkt an Port B), aber
> auf dem Display bleiben die schwarzen Balken in Zeile 1 & 3...

Dann hat die Initialisierung nicht funktioniert. Hast Du es erst nach 
dem Start angesteckt?

von M. B. (freiberger77)


Lesenswert?

zum CLEAR... die RS-Leitung muß funktionieren, sonst würden die anderen 
Daten ja nicht übertragen.

Wenn ich den Prozessor an das Programmiergerät anstecke, erscheint 
sofort die Schrift.
Nehme ich den ISP-Stecker ab und lege Reset (Pin1) an +5V und lege dann 
die Batterie an, dann zeigt es keine Schrift. Der Prozessor läuft aber 
(LED blinkt).

manchmal kommen aber auch beim Batt. anlegen mit Programmiergerät nur 
Balken oder wirre Zeichen.

von spess53 (Gast)


Lesenswert?

Hi

>Nehme ich den ISP-Stecker ab und lege Reset (Pin1) an +5V und lege dann
>die Batterie an, dann zeigt es keine Schrift. Der Prozessor läuft aber
>(LED blinkt).

Dann solltest du mal die Wartezeit vor der Initialisierung verlängern.

MfG Spess

von Michael S. (msk) Benutzerseite


Lesenswert?

Marco B. schrieb:
> zum CLEAR... die RS-Leitung muß funktionieren, sonst würden die anderen
> Daten ja nicht übertragen.
>
> Wenn ich den Prozessor an das Programmiergerät anstecke, erscheint
> sofort die Schrift.
> Nehme ich den ISP-Stecker ab und lege Reset (Pin1) an +5V und lege dann
> die Batterie an, dann zeigt es keine Schrift. Der Prozessor läuft aber
> (LED blinkt).
>
> manchmal kommen aber auch beim Batt. anlegen mit Programmiergerät nur
> Balken oder wirre Zeichen.

Wie ist der Reset-Pin an Deinem Controller beschaltet? Da sollte ein 
10k-Widerstand gegen Vcc und ein 47nF-Kondensator gegen Masse beschaltet 
sein, um beim Anlegen von Betriebsspannung auch einen Reset auszuführen. 
Nach Deiner Beschreibung wird Dein Controller nicht vernünftig resettet.
Dann solltest Du die Wartezeiten bei der Initialisierung Deines Displays 
nachprüfen.

von M. B. (freiberger77)


Lesenswert?

habe einen 100nF Kondensator (mit 10nF habe ich auch versucht), sollte 
aber auch gehen.
Auf dem Display blinken jetzt ab und zu Kästchen auf, aber kein Text.
Die Spannung ist bei 5,1V konstant.

von Michael S. (msk) Benutzerseite


Lesenswert?

100nF sollten auch gehen. Und der Pullup (10k) ist auch dran?

von M. B. (freiberger77)


Lesenswert?

ja, habe extra nachgemessen.
Ich warte sogar 1 Sek nach Start und init. dann erst das Display.

Wenn ich wärend dem "Fehlbetrieb" das ISP anstecke, muß ich erst den 
USB-Stecker raus/rein machen. Dann geht es erst...

Wenn ich im Batt-Betrieb Reset auf Minus und wieder abnehme ,
dann geht es...

Es muß am Kondensator liegen, aber den habe ich nachgemessen...
Vielleicht nen Elko nehmen ?

von Michael S. (msk) Benutzerseite


Lesenswert?

Marco B. schrieb:
> Es muß am Kondensator liegen, aber den habe ich nachgemessen...
> Vielleicht nen Elko nehmen ?

Nein, keinen Elko. Prüfe lieber nochmal Deine Schaltung am Reset-Pin.

von M. B. (freiberger77)


Lesenswert?

da kann ich nicht mehr prüfen. Habe die Bauteile nachgemessen.
10k gegen +5V und 100nF gegen GND.
Erst wenn ich Reset kurz auf GND lege, dann geht es.

Habe jetzt mal 5 sek Wartezeit vor LCD_INIT.
Die LED leuchtet nach anlegen der Spannung 5 sek und fängt dann an zu 
blinken...
Aber das Display zeigt nur Kästchen...

von M. B. (freiberger77)


Lesenswert?

habe gerade zurch Zufall was merkwürdiges festgestellt.
Wenn ich Kurz Reset auf GND lege, geht es.
Mache ich es nochmal, zeigt es Balken an.
Immer abwechselnd. Malg gehts, mal gehts nicht.
Das Display hat aer keinen Reset-Pin...

Ich denke fast, es ist ein Fehler in der INIT-Routine.
Es wird erst auf 8-Bit und dann auf 4-Bit umgeschalten.
Wie erkenne ich im Datenblatt, ob die Routine stimmt ?

von spess53 (Gast)


Lesenswert?

Hi

>Wie erkenne ich im Datenblatt, ob die Routine stimmt ?

Im Datenblatt vom KS0066 steht es drin.

MfG Spess

von Michael S. (msk) Benutzerseite


Lesenswert?

Sieht mir eher danach aus, dass die Wartezeit zur Initialisierung des 
Displays nicht stimmt oder ähnliches.

Wie Du im Datenblatt erkennst, dass die Routine stimmt? Eigentlich nur 
durch vergleichen des Beispiels zur 4-Bit-Initialisierung, wenn 
vorhanden (oftmals leider nicht). Schau mal hier:
http://www.sprut.de/electronic/lcd/index.htm#init

Das sollte eigentlich so funktionieren.

von M. B. (freiberger77)


Lesenswert?

Hey, die Seite ist ja richtig gunt erklärt.
Ich lese mir das morgen mal in Ruhe durch.
Dankeschön erstmal...

von M. B. (freiberger77)


Lesenswert?

WOW,
vielen Dank an Michael S.
Die Seite hat mir sehr geholfen... Jetz hab ich den Durchblick.

Es ist ein Fehler in der Initialisierung gewesen. (Umschaltung auf 4 Bit 
- LOW & HIGH-Bit vertauscht)
Mit folgender Änderung klappt es wunderbar...
1
// Display initialisieren. Einmal als erstes aufrufen
2
void lcd_ini ()
3
{
4
  DDRD = 0x3F;    // setze Portrichtung (1 = Ausgang): 0011 1111 
5
  PORTD=0x00;      // alle Leitungen LOW
6
7
  _delay_ms(60);    // 10ms warten bis LCD wirklich bereit (max. Wert lt. Datenblatt)
8
9
10
  lcd_write(0b00110000,0);     // 8-Bit-Modus aktivieren, Ist wichtig, falls LCD schon im 4-Bit Modus war und dann               
11
                  // nach einem Programm-Reset vergeblich versucht würde, den 4-Bit Modus erneut zu aktivieren
12
  lcd_write(0b00110000,0); 
13
  lcd_write(0b00110000,0);
14
  
15
16
  lcd_write(0b00100000,0);    // B 0000 0010 => mit 8-Bit-Command in 4-Bit-Modus umschalten 
17
18
  lcd_flash_e ();      // Enable
19
20
  _delay_us(200);      // sicherheitshalber warten
21
22
  // ab jetzt 4-Bit-Modus
23
  lcd_write(0b00101000,0);     // => Function Set: 4Bit (kein 8-Bit Bus), zweizeiliges Display, 5x7 Dots/Zeichen (kein 5x10)
24
  lcd_write(0b00001100,0);     // => Display On/Off: Display ein, Cursor aus, Blinken aus
25
  lcd_write(0b00000110,0);     // => Entry Mode Set: DD-RAM autom. inkr., Cursor bewegen
26
  
27
  lcd_cls();        // Display löschen
28
}

Es ist zwar bestimmt nicht perfekt, aber jetzt kommt sofort der richtige 
Text.
Aber die CLS-Funktion geht trotzdem nicht. Naja, mann kann ja 
Leerzeichen drüberschreiben...

Danke an alle Helfer    ;-)

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.