Zeilenadressen LCD 4x20 blau

OP #1718852
Lesenswert?

Hi Leuts, ich habe hier ein 4x20 Zeichen LCD (blau/weiss) und versuche 
es mit den Routinen aus dem Tutorial anzusteuern.
#define LCD_DDADR_LINE1         0x00
#define LCD_DDADR_LINE2         0x40
#define LCD_DDADR_LINE3         0x10
#define LCD_DDADR_LINE4         0x50

Zunächst mal klappt es soweit, aber natürlich können ja die RAM Adressen 
nicht stimmen, da es ja 20 Zeichen sind und die Routinen für 16 
ausgelegt sind. Folgendes passiert:
Wenn ich in der 1. und 2. Zeile was ausgebe, dann steht das am 
Zeilenanfang(so wie es soll).
Wenn ich in der 3. Zeile was ausgebe, dann steht das in der 1. Zeile an 
Position 17 (würde auch noch passen). Wenn ich in der 1. Zeile einen 
String > 20 Zeichen ausgebe, dann wird er in der 3. Zeile fortgesetzt. 
Also liegen wohl die Adressen für die 1. und die 3. Zeile 
hintereinander.
Nun änderte ich die Adresse der Zeile 3 von 0x10 auf 0x15. Ergebnis: 
Nichts verändert sich, der Text steht in der 1. Zeile ab Position 17. 
Ich habe jetzt alle möglichen Werte durchprobiert, ich kriege keine 
Ausgabe in der 3. Zeile an Position 1.
Bei der 2. und der 4. Zeile das Gleiche. Woran kann das liegen ?
Auf dem Display finde ich lediglich folgende Angaben:
2004BD1660Y
L200657A
E170968
Das hat mir auf der Suche nach einem Datenblatt auch nicht wirklich 
weitergeholfen.
Es sind aber auch noch 5 Lötbrücken auf der Platine, von denen 1,3 und 5 
offen und 2&4 gelötet sind.
Hat jemand eine Idee ?
OP #1718892
Lesenswert?

>Nun änderte ich die Adresse der Zeile 3 von 0x10 auf 0x15. Ergebnis:
>Nichts verändert sich, der Text steht in der 1. Zeile ab Position 17.
>Ich habe jetzt alle möglichen Werte durchprobiert, ich kriege keine
>Ausgabe in der 3. Zeile an Position 1.


Wenn ihr meinen Beitrag aufmerksam gelesen habt, dann werdet ihr 
feststellen dass die dies schon versucht habe und die Adressänderungen 
nichts bewirken!!!
OP #1718897
Lesenswert?

Selbst folgende Änderung bewirkt nichts:
#define LCD_DDADR_LINE1         0
#define LCD_DDADR_LINE2         40
#define LCD_DDADR_LINE3         00
#define LCD_DDADR_LINE4         40
Nun sollte doch eigentlich egal sein, ob ich die erste oder die dritte 
Zeile anspreche.
Aber es macht ein Unterschied: Spreche ich die 1. Zeile an, dann steht 
der Text ab Position 0,0. Spreche ich aber die 3. Zeile an, dann steht 
der Text wieder ab Position17 in der 1. Zeile??????
OP #1718903
Lesenswert?

int main(void)
{
  // Initialisierung des LCD
  // Nach der Initialisierung müssen auf dem LCD vorhandene schwarze 
Balken
  // verschwunden sein
  lcd_init();

  // Text in einzelnen Zeichen ausgeben
  lcd_setcursor(0,1);
  lcd_string("0123456789");




  while(1)
  {
  }

  return 0;
}

Die LCD-Routinen sind die Originalroutinen aus dem Tutorial hier:
http://www.mikrocontroller.net/articles/AVR-Tutorial:_LCD
Ich denke eher dass es am Display liegt (nur so ein Gefühl)
Gast #1718952
Lesenswert?

Leider haut das mit den Zeilenadressen ggf. nicht so hin...
Z.B. haben die LCD's bei denen der KS0073 Controller verbaut ist,
(Z.B. EA DIP204) die Adressen, ebenfalls ein 4*20 Display.

