Tach zusammen,
ich bräuchte mal fachkundigen Rat zur Ansteuerung eines LCDs. Ich
versuche, mit einem ATmega8 @8MHz ein DEM20486SYH-LY (KS0066)
anzusteuern. Interface ist 8-Bit, Sprache Assembler. Da ich so etwas
vorher noch nicht gemacht habe, hab ich mich am LCD-AVR-Tutorial von
dieser Seite orientiert.
Mein Problem kurz zusammengefasst: Ich bekomme es nicht hin, Text auf
dem Display anzuzeigen. Die Initialisierung scheint geglückt zu sein, da
ich keine schwarzen Balken, sondern einen blinkenden Cursor links oben
zu sehen bekomme, wie ich es auch haben möchte. Die Verdrahtung ist wie
folgt:
DB0...7: PB0...7
RS: PD7
R/W: PD6
E: PD5
Ich hab sie mehrmals überprüft, wenn aber jemand einen Tip hat, welche
Verbindung ich nochmals kontrollieren sollte, immer her damit.
Der relevante Code sieht folgendermaßen aus:
1
.equ LCD_PORT = PORTB
2
.equ XTAL = 8000000
3
.equ PIN_E = 5
4
.equ PIN_RW = 6
5
.equ PIN_RS = 7
6
(...)
7
8
.def temp1 = r16 ;Temporäre Variable
9
.def lcd_data = r17 ;LCD-Daten
10
11
;Stackpointer initialisieren
12
ldi temp1,HIGH(RAMEND)
13
out SPH,temp1
14
ldi temp1,LOW(RAMEND)
15
out SPL,temp1
16
17
(...)
18
19
;Text anzeigen
20
ldi lcd_data,'T'
21
rcall show_char
22
23
ldi lcd_data,'e'
24
rcall show_char
25
26
ldi lcd_data,'s'
27
rcall show_char
28
29
ldi lcd_data,'t'
30
rcall show_char
31
32
end:
33
rjmp end
34
35
(...)
36
37
;Zeigt ein Zeichen auf dem Display an
38
show_char:
39
sbi PORTD,PIN_RS
40
out LCD_PORT,lcd_data
41
rcall lcd_enable
42
rcall delay_50us
43
cbi PORTD,PIN_RS
44
ret
45
46
;Wartet 50µs
47
delay_50us:
48
push temp1
49
ldi temp1,(XTAL * 50/3) / 1000000 - 8
50
delay_50us_:
51
dec temp1
52
brne delay_50us_
53
pop temp1
54
ret
55
56
;Schickt einen Enable-Puls ans LCD
57
lcd_enable:
58
sbi PORTD,PIN_E
59
nop
60
nop
61
nop
62
cbi PORTD,PIN_E
63
ret
Meine Vermutung ist, dass das Problem in show_char liegt und ich da
irgendwas mit dem Timing falsch gemacht habe. Ich habe mich am
Datenblatt des KS0066 orientiert und auch testweise an verschiedenen
Stellen nops eingefügt, was mich bisher leider nicht weitergebracht hat.
Im Moment hab ich keinen Ansatzpunkt, was genau das Problem ist,
deswegen wär ich für Hilfe sehr dankbar :-)
Deine Wait Routine scheint falsch zu sein. Rechne doch einfach mal
selber den Wert für temp1 aus. Aber nicht vergessen: Auch in ASM get
Punktrechnung vor Strichrechnung.
Steffen
Steffen H. schrieb:> Auf welchem Potential (0 oder 1) liegt denn RW?
Ich setze in meiner Initialisierungs-Routine den ganzen Port D als
Ausgang und alle Pins auf Low. Also müsste RW 0 sein.
Ich geb dir mal meine alt bewärte LCD-Routine. Ist allerdings für 4bit
Daten. Dafür kannst du jeden PIN für D4-D7, RW, RS und E frei wählen. Du
kannst also auch ein Datenpin auf PB2 und den anderen auf PC0 setzen.
Es ist eine .inc Datei. Du musst sie also irgendwo im Programmcode
mit .include "lcd_routines_4bit" einbinden.
Text Strings werden z.B. im Flash gespeichert. Das ganze könnte dann wie
folgt aussehen.
..
..
rcall Init_LCD
rcall clr_lcd
ldi Data, 0
rcall lcd_pos
ldi ZL, Byte1(phone_discon *2)
ldi ZH, Byte2(phone_discon *2)
rcall lcd_clr_row2
ldi ZL, Byte1(phone_con *2)
ldi ZH, Byte2(phone_con *2)
rcall lcd_printf
loop: rjmp loop
.include "lcd_routines_4bit"
wait: .db "Wait...",0
phone_discon: .db "Please connect Phone",0,0
phone_conw: .db "Phone connect: wait.",0,0
phone_con: .db "Phone connection: OK",0,0
Also ich habs mal mit Deiner Routine versucht, damit bin ich aber auch
zu keinem Ergebnis gekommen. Vermutlich hab ich die nicht 100%ig richtig
umgeschrieben...
Hat sonst noch jemand eine Idee, was an meinem oben geposteten Code
falsch ist? Wie gesagt, Initialisierung funktioniert, Cursor blinkt, nur
Zeichen nimmt das Display bis jetzt nicht an.