Ein 2-Zeiliges LCD das lieber 1-Zeilig sein möchte...

A

Artur

Guest
Hallo NG,

es ist mir schon fast unangenehm hier einen Thema für ein LC-Display
anzufangen weil die meisten Themen dazu hier ja eh dazu geführt haben
das es sich um Timingproble handelt, aber ich komme einfach nicht
weiter...

LCD-Typ: 162C Displaytech
Anzeigeformat: 2x16 Zeichen
LCD-Controller: KS0070 B
Betriebsspannung: 5V

Ich kann die oberste Zeile des Displays einwandfrei beschreiben, den
Cursor positionieren und auch die Befehle "LCD-Clear" und
"Return-Home" funktionieren ohne Probleme.
Die 2-te Zeile funktioniert aber nicht, überhaupt nicht, nichts, nada,
nothing!
Schreibversuche ab der DD-Ram Adresse 0x40 bleiben erfolglos. Ich habe
bereits versucht den gesamten DD-Ram-Bereich 0x00 bis 0x7F zu
beschreiben mit dem Hintergedanken das sich die zweite Zeile an einer
anderen Adresse befindet -aber es werden nur in der ersten Zeile
Zeichen
angezeigt.

Bei der Initialisierung des LCDs wird das LCD auch auf 2 Zeilen
eingestellt.
(Ich glaube das ändert ja aber eh nur den Duty-Cycle von 1/8 auf
1/16.)

Ich betreibe das LCD im 4-Bit-Modus und nur im "Write"-Betrieb. D.h.
ich
kann die RW-Leitung des LCDs nicht umschalten und somit auch nicht das
Busy-Bit abfragen. Zwischen den einzelnen Schreibbefehlen warte ich
auch
ganz sicher mind. 50us bzw. 16ms. (Nur "Enable", "RS" und die vier
oberen
Datenbits sind beschaltet. Ja, natürlich auch Vcc, Vee, GND und RW ist
fest auf "Write" gelegt.)

Das Timing der LCD-Routinen habe ich bereits auseinander gezogen und
völlig unkritisch gemacht - die zweite Zeile funktioniert aber nicht.

Wenn ich die Kontrastspannung (Vee) verändere, wird auch nur der
Kontrast der oberen Zeile verändert.

Meine letzte Idee war, dass es sich um ein defektes LCD handelt. Also
habe ich das LCD ausgelötet und gegen ein neues, gleichen Typs,
ersetzt.
.... die zweite Zeile funktioniert immer noch nicht...

Hat irgend jemand eine Idee oder einen Vorschlag an welcher Stelle ich
den 'BUG' noch suchen kann?

Gruß,
Artur Pundsack

(OT: Frank W.- ESD W. konnte mir auch nicht helfen ;-)
 
Artur wrote:

Hallo NG,

es ist mir schon fast unangenehm hier einen Thema für ein LC-Display
anzufangen weil die meisten Themen dazu hier ja eh dazu geführt haben
das es sich um Timingproble handelt, aber ich komme einfach nicht
Peinlicher ist es allerdings, den Code nicht zu posten. Gibt es welchen?

Robert
(meinend, dass die Verdrahtung in Ordnung scheint)
--
'Vom Standpunkt eines Beamtenrechtlers aus betrachtet ist der Tod die
schärfstwirkenste aller bekannten, langfristig wirkenden Formen der
vollständigen Dienstunfähigkeit.'
aus: Kommentar zum Beamtenrecht.
 
Peinlicher ist es allerdings, den Code nicht zu posten. Gibt es welchen?
// Macros
#define EN0 {PORTD &= ~_BV(PD0);} // LCD Enable LOW
#define EN1 {PORTD |= _BV(PD0);} // LCD Enable HIGH
#define RS0 {PORTD &= ~_BV(PD1);} // LCD Register select LOW
#define RS1 {PORTD |= _BV(PD1);} // LCD Register select HIGH
#define WR_DB(x) {PORTD = (PORTD & 0x0F) | ((x<<4) & 0xF0);}

extern void wait(uint16_t time); // Verzögerungsschleife Zeit ~ time
x 2ms
extern void waitUS(uint16_t time); // Verzögerungsschleife Zeit ~
time x 1us

// write a byte to the display
void lcd_write(uint8_t data, uint8_t rs)
{
if(rs)
RS1
else
RS0
NOP;

// high nibble
EN1;
WR_DB(data >> 4);
NOP;
EN0;
NOP; NOP; NOP; NOP; NOP;

// low nibble
EN1;
WR_DB(data);
NOP;
EN0;
waitUS(50);
}