Zeile 1: 0x00...0x13
Zeile 2: 0x20...0x33
Zeile 3: 0x40...0x53
Zeile 4: 0x60...0x73

Das nennt man dann "fast 100% kompatibel".
#1718962
Lesenswert?

Karlheinz Druschel schrieb:

> @Mike: Dann würde sich ja gar nichts ändern, aber es ändert sich doch
> fast (siehe oben).

Hmm.
Ich seh von dir immer nur die Meldung:
Der Beginn meiner 3. Zeile ist in der ersten Zeile Zeichen 17.

An dieser Fehlerbeschreibung hat sich seit deinem ersten Posting nichts 
verändert.

Also für mich klingt das nach:
Du änderst zwar etwas im Header File, aber es kommt nicht auf dem 
Controller an.

Ich würde mal einen Rebuild All machen und darauf achten ob auch 
wirklich alles neu compiliert wird.
#1718975
Lesenswert?

Guter Rat schrieb:
> Z.B. haben die LCD's bei denen der KS0073 Controller verbaut ist,
> (Z.B. EA DIP204) die Adressen, ebenfalls ein 4*20 Display.
>
> Zeile 1: 0x00...0x13
> Zeile 2: 0x20...0x33
> Zeile 3: 0x40...0x53
> Zeile 4: 0x60...0x73

Um die Sache noch etwas mehr zu verwirren:
Ich habe hier ein DB von EA, u.a. für EA DIP204*.
Da steht aber gerade nicht deine Adressierung drin, sondern
diese:
Zeile: 0x00
Zeile: 0x40
Zeile: 0x14
Zeile: 0x54

Dann habe ich noch ein DB zu einem EA P204-3N/-NLED, mit
einem Controller HD 66712.
Das wiederum hat deine Belegung:
Zeile: 0x00
Zeile: 0x20
Zeile: 0x40
Zeile: 0x60

(Meine obige Behauptung, daß die eh alle gleich wären,
ziehe ich hiermit stillschweigend wieder ein und behaupte
das Gegenteil.)
#1718979
Lesenswert?

Karlheinz Druschel schrieb:
> @Klaus:
> Wie bereits mehrfach erwähnt ist die Routine hier im Tutorial zu finden
> (Link steht oben).

Die LCD-Routinen gibt es hier in etlichen Varianten (die beste
natürlich von mir :-), und dein Link führt auf die Ansteuerung
des LCD in Assembler.
Ehrlich gesagt habe ich keine Lust, zu raten, welchen Quelltext
du nun nimmst, um darin dann Fehler zu suchen.
Gast #1718990
Lesenswert?

Hi,
sieht so aus, also ob da noch eine Routine zur Ausgabe dazwischen ist, 
die von einem 2 x 16-stelligen Display übrig ist. Denn bei einem 2x16 
Display gibt es Zeile 1 und Zeile 3. Und da sind oft die Routinen so 
geschrieben, dass nach dem 16. Zeichen auf der nächsten Zeile 
weitergeschrieben wird. Und das wäre das 17. Zeichen auf Zeile 3 bei 
deinem 4x20 Display.
Schmeiss den ASM-Schrott weg und nimm ein C-Programm, welches 
übersichtlicher ist.
#1718994
Lesenswert?

Noch ein Nachtrag zu den Adressen:
In einem gedruckten DB von EA namens "Blue Line - Blau negativ
mit weisser LED" ist die Tabelle zu sehen wie im Anhang.

Dieses DB beschreibt (an 4x20) die Typen EA W204B-NLW, EA 017-9UKE,
EA DIP204B-4NLW, EA DIP204B-6NLW und EA T204B-BNLW.
Leider finde ich darin nicht, welches jetzt welchen Controller hat...

Also verwendet alleine EA mindestens 3 Controller (HD44780,
KS0073, HD66712), wobei erster bei 4x20 die eine Adressierung
verwendet, KS0073 und HD66712 die andere (siehe oben).

