Hallo,
Ich wollte ein kleines Programm schreiben, um ein LC Display mit einem
Atmega8 ansteuern und hab dazu für die Initialisierung ein
Assembler-Programm geschrieben und wollte dann ein paar Buchstaben
anzeigen lassen (Sind nur kleine Laufversuche, bin Assembler Anfänger).
Dabei ist mir aufgefallen, dass die Buchstaben nur angezeigt werden,
wenn ich eine Anweisung bei der Initialisierung einbaue, die für mich
eigentlich keinen Sinn ergibt. Vor dieser Anweisung sind noch
"Function-Set", "Display aus", "Display löschen", "Entry-Mode set
(8bit)" und "Display on"
"Unerklärbares" Codestück ist:
1
LDI rmp, 0b10000000;
2
out LCD_DATA, rmp
3
CBI LCD_CONTROL, rw
4
SBI LCD_CONTROL, rs
5
CBI LCD_CONTROL, en ; Enable: H->L Daten übernehmen
Laut Spezifikation ist das eigentlich ein Schreiben von Daten in den RAM
des Bausteins (in dem Fall ein "leeres Zeichen", aber ich verstehe nicht
was das für die Initialisierung zu bedeuten hat.
Wenn das Codestück nicht drinnen ist, dann wird auf dem Display nichts
angezeigt, wenn ich versuche Buchstaben oÄ anzeigen zu lassen.
Das Display verwendet einen HD44780 Baustein und ich hoffe, dass ich
alle Informationen bereitgestellt habe.
Danke schon mal im Voraus!
Ich denke, dass du in Zeile 42 ein bist aus Versehen gelöscht, statt
gesetzt hast und das "SBI LCD_CONTROL, rs" das mit viel Glück rettet. Es
könnte aber auch was ganz andres sein, dazu müsste man aber den
gesamten Code sehen.
Hallo Marc,
laut Datenblatt muss man erst die RS und RW Leitungen setzen, und dann
auf E einen positiven Impuls erzeugen. (E<--1, E<--0 ) Musst du auf
Timing auch aufpassen. Mit welchem Takt läuft der Controller? Nach dem
man RS und RW Leitungen gesetzt hat, muss mindestens 140ns laut
Datenblatt vergehen vor dem Enable Impuls. Aus Deinem Codestück leite
ich ab, dass bei RS=1 und RW = 0 ein CG RAM/DD RAM data write statt
findet. Wie weit das sinnvoll ist, lässt sich nicht aus diesem
5-zeiligen Code heraus lesen.
Also es lag tatsächlich daran, dass ich zuerst en auf 1 und dann wieder
auf 0 setzen musste. Danke für den Tipp @Karoly!!
Bis ich das gesehen hätte wären vermutlich Tage vergangen!!
Falls jemand anderes auch mal nach der Lösung sucht, hier der Init-Code,
den ich jetzt habe:
1
init:
2
LDI rmp, WAITING
3
RCALL delay
4
CBI LCD_CONTROL, en ;Set enable to low -> Datasheet
5
6
LDI rmp, 0b00111100;
7
out LCD_DATA, rmp ; Function Set 2 Lines and 5x10 characters
8
CBI LCD_CONTROL, rw
9
CBI LCD_CONTROL, rs
10
RCALL delayMS ; Wait for one ms
11
12
RCALL enable
13
14
LDI rmp, 0b00001000;
15
out LCD_DATA, rmp ; Display off
16
CBI LCD_CONTROL, rw
17
CBI LCD_CONTROL, rs
18
RCALL delayMS
19
20
RCALL enable
21
22
LDI rmp, 0b00000001;
23
out LCD_DATA, rmp ; Display clear
24
CBI LCD_CONTROL, rw
25
CBI LCD_CONTROL, rs
26
RCALL delayMS
27
28
RCALL enable
29
30
LDI rmp, 0b00000010;
31
out LCD_DATA, rmp ; Set entry mode => Increment cursor
32
CBI LCD_CONTROL, rw
33
CBI LCD_CONTROL, rs
34
RCALL delayMS
35
36
RCALL enable
37
38
LDI rmp, 0b00001111;
39
out LCD_DATA, rmp ; Turn the display on; on, blinking, cursor
Warum machst Du Dir soviel Schreibarbeit, wirst Du nach Zeilen bezahlt?
Gleichen Code macht man nicht als Copy&Paste Monster, sondern fast man
als Funktion zusammen:
Hinweis:
In binär liest es sich doch recht schwer da man jedesmal das DB haben
muss um evtl mal nen Bit zu ändern somit definierst du dir es ähnlich
wie dieses hier
; Pinbelegungen
; STD ;
.equ SClock = 0 ;LCD ;;;
.equ SRS = 0
.equ SData = 1 ;74164 ;;;;;so Kann die HW angeschlossen
sein
.equ SRW = 1
.equ Light = 2 ;LCD ;;;;;
.equ SEnable = 3 ;74164 ;;;
;Entry Set
.equ SH = 0 ;1 = Display shift 0 = not shifted
.equ ID = 1 ;1 = increase 0 = decrease
.equ HES = 2 ;immer 1 setzen Symbolisiert das Ende
;des Commandos
;DISPLAY on/off
.equ B = 0 ;1 = Blink 0 = no Blink
.equ C = 1 ;1 = Cursor on 0 = Cursor off
.equ D = 2 ;1 = Disp on 0 = Disp off
.equ HD = 3 ;immer 1 setzen Symbolisiert das Ende
;des Commandos
;Shift
.equ RL = 2 ;1 = right shift 0 = left shift
.equ SC = 3 ;1 = Disp shift 0 = Cursor move
.equ HS = 4 ;immer 1 setzen Symbolisiert das Ende
;des Commandos
;SET Function
.equ F = 2 ;1 = 5x10 0 = 5x7
.equ N = 3 ;1 = 2line(4line) 0 = 1line
.equ DL = 4 ;1 = 8bit int 0 = 4bit interface
.equ HSF = 5 ;immer 1 setzen Symbolisiert das Ende
;des Commandos
sbi Port_lcd_x,SRS
ldi temp0,(1<<SData|1<<Light|1<<SEnable)
out ddrx_lcd_x,temp0
ntry_mode_std:
ldi temp1,(1<<HES|1<<ID|0<<SH)
rcall lcd_command
ret
lcd_on: ldi temp1,(1<<HD|1<<D|0<<C|0<<B)
rcall lcd_command
ret
lcd_shift:
ldi temp1,(1<<HS|0<<SC|1<<RL)
rcall lcd_command
ret
lcd_function_set_std:
ldi temp1,(1<<HSF|1<<DL|1<<N|0<<F) ;funktionset
rcall lcd_command
nur ein Beispiel Code nicht vollständig
chris schrieb:> In binär liest es sich doch recht schwer da man jedesmal das DB haben> muss um evtl mal nen Bit zu ändern somit definierst du dir es ähnlich> wie dieses hier
Ich würde es sogar noch weiter treiben und die Bitshifterei in den EQUs
machen, und sinnvolle Namen vergeben.
E.g. :