Forum: Mikrocontroller und Digitale Elektronik LCD Initialisierung mit Atmega


von Marc O. (Gast)


Lesenswert?

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!

von Hi (Gast)


Lesenswert?

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.

von Hi (Gast)


Lesenswert?

Hi schrieb:
> bist
Syr, sollte "bit" heißen.

von Karoly (Gast)


Lesenswert?

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.

von Marc O. (Gast)


Lesenswert?

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
40
  CBI LCD_CONTROL, rw
41
  CBI LCD_CONTROL, rs
42
  RCALL delayMS
43
44
  RCALL enable
45
46
  RET
47
48
enable:
49
  SBI LCD_CONTROL, en
50
  RCALL delayMS
51
  CBI LCD_CONTROL, en
52
  LDI rmp,WAITING
53
  RCALL delay
54
  RET

von Peter D. (peda)


Lesenswert?

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:
1
  LDI rmp, 0b00111100; 
2
  rcall lcd_command
3
  LDI rmp, 0b00001000; 
4
  rcall lcd_command
5
  LDI rmp, 0b00000001; 
6
  rcall lcd_command
7
  LDI rmp, 0b00000010; 
8
  rcall lcd_command
9
  LDI rmp, 0b00001111; 
10
  rcall lcd_command

von chris (Gast)


Lesenswert?

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

von Eric B. (beric)


Lesenswert?

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. :
1
.equ CMD_DISPLAY_CTL = 8
2
.equ DSPL_ON         = 4
3
.equ DSPL_OFF        = 0
4
.equ CRSR_ON         = 2
5
.equ BLINK           = 1
6
.equ NO_BLINK        = 0
7
8
9
  ldi  param,(CMD_DISPLAY_CTL|DSPL_ON|CRSR_OFF|NO_BLINK)
10
  call lcd_command

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.