Die Zuordnung von "Guter Rat" von KS0073 zu den Adressen stimmt
hiermit; auch wenn es offenbar nicht oder nicht alle mit einer
Bezeichnung EA DIP... sind.
Angehängte Dateien:
OP #1719017
Lesenswert?

ok, mit dem Link habe ich mich verhauen. Hier ist der Richtige:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/LCD-Ansteuerung

@Karlheinz Buchegger: Ich mache immer ein "Rebuild All" (sind ja nur 
zwei Dateien), und wenn ich den Text ändere, dann klappt das auch.

Aber ich glaube ich habe was gefunden.
Im Quellcode von lcd_init steht folgendes:

#define LCD_FUNCTION_2LINE      0x08
// 4-bit Modus  2 Zeilen  5x7
lcd_command( LCD_SET_FUNCTION | LCD_FUNCTION_4BIT |
            LCD_FUNCTION_2LINE |LCD_FUNCTION_5X7 );

Anscheinend wird damit auf zweizeiligen Betrieb umgeschaltet. Fargt sich 
nur noch wie ich auf vierzeiligten Betrieb umschalte...
OP #1719018
Lesenswert?

ok, mit dem Link habe ich mich verhauen. Hier ist der Richtige:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/LCD-Ansteuerung

@Karlheinz Buchegger: Ich mache immer ein "Rebuild All" (sind ja nur 
zwei Dateien), und wenn ich den Text ändere, dann klappt das auch.

Aber ich glaube ich habe was gefunden.
Im Quellcode von lcd_init steht folgendes:

#define LCD_FUNCTION_2LINE      0x08
// 4-bit Modus  2 Zeilen  5x7
lcd_command( LCD_SET_FUNCTION | LCD_FUNCTION_4BIT |
            LCD_FUNCTION_2LINE |LCD_FUNCTION_5X7 );

Anscheinend wird damit auf zweizeiligen Betrieb umgeschaltet. Fragt sich 
nur noch wie ich auf vierzeiligten Betrieb umschalte...
#1719030
Lesenswert?

Karlheinz Druschel schrieb:
> Anscheinend wird damit auf zweizeiligen Betrieb umgeschaltet. Fragt sich
> nur noch wie ich auf vierzeiligten Betrieb umschalte...

Gar nicht.
Es gibt an dieser Stelle nur die Möglichkeit ein- oder zweizeilig.
Vierzeilig als eigenen Modus gibt es nicht.

Dieses Bit im Kommando Function Set betrifft m.W. nur Displays
mit 1x16, von denen gibt es zwei Varianten bzgl.
der Adressierung (alle 16 Zeichen direkt hintereinander, oder
mit ein paar Byte Abstand kompatibel zu einem 2x8-LCD als
ob die zwei Zeilen eines 2x8 hintereinander montiert
wären).

Bei einem 4x20 sollte es keinen Unterschied machen.
#1719046
Lesenswert?

PS: in meiner eigenen C++-Klasse für die LCD-Ansteuerung
habe ich solche Kuriositäten zwar eingebaut nach den Unterlagen,
die ich so finden konnte.
Leider konnte ich das nie probieren...
Falls jemand 1x16 hat und entbehren kann (oder sonstige, die ich
noch nicht probieren konnte) und entweder leihweise hergeben könnte
oder für kleines Geld abtreten, dann könnte ich sowas mal
probieren und ggf. vervollständigen.

Was ich bisher schon habe sind:
- EA W162B-BNLW
- EA W204B-NLW
- EA W162B-N3LW
- TC1602A-09
- LCD Displaytech 404B 4x40 Controller: KS0066U
- TC1602E (aus dem Pollin Addon-Board)
OP #1719161
Lesenswert?

Ok, Thema erledigt.
Ich verstehe zwar definitiv nicht den Zusammenhang, aber es ist wirklich 
so:
Nach der ganzen Probierei wollte mein Dragon auf einmal keinen 
Controller mehr programmieren. Also habe ich das AVR-Studio neu 
gestartet. Als auch das nicht geholfen hat, habe ich den kompletten PC 
neu gebootet. Und schlagartig geht das Display so wie es soll.
Kapier ich nicht
OP #1719162
Lesenswert?