void lcd_init(void)
{
// init and config the LCD
EN0;
wait(16); // wait >15ms after power On
RS0;
// first sequence
EN1;
WR_DB(0x03);
NOP;
EN0;
wait(5); //5 wait >4.1ms
// second sequence
EN1;
WR_DB(0x03);
NOP;
EN0;
waitUS(200); //2 wait >100us
// third sequence
EN1;
WR_DB(0x03);
NOP;
EN0;
waitUS(100);

EN1;
WR_DB(0x02);
NOP;
EN0;
waitUS(100);

// config the LCD
lcd_write(0x28, 0); // 4 bit, 2 line, 7x5 dots
lcd_write(0x08, 0); // display off
lcd_write(0x01, 0); // display clear
wait(20); // wait >16ms
lcd_write(0x06, 0); // entry mode set
lcd_write(0x0C, 0); // Blinking off, Cursor on, Display on
lcd_write(0x02, 0); // move to first digit
wait(20); // wait >16ms
}

Ja, ich weiß, man hätte sich ein paar mal das Schieben der Nibbels
bei
dem WR_DB(x) Makro sparen können... aber es funktioniert ja...
bis auf die zweite Zeile.


Artur
 
Der uC (ein Atmega32) wird mit einem Quarz mit 8MHz betrieben...

Artur
 
Hallo Artur,

Artur schrieb:
void lcd_write(uint8_t data, uint8_t rs)
{
if(rs)
RS1
else
RS0
NOP;
Grauenhafte Einrückung....aber das ist wohl nicht der Fehler :)

// high nibble
EN1;
WR_DB(data >> 4);
NOP;
EN0;
Ich würde vorschlagen, erst die Datenbits anzulegen bevor Du
Enable 1 gibst:

// high nibble
WR_DB(data >> 4);
EN1;
NOP;
EN0;

// config the LCD
lcd_write(0x28, 0); // 4 bit, 2 line, 7x5 dots
lcd_write(0x08, 0); // display off
lcd_write(0x01, 0); // display clear
wait(20); // wait >16ms
lcd_write(0x06, 0); // entry mode set
lcd_write(0x0C, 0); // Blinking off, Cursor on, Display on
lcd_write(0x02, 0); // move to first digit
wait(20); // wait >16ms
}
Sieht auf den ersten Blick gut aus.

Wenn Du den Kontrast am LCD mal voll aufdrehst und/oder schräg
reinschaust, siehst Du die Pixelmatrix in der zweiten Zeile
genauso stark/schwach wie die der ersten Zeile (wenn nur Leerzeichen
angezeigt werden)?

HTH
Wolfgang

--
From-address is Spam trap
Use: wolfgang (dot) mahringer (at) sbg (dot) at
 
Hallo Artur,


Code Experte bin ich nicht, aber irgendwie finde ich die Umschaltung in
die 2te Reihe darin nicht. Hier wird es erlaeutert, vielleicht hilft das:
http://www.myke.com/lcd.htm

Gruesse, Joerg

http://www.analogconsultants.com
 
"Artur" <Artur.Pundsack@web.de> schrieb

Peinlicher ist es allerdings, den Code nicht zu posten. Gibt es welchen?

..... ich spare mir die Wiederholung von dem hässlichen "bastel code" ...

Hallo Arthur,

deine Makros machen das Programm unübersichtlich und du
verlierst dadurch auch die Möglichkeit mit dem Debugger
anständig durch den Source Code zu steppen.

In deinem Code will man keine Fehler suchen.

Dein Display kannst du am PC-Parallel Port damit:
http://www.crystalfontz.com/software/CFAH_WinTest/index.html
testen.

Gruß

Hans-Georg
 
"Artur" <Artur.Pundsack@web.de> schrieb im Newsbeitrag
news:1143805362.458874.175210@g10g2000cwb.googlegroups.com...

Wenn ich die Kontrastspannung (Vee) verändere, wird auch nur der
Kontrast der oberen Zeile verändert.
D.h. das Display hat NICHT auf 2-zeilig umgeschaltet.
Verlaengere mal dein Timing auf das 10-fache.
--
Manfred Winterhoff, reply-to invalid, use mawin at gmx dot net
homepage: http://www.geocities.com/mwinterhoff/
de.sci.electronics FAQ: http://dse-faq.elektronik-kompendium.de/
Read 'Art of Electronics' Horowitz/Hill before you ask.
Lese 'Hohe Schule der Elektronik 1+2' bevor du fragst.
 
