LCD-Display AV1640 - Zeilenfehler

#1377469
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.
Angehängte Dateien:
Moderator (Firma: Titel) Persönliche Seite #1377686
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...
Persönliche Seite #1377713
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.
Persönliche Seite #1378238
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.
Persönliche Seite #1378244
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?
#1379489
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.
Persönliche Seite #1379502
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.
#1379535
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 ?
#1379601
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 ?
Persönliche Seite #1379634
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.
#1381141
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    ;-)

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