Ok, Thema erledigt.
Ich verstehe zwar definitiv nicht den Zusammenhang, aber es ist wirklich 
so:
Nach der ganzen Probierei wollte mein Dragon auf einmal keinen 
Controller mehr programmieren. Also habe ich das AVR-Studio neu 
gestartet. Als auch das nicht geholfen hat, habe ich den kompletten PC 
neu gebootet. Und schlagartig geht das Display so wie es soll.
Kapier ich nicht.
Ich weiss, das klingt so als hätte ich einen Fehler gemacht und wolle 
ihn nicht zugeben, ist aber wirklich so passiert!!!!!!!
OP #1722506
Lesenswert?

Und schon habe ich das nächste Problem:
Nachdem alles an PortD so funktioniert wie es soll, wollte ich das Ganze 
umverdrahten auf PortC.
Dazu habe ich im Quelltext (lcd_routines.h> folgendes geändert:
//////////////////////////////////////////////////////////////////////// 
////////
// Pinbelegung für das LCD, an verwendete Pins anpassen
// Alle LCD Pins müssen an einem Port angeschlossen sein und die 4
// Datenleitungen müssen auf aufeinanderfolgenden Pins liegen

//  LCD DB4-DB7 <-->  PORTD Bit PD0-PD3
#define LCD_PORT      PORTC
#define LCD_DDR       DDRC
#define LCD_DB        PC0

//  LCD RS      <-->  PORTD Bit PD4     (RS: 0=Data, 1=Command)
#define LCD_RS        PC4

//  LCD EN      <-->  PORTD Bit PD5     (EN: 1-Impuls für Daten)
#define LCD_EN        PC5

Alles neu kompiliert und Ergebnis: Geht nicht. Aber im Quellcode finde 
ich keine weitere Angabe von PORTD, es sollte also alles umgesetzt sein.
Die Verdrahtung habe ich auch schon mehrfach überprüft.
Wieso das jetzt ? Ist PortC anders zu handhaben als PortD ?
#2950529
Lesenswert?

Guten Tag,

Habe leider das gleiche Problem und komme der Sache nicht auf die 
Schliche.. :(

Wenn ich in die 3 Zeile schreiben möchte , schreibt er mir für

#define LCD_LINE1      0x00
#define LCD_LINE2      0x40
#define LCD_LINE3      0x14
#define LCD_LINE4      0x54

in das 17 Zeichen der 1. Zeile

und für :

#define LCD_LINE1      0x00
#define LCD_LINE2      0x40
#define LCD_LINE3      0x20
#define LCD_LINE4      0x54

in das 13 Zeichen in der 3. Zeile.

Dazwischen kann ich nicht schreiben.

Das Display ist über einen I2C Portexpander angeschlossen ( Pollin Board 
) und soll laut Hersteller einen KS0066U Display Treiber haben.

http://pdf1.alldatasheet.com/datasheet-pdf/view/132627/ETC1/JHD204A.html


Ich hänge die LCD routinen mal an.

Ich bin wirklich am verzweifeln.

Grüße
Dennis
Angehängte Dateien:
#2950646
Lesenswert?

Okay.. vielen Dank.
Kann ich das in meine Routine einbauen ? bzw. an welchem Punkt. Da dort 
ja ein "direkter" Zeilenzugriff implementiert ist.

Also Zeile 3 ist ab Adresse 0x??  usw...

Bzw. das Programm macht doch auch nichts anderes , als nach Zeichen "39" 
ab Adresse 0x14 weiterzuschreiben. Das wäre ja ohne hin die Zeile 3 wie 
sie bei mir definiert ist.

Auf Zeichen 0x14  zu schreiben bringt aber "scheinbar" nichts.
#2950742
Lesenswert?

In dem verlinkten Dokument ist ein C-Beispiel drin, wo die Position 
etwas krude berechnet wird:
1
if (Position > 59)     //also ab 60=0x3C
2
   Position += 0x18;   //also plus 24, 4. Zeile ab 0x54
3
else if (Position > 39)//also ab 40=0x28
4
   Position -= 0x14;   //also minus 20, 3. Zeile ab 0x14
5
else if (Position > 19)//
6
   Position += 0x2C;   //also plus 44, 2. Zeile ab 0x40

Schreibe doch zum Test mal die Zeichen A-Z,a-z,0-9 der Reihe nach auf 
das Display. Dann siehst Du schon, wo die Zeichen landen.
#2951002
Lesenswert?

Dennis Henning schrieb:
> Wenn ich in die 3 Zeile schreiben möchte , schreibt er mir für
>
> #define LCD_LINE1      0x00
> #define LCD_LINE2      0x40
> #define LCD_LINE3      0x14
> #define LCD_LINE4      0x54
>
> in das 17 Zeichen der 1. Zeile

das sind doch genau die Werte.. das Test Programm schreibt mir 1 und 2te 
Zeile ohne Probleme und ab der dritten schreibt er wieder ins 17. 
Zeichen der 1. Zeile.

Wie oben schon beschrieben.
#2951169
Lesenswert?

Mein Gott du stellst dich aber auch an.

Gib halt einfach mal einen Haufen Zeichen aus!
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHI 
JKLMNOPQRSTUVWXYZ"  usw. usw.
Dann siehst du schon, welches das erste Zeichen in der 3. Zeile ist. 
Dann zählst du noch ab der wievielte Buchstabe das in deinem String war 
und du hast die Startadresse.
Und wenn dieser "Monstertext" nicht ausreicht, dann hängst du eben noch 
ein paar "ABCD.." hinten drann. Aber so, dass dir du im Nachhinein noch 
identifizieren kannst, welche Wiederholung das 1. Zeichen einer Zeile 
darstellt. Zur Not ersetzt du dann eben das erste "ABCD..." durch lauter 
Leerzeichen, oder machst abwechselnd einen Buchstaben und ein 
Sonderzeichen oder was auch immer.

Dem LCD ist das doch wurscht, das schreibt einfach die Zeichen 
nacheinander in der Speicher und der Anzeigeteil vom LCD holt sich dann 
ab einer bestimmten Startadresse die Zeichen und färbt die Pixel in der 
3. Zeile entsprechend. Also bügelst du einfach den Character-Speicher 
mit Zeichen voll und bei irgendeinem fängt der Anzeigeteil an, dafür die 
Pixel der 3. Zeile einzufärben. Du musst nur im Nachhinein abzählen 
können, welches Zeichen wo im Speicher gelandet ist.

Manchmal probiert man die Dinge einfach aus und überlegt sich eine 
Teststrategie anstatt lange rumzurechnen und es dann doch nicht 
rauszukriegen.


Edit:
Aber nimm die lcd_print, die ohne Ansehen von irgendwelchen 
Zeilenstrukturen einfach die Zeichen rausgibt.
Gast #4027678
Lesenswert?

Stundenlang habe ich auch mit dem selben Problem rumgemacht (mein 
Display EA DIP204-4 ist ein LCD mit 4 x 20 Zeichen mit dem Samsung 
K0073). Problem ist, man muss durch die 'extended function set' das Bit 
NW auf HIGH setzen !!! (Vorsicht, nach dem NW-Setzen das Bit RE nicht 
vergessen auf LOW zurückzusetzen - das RE Bit müsste man nämlich vor der 
Benutzung von 'extended function set' auf HIGH setzen ). Durch diese 
Operation ist jetzt 4-Zeilen Modi aktiviert.

Erst ab jetzt gelten die Adressen:
LINE1 0x00
LINE2 0x20
LINE3 0x40
LINE4 0x60

Im Tutorial:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/LCD-Ansteuerung
ist dies nicht gemacht, muss mal selber ergänzen.

Ich hoffe es hilft denjenigen, die mit 4-Zeilern kämpfen.

Schöne Grüße aus der Slowakei!

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