MaWin schrieb:

"Artur" <Artur.Pundsack@web.de> schrieb im Newsbeitrag
news:1143805362.458874.175210@g10g2000cwb.googlegroups.com...

Wenn ich die Kontrastspannung (Vee) verändere, wird auch nur der
Kontrast der oberen Zeile verändert.

D.h. das Display hat NICHT auf 2-zeilig umgeschaltet.
Verlaengere mal dein Timing auf das 10-fache.
Das Umschalten auf "2-zeilig" erfolgt zusammen mit dem Einstellen des
"4 Bit Modus" im Kommando "Function Set". Da Artur anscheinend alle
weiteren Befehle im 4 Bit Modus programmieren konnte, müßte das
Timing für das "Function Set" doch eigentlich richtig gewählt sein?

Bye,
Frank
 
Hi Frank,

Frank Wagner schrieb:
Das Umschalten auf "2-zeilig" erfolgt zusammen mit dem Einstellen des
"4 Bit Modus" im Kommando "Function Set". Da Artur anscheinend alle
weiteren Befehle im 4 Bit Modus programmieren konnte, müßte das
Timing für das "Function Set" doch eigentlich richtig gewählt sein?
Ich glaube, mich dunkel zu erinnern, dass man erst mal "nur" auf den
4 bit-Modus umschalten und danach mit einem weiteren Befehl die anderen
Modi aktivieren soll.

@Artur: Probier das mal aus.

HTH
Wolfgang

--
From-address is Spam trap
Use: wolfgang (dot) mahringer (at) sbg (dot) at
 
Ich habe damals auch lange herumgesucht.
Man muss unbedingt zuerst den 4 Bit-Modus einschalten, da man durch die
Verdrahtung (nur die 4 MSB des LCD können angesprochen werden) nicht
mehr den Befehl "2-zeilig", binär 00001000 senden kann !
Ich poste mal meinen funktionierenden Mnemonics-Ausschnitt in der
Hoffnung zu helfen:

lcd_init:
ldi temp,0b00000011 ;muss 3mal hintereinander gesendet
out Po_lcd,temp ;werden zur Initialisierung des Display
rcall lcd_enable ;1
rcall delay5ms
rcall lcd_enable ;2
rcall delay5ms
rcall lcd_enable ;3
rcall delay5ms

ldi temp,0b00100000 ;set Function (zuerst einmal 4 bit Interface
aktivieren)
rcall lcd_command ;sonst komme ich nämlich nicht an Bit 3 ran, zur
Einstellung des Modus 2-zeilig !)
rcall delay5ms

ldi temp,0b00101000 ;set Function (2 zeilig, Font 5x7)
rcall lcd_command
rcall delay5ms

ldi temp,0b00001100 ;Display on/off Control (Display on, Cursor off,
Blinking off)
rcall lcd_command
rcall delay5ms

ldi temp,0b00000100 ;set Entry Mode (Cursor Direction right, Display
shift off)
rcall lcd_command
rcall delay5ms

Unterprogramme:
lcd_command:
mov temp1,temp
swap temp
andi temp,0b00001111
out Port,temp
rcall lcd_enable
andi temp1,0b00001111
out Port,temp1
rcall lcd_enable
rcall delay50us
ret

lcd_enable:
sbi Port,Pin_en ;Enable auf high
nop ;3 Taktzyklen warten
nop ;bei 4 MHz Controllertakt
nop
cbi Port,Pin_en ;Enable wieder auf low
ret ;ferig

Wolfgang Mahringer schrieb:

Hi Frank,

Frank Wagner schrieb:
Das Umschalten auf "2-zeilig" erfolgt zusammen mit dem Einstellen des
"4 Bit Modus" im Kommando "Function Set". Da Artur anscheinend alle
weiteren Befehle im 4 Bit Modus programmieren konnte, müßte das
Timing für das "Function Set" doch eigentlich richtig gewählt sein?

Ich glaube, mich dunkel zu erinnern, dass man erst mal "nur" auf den
4 bit-Modus umschalten und danach mit einem weiteren Befehl die anderen
Modi aktivieren soll.

@Artur: Probier das mal aus.

HTH
Wolfgang

--
From-address is Spam trap
Use: wolfgang (dot) mahringer (at) sbg (dot) at
 
Hallo Hans-Georg,

Bastel Code hin, hässlicher Code her...!
Konstruktive Kritik kann ich vertragen.... wenn sie denn konstruktiv
ist :)

EN0 = Enable auf '0' setzen
EN1 = Enable auf '1' setzen

Preisfrage (zu gewinnen gibt es aber nichts :)
Was bedeutet "RS0" wenn 'RS' für "Register Select" steht?

Die Codefragmente stammen noch aus einem Projekt bei dem ich
den Multitasking (oder war es Multitreating) Kernel AVRX eingesetzt
habe.
Der Code war durch die und auch durch andere Makros für mich
übersichtlicher.

Das das Display funktioniert, davon gehe ich aus (ist ja aus einer
neuen
Verpackung) sonst könnte ich ja nicht die erste Zeile beschreiben.

Ich glaube auch nicht das der PC-Parallel Port das gleich Timing
verwendet
den das Programm wurde ja wahrscheinlich von jemanden geschrieben der
keinen BASTEL CODE schreibt sondern von HÄSSLICHEN Makros absieht
und alles in Klassen und Objekte versteckt.

Vielen Dank,

Artur
 
Hallo Wolfgang,

vielen Dank für Deine Anregungen zu den Einrückungen. (Ich habe den
Code Teilweise mit dem Textpad und teilweise mit dem Programmers
Notepad geschrieben. Irgendwie sind beim Copy-Paste die Tabulatoren
und Leerzeichen durcheinander gekommen... ich werde es korreigieren:)

Wenn ich den Kontrast ganz hoch drehe, werden die Pixel der zweiten
Zeile leider nicht angezeigt. Ich denke mal, es wird irgendwie ein
Fehler
beim setzen der Zeilenanzahl Bit "N" sein. Aber wird hierdurch nicht
nur
der Dutycycle verändert?...

Gruß,

Artur
 
Hallo MaWin,

wird durch das "N" Bit bei der Initialisierung nicht nur der
Duty-Cycle verändert (von 1/8 auf 1/16 o.ä.)?

Ich werde Deinen Vorschlag mal ausprobieren und das Timing ganz
auseinander ziehen...

Artur
 
Hallo NG-Gemeinde,

erst mal vielen Dank für eure z.T. Hilfreichen, Lehrreichen
und zum Teil kritischen Antworten.

Den Fehler habe ich jetzt gefunden. Nachdem ich
folgende Vorschläge von euch durchgespielt habe:

* das Timing um das 10-fache verlängert habe -> erfolglos
* die Daten anlege bevor ich an EN wackel -> erfolglos
* den Befehl zum setzen des 4-Bit Modus seperat und
zusammen mit den Initialisierungen (2-Linien, 5x7 Pixel)
schreibe -> erfolglos

Habe ich nochmals mit dem Multimeter die Verdrahtung
durchgemessen und festgestellt, dass

RS und D0

einen Kurzschluß haben (hatten). Aufgrund eines VIAS, der
zu nah an einer Buchsenleiste plaziert ist, kam diser Fehler
zustande. Direkt nachdem ich den Fehler im Layout behoben
habe, funktionierte das Display mit dem Ursprünglichen C-Code
einwandfrei (Auch wenn es nur "bastel code" mit unpraktischen,
nicht leserlichen Makros ist ;-)

Warum ich aber ohne Fehler den Cursor in der ersten Zeile
positionieren und Daten schreiben konnte ist mir ein Rätsel.

Dennoch habe ich eure Anregungen zu Herzen genommen und
meine Standard LCD-Routinen überarbeitet und teilweise direkt
in Assembler geschrieben...

Nochmals vielen Dank an alle die mir versucht haben zu Helfen.

Gruß,

Artur Pundsack
 
"Artur" <Artur.Pundsack@web.de> schrieb

funktionierte das Display mit dem Ursprünglichen C-Code
einwandfrei (Auch wenn es nur "bastel code" mit unpraktischen,
nicht leserlichen Makros ist ;-)
Hallo Artur,

ich hab ja nicht gesagt, dass Bastel-Code nicht funktioniert ;-)

Das Problem ist nur, dass die tollen Programmierer-Einzelkämpfer kommen
und gehen und die Hinterbliebenen die Wartung übernehmen dürfen.
Ich mach das nun schon 20 Jahre mit.

Aber noch etwas zum Display, damit wir noch einen positiven
Abschluss haben ;-) .
ich meine noch in Erinnerung zu haben, dass auch nach dem 2. Senden von
0x03 5ms gewartet werden muss.

Gruß

Hans-Georg
 

Welcome to EDABoard.com

Sponsor

Back
Top