Forum: Mikrocontroller und Digitale Elektronik Warum funktioniert dieses LCD-Programm nicht?


von Florian G. (suffix)


Lesenswert?

Hallo,

ich habe versucht, die Routinen hier ausm Wiki für den 
8Bit-Betriebsmodus umzuschrieben.

PORTD ist der Datenport.
PORTB ist zum kontrollieren von RS und EN da.

Bitte schaut euch einma meine Programme an, fragt bei unlaren Befehlen 
und weißt auf Fehler hin, damit ich einen Sofrware-Fehler ausschließen 
kann, wobei die Hardware funktionieren sollte.
1
;lcd-routines.asm 
2
3
.equ LCD_PORT = PORTD
4
.equ LCD_CTRL_PORT = PORTB
5
.equ PIN_EN = 0
6
.equ PIN_RS = 1
7
.equ XTAL = 4000000
8
9
10
11
;LCD enablen
12
lcd_enable:  sbi LCD_CTRL_PORT, PIN_EN    ; Enable high
13
             nop                          ; 3 Taktzyklen warten
14
             nop
15
             nop
16
             cbi LCD_CTRL_PORT, PIN_EN    ; Enable wieder low
17
             ret                          ; Und wieder zurück
18
19
20
;kurze Pause
21
delay50us:   push r16                     ; 50us Pause
22
      ldi  r16, ( XTAL * 50 / 3 ) / 1000000
23
delay50us_:
24
             dec  r16
25
             brne delay50us_
26
      pop  r16
27
             ret                          ; wieder zurück
28
 
29
;Längere Pause für manche Befehle
30
delay5ms:  push r16                     ; 5ms Pause
31
      push r17
32
             ldi  r16, ( XTAL * 5 / 607 ) / 1000
33
WGLOOP0:     ldi  r17, $C9
34
WGLOOP1:     dec  r17
35
             brne WGLOOP1
36
             dec  r16
37
             brne WGLOOP0
38
      pop  r17
39
      pop  r16
40
             ret                          ; wieder zurück
41
42
43
 ; Sendet den Befehl zur Löschung des Displays
44
lcd_clear:
45
           push  r16
46
           ldi   r16,0b00000001       ; Display löschen
47
           rcall lcd_command
48
           rcall delay5ms
49
           pop   r16
50
           ret
51
52
 ; Cursor Home
53
lcd_home:
54
           push  r16
55
           ldi   r16,    0b00000010     ; Cursor Home
56
           rcall lcd_command  
57
           rcall delay5ms
58
           pop   r16
59
           ret
60
  
61
62
 ; Initialisierung: muss ganz am Anfang des Programms aufgerufen werden
63
lcd_init:
64
           push  r16
65
       push   r17
66
       push  r18
67
           ldi   r18,6
68
powerupwait:
69
           rcall delay5ms
70
           dec   r18
71
           brne  powerupwait
72
           ldi   r16,      0b00000011   ; muss 3mal hintereinander gesendet
73
           out   LCD_PORT, r16          ; werden zur Initialisierung
74
           rcall lcd_enable             ; 1
75
           rcall delay5ms
76
           rcall lcd_enable             ; 2
77
           rcall delay5ms
78
           rcall lcd_enable             ; und 3!
79
           rcall delay5ms
80
81
           ldi   r16,      0b00111000   ; 4 Bot, 2 Zeilen
82
           rcall lcd_command
83
           ldi   r16,      0b00001100   ; Display on, Cursor off
84
           rcall lcd_command
85
           ldi   r16,      0b00000100   ; endlich fertig
86
           rcall lcd_command
87
88
           pop   r18
89
       pop   r17
90
       pop   r16
91
           ret
92
93
94
lcd_data:
95
96
       push  r17
97
           push  r18
98
99
           sbi   LCD_CTRL_PORT, PIN_RS
100
101
           out   LCD_PORT, r16           ; ausgeben
102
           rcall lcd_enable              ; Enable-Routine aufrufen
103
104
           rcall delay50us               ; Delay-Routine aufrufen
105
106
           pop   r18
107
           pop   r17
108
           ret                           ; zurück zum Hauptprogramm
109
110
111
lcd_command:
112
113
       push  r17
114
           push  r18
115
116
           cbi   LCD_CTRL_PORT, PIN_RS
117
118
           out   LCD_PORT, r16           ; ausgeben
119
           rcall lcd_enable              ; Enable-Routine aufrufen
120
121
           rcall delay50us               ; Delay-Routine aufrufen
122
123
           pop   r18
124
           pop   r17
125
           ret                           ; zurück zum Hauptprogramm
126
127
       .EXIT
1
;testfile.asm
2
    .include "m16def.inc"
3
    .CSEG          ;Flash-Speicher verwenden
4
    .def akku = r16
5
    rjmp start        ;Interrupts überspringen
6
    .ORG $2A
7
start:   ldi  akku,LOW(RAMEND)  ;Stapel initialisieren
8
    out  SPL,akku
9
    ldi akku,HIGH(RAMEND)
10
    out SPH,akku
11
    ser akku
12
    out DDRB,akku
13
    out DDRD,akku 
14
    rcall lcd_init
15
    rcall lcd_clear
16
    ldi akku,'T'
17
    rcall lcd_data
18
loop:  rjmp loop
19
    .include "lcd_routines.asm"
20
    .EXIT
[/avrasm]

von jack (Gast)


Lesenswert?

Funktioniert denn das Programm nicht?

von jack (Gast)


Lesenswert?

Quatsch, sollte heißen:
Wie äußert sich denn der Fehler?

von Otto (Gast)


Lesenswert?

Oder was macht das Programm und was nicht...

geht z. B. das enable (scope)

Wird das Display initialisiert ?

Gruss Otto

von Suffix (Gast)


Lesenswert?

 Aso, das hatte ich ganz vergessen. Das display bleibt einfach aus und 
macht nichts. Die enable und die rs leitung gehen 2mal kurz auf high und 
bleiben dann high. Datenleitungen gehen auch mehrmalsauf high und 
bleiben es dann. Sieht so aus, als würde er mitten im programm hängen 
bleiben. Mfg suffix

von ich (Gast)


Angehängte Dateien:

Lesenswert?

Probier das mal aus

von Florian G. (suffix)


Lesenswert?

was braucht man denn für dieses skript für vorraussetzungen an Hardware 
und was muss man wann wohin schreiben, um zb ein einfaches T auszugeben?

Hat noch jemand einen Vorschlag, was bei meinem Skript nicht stimmen 
könnte?

von Stefan W. (wswbln)


Lesenswert?

Florian Glaser wrote:

>            ldi   r16,      0b00111000   ; 4 Bot, 2 Zeilen

...was sind "4 Bot"??  ;-)

Schaltest Du das Display in den 4-Bit-Modus (sorry, hab' gerade kein 
Datenblatt greifbar)? - dann klappt's mit dem 8-Bit Port nicht so gut...

von Florian G. (suffix)


Lesenswert?

das ist noch aus dem Originaltext. das soll schon 4bit heißen, aebr laut 
http://www.mikrocontroller.net/articles/HD44780 stellt man mit diesem 
befehl den 8bit-modus ein. Mit Display hat 4*20 Zeichen, aber eigentlich 
sollte es doch auch erstmal mit 2 Zeilen klappen?

Ich habe das Originalprogramm für den 4bit-Modus mit entsprechender 
Beschaltung getestet. Das funktionierte wunderbar, das ist es ja, was 
mich frustiert. Mein Programm ist soweit ok?

von Florian G. (suffix)


Lesenswert?

Keiner was gefunden?

von Michael U. (Gast)


Lesenswert?

Hallo,

powerupwait:
           rcall delay5ms
           dec   r18
           brne  powerupwait
           ldi   r16,      0b00000011   ; muss 3mal hintereinander 
gesendet
           out   LCD_PORT, r16          ; werden zur Initialisierung
           rcall lcd_enable             ; 1

wenn das Dein Code ist, stimmt es nicht.
Du sendest 3x 0x03, Du musst aber 3x 0x30 also 0b00110000 senden...
Danach die 0x38 ist dann ok.

Gruß aus Berlin
Michael

von Florian G. (suffix)


Lesenswert?

Da hast du natürlich recht. Habe ich eben korrigiert, funktioniert 
wunderbar! Danke für eure Hilfe!

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.