PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : LCD Initialisierung



eis
23.11.2007, 20:29
Hallo zusammen,
ich versuche gerade ein 16-1A LCD von Reichelt mithilfe eines AVR mega16 anzusteuern.
so ganz sporadisch hat's natürlich nicht funktioniert, also mache ich eins nach dem anderen.
hab mich zunächst einmal durch sämtliche tutorials und datenblätter durchgearbeitet, eins verstehe ich aber immer noch nicht ganz.
und zwar, bevor man irgendwelche daten an das LCD schickt, sollte man das gute Teil erst einmal initialisieren.
das ist schon mal klar.. Nur wie erkenne ich dass das LCD die Initialisierungsroutine geschluckt hat und nun bereit ist daten zu empfangen?das einzige was ich auf meinem LCD sehen kann sind fünf schwarze Balken.
sollten dann diese nach einer erfolgreichen Initialisierung verschwinden oder bleiben sie sichtbar bis sie mit "richtigen" daten so zu sagen überschrieben werden?

Hubert.G
23.11.2007, 21:04
Normalerweise ist nur die erste Zeile schwarz, wenn das LCD nicht initialisiert ist. Nach den initialisieren ist es leer. Sollte es nicht so sein, dann den Kontrast verändern. Es gibt auch LCD die eine negative Kontrastspannung benötigen.

kalledom
23.11.2007, 21:06
Hallo,
ein LCD hat ein Busy- oder Ready-Signal, welches ausgelesen werden kann. Das benutzt kaum jemand und das zeigt auch nicht an, ob die Initialisierung erfolgreich war.
Wichtig ist die Reihenfolge der Initialisierungs-Befehle im 4 oder 8 Bit Modus mit den entsprechenden Wartezeiten. Die Wartezeiten dürfen auf keinen Fall unterschritten werden, weil sonst Befehle gesendet werden, obwohl das LCD noch beschäftigt ist und diese nicht annehmen kann.
Erst nach korrekter Initialisierung werden die gesendeten ASCII-Zeichen dargestellt. Auch hier sind Wartezeiten zwischen der Zeichen-Übergabe einzuhalten.

Wenn Du nur schwarze Balken siehst, solltest Du vielleicht mal an dem Poti für den Kontrast drehen.

eis
23.11.2007, 22:04
nee, ich glaube der Poti ist es nicht.
hab jetzt nämlich ein bisschen damit rumexperimerntiert.
also, wenn am Kontrast-Pin die vollen +5V anliegen dann ist das Display absolut leer.
so, wenn mann die Kontrastspannung etwas runterdreht, kommen lansam schwarze Balken zum vorschein zunächst mal 8 Stück an der Zahl,die werden aber mit abnehmender Spannung immer dunkler .
und wenn man mit der Kontrastspannung noch weiter über 0Volt in den negativen Spannungbereich geht, dann werden aus 8 schwarzen Balken plötzlich 16 Stück, und bei -5V sind die genauso dunkel wie die ersten acht.
ist eigentlich auch nicht gerade das gelbe...

Hubert.G
24.11.2007, 09:17
Die ersten Balken sind OK, das Display ist nicht initialisiert.
Womit arbeitetst du, C, BASCOM, Assembler und hast du eine fertige Lib oder etwas eigenes und welchen Modus.

Dolfo
24.11.2007, 09:57
Guten Morgen,

- Datenpins richtig herum angeschlossen?
- Chip-Select ("Enable") Signal acitve high (nicht wie üblich low)?
- großzügige Warteschleifen (bei der Initialisierung gibts kein Feedback, ob die Befehle angekommen sind, da hilft nur abwarten)?
- R/W Signal aktiviert (Befehle werden nur beim Pegelwechsel übernommen, müssen also schon vorher am Bus anliegen)?

So klappts bei meinem 20x4 Display (sicher keine Augenweide, funktioniert aber):


Display_initiieren:
rcall warte250 ; Einschalt-Reset vom Display abwarten


ldi Zeichen,0b00111000 ; Befehl "Function Set"
rcall Display_Befehl_schreiben
rcall warte10
rcall warte10
rcall Display_Befehl_schreiben
rcall warte10
rcall Display_Befehl_schreiben
rcall warte2

ldi Zeichen, 0b00111000 ; lade Befehl "2-zeilig, 5x8"
rcall Display_Befehl_schreiben

rcall warte2
ldi Zeichen, 0b00001000 ; lade Befehl "Display aus"
rcall Display_Befehl_schreiben

rcall warte2
ldi Zeichen, 0b000000001 ; lade Befehl "Display löschen"
rcall Display_Befehl_schreiben

rcall warte2
ldi Zeichen, 0b000000110 ; lade Befehl "Cursor nach rechts wandern"
rcall Display_Befehl_schreiben

rcall warte2
ldi Zeichen, 0b000001111 ; lade Befehl "Display einschalten"
rcall Display_Befehl_schreiben
ret


Display_Zeichen_schreiben:
rcall warte2 ; warte bis Display empfangsbereit ist
rcall Datenbus_ist_Ausgang
out Datenbus, Zeichen ; schreibe Daten in Datenbus
nop
ldi Adresse,0b00001001 ; RW=0 | RS=1 | E=1
out Adressbus, Adresse ; schreibe Enable-Bit auf Adressbus
nop
ldi Adresse,0b00001000 ; RW=0 | RS=1 | E=1
out Adressbus, Adresse ; schreibe Enable-Bit auf Adressbus
nop
ret

Display_Befehl_schreiben:
rcall Datenbus_ist_Ausgang
out Datenbus, Zeichen ; schreibe Befehl in Datenbus
nop
ldi Adresse,0b00000001 ; setze Enable-Bit für Display
out Adressbus, Adresse ; Display im Schreibmodus ansprechen
nop
ldi Adresse,0b00000000 ; lösche Enable-Bit für Display
out Adressbus, Adresse ; schreibe Enable-Bit auf Adressbus
nop
ret


"wartexxx" ist eine Routine, die den angegebenen Zahlenwert in mSek. abwartet.

Grüße

Edit von BASTIUniversal: Code-Box!

eis
24.11.2007, 14:57
@Hubert.G
ich bin gerade dabei mir Assembler beizubringen.
hab da ein Paar Zeilen Code geschriben, versuche erst eimal übersichtlichkeithalber mit 8-Bit-Modus.
hier poste ich's mal, falls jemand sich die Zeit nimmt wäre ich sehr dankbar.

;LCD-Ansteuerung im 8-Bit-Modus
;PORTC -- Datenbits DB0-DB7
;Enable -- PD6
;R/S -- PD7
;R/W -- GND

.INCLUDE "m16def.inc"
.EQU XTAL=1000000
.DEF temp1=r16
.DEF temp2=r17
.DEF temp3=r18
.DEF temp4=r19
.DEF temp5=r20
.CSEG
rjmp main
.ORG $2A

main: ldi temp1,LOW(RAMEND)
out SPL,temp1
ldi temp1,HIGH(RAMEND)
out SPH,temp1

ldi temp1,0x0F
out DDRD,temp1

ldi temp1,0xFF
out DDRB,temp1
out DDRC,temp1

rcall lcd_init
rcall lcd_clear
rcall lcd_home

loop: ldi temp1,0x55
rcall lcd_data
out PORTB,temp1 ;bloß Kontrolle
rjmp loop


lcd_enable: sbi PORTD,PD6 ;E setzten
nop
nop
cbi PORTD,PD6 ;E zurück
ret
;sendet ein Datenbyte an LCD
lcd_data: sbi PORTD,PD7 ;R/S-Bit
out PORTC,temp1
rcall lcd_enable
rcall delay_5ms
cbi PORTD,PD7 ;R/S-Bit
ret
;sendet ein Befehl an LCD
lcd_command: cbi PORTD,PD7 ;R/S-Bit
out PORTC,temp1
rcall lcd_enable
rcall delay_5ms
ret
;initialisiert LCD
lcd_init: push temp1
push temp3
ldi temp3,5
pow_upwait: rcall delay_5ms
dec temp3
brne pow_upwait
ldi temp1,0b00110000
out PORTC,temp1
cbi PORTD,PD7
rcall lcd_enable
rcall delay_5ms
ldi temp1, 0b00110000 ; 8bit-Modus einstellen
out PORTC,temp1
rcall lcd_enable
rcall delay_5ms
ldi temp1,0b00110000 ; Functoin set
rcall lcd_enable
rcall delay_5ms
ldi temp1,0b00010100 ; Cursor,Display,Shift
rcall lcd_enable
rcall delay_5ms
ldi temp1,0b00001100 ; Display,on/off
rcall lcd_enable
rcall delay_5ms
ldi temp1,0b00000110 ; Entry mode
rcall lcd_enable
rcall delay_5ms
pop temp3
pop temp1
ret
;löscht LCD
lcd_clear: push temp1
ldi temp1,0b00000001 ;Display löschen
rcall lcd_command
rcall delay_5ms
pop temp1
ret
;cursor home
lcd_home: push temp1
ldi temp1,0b00000010 ;cursor home
rcall lcd_command
rcall delay_5ms
pop temp1
ret
;Warteschleifen
delay_50us: push temp1
ldi temp1,20 ;Takt=1MHz
delay_50us_: nop
dec temp1
brne delay_50us ;verzweige bei=0 pop temp1
ret

delay_5ms: push temp1
push temp2
ldi temp1,5
d_5ms_a: ldi temp2,100 ;100 dezimal
d_5ms_i: nop ;interne Schleife=5Takte
nop
dec temp2
brne d_5ms_i ;gibt 500 Durchläufe=500us
dec temp1
brne d_5ms_a
nop
pop temp2
pop temp1
ret
.EXIT
@Dolfo
hab nochmal alles gecheckt - Verdrahtungs- und Hardwarefehler kann man fast ausschliessen.
Chip-Select ("Enable") Signal schaltet auch mit acitve high (eigentlich wie alle anderen Pins)

R/W Signal aktiviert (Befehle werden nur beim Pegelwechsel übernommen, müssen also schon vorher am Bus anliegen)?
du meinst wahrscheinlich R/S oder? weil R/W habe ich einfach auf GND gelegt.
und RS aktiviere ich nur wenn ich Daten senden will und keine Befehle.

Dolfo
24.11.2007, 16:57
!!! Es ist ein Unterschied, ob ein Zeichen oder ein Befehl gesendet wird:

* Schreiben eines Steuerbefehls (RS=R/W=0)
* Lesen des Status (busy-Flag und AC) (RS=0, R/W=1)
* Schreiben eines Zeichens zur Anzeige (RS=R/W=1)
Zitat aus http://www.sprut.de/electronic/lcd/index.htm. Die Seite hat mir sehr geholfen.

Initialisiere auch mit "Cursor=on". Dann lässt sich schnell erkennen, ob die Init erfolgreich war.

Dein Quellcode: sollte jemand prüfen, der's schon besser kann als ich.

Ansonsten bleibt nur: hartnäckiger sein als das Display O:)

Gruß

eis
25.11.2007, 12:31
so...jetzt hat das gute Ding endlich verloren - die Initialisierung klappt schon mal - war blos ein Programmierfehler.
danke allen für die freundliche unterstützung.

FriLu
25.11.2007, 18:07
Hallo,
@Dolfo: Bei R/W und RS = 1 LIEST du das Zeichen auf der Cursorposition.
MfG Lutz