Hi,
ich verusche ein LCD anzusteuern.
Das LCD ist leider noch nicht da, aber ich habe beim Simulieren bemerkt
das irgendwie der Stack überläuft.
Nachdem ich gleich nach der Stack-Initialisierung (nur zum Test) nachdem
ich die Adresse in den z-Pointer geladen habe mit rcall lcd_send_Data
das UP aufrufe.
Dort geht es auch noch durch, durch das weitere UP wait5ms geht es auch
noch.
Dann wenn das ret von lcd_send_data ausgeführt wird, lande ich wieder
bei init.
Woran liegt das?
Habe ich irgendwo veressen wieder ein Register zurück zu holen, oder
derartiges?
Mir fällt nämlich da nichts auf, was ich vergessen haben könnte.
Wäre gut wenn mir da jemand helfen könnte. 1 ;********************************:
2 ;* Display-Ansteuerung ATMEGA16 *;
3 ;* PA0 DB4 *;
4 ;* PA1 DB5 *;
5 ;* PA2 DB6 *;
6 ;* PA3 DB7 *;
7 ;* PA4 RS *;
8 ;* PA5 E *;
9 ;********************************;
10 .include "m16def.inc"
11
12 .def temp = r16
13 .def temp1 = r17
14 .def temp2 = r18
15 .def lcd_data = r19
16
17 .equ LCD_PORT = PORTA
18 .equ XTAL = 16000000
19
20 rjmp init ; Reset Handler
21
22
23 init:
24 ldi temp, LOW(RAMEND) ; Stackpointer initialisieren
25 out SPL, temp
26 ldi temp, HIGH(RAMEND)
27 out SPH, temp
28
29 ldi temp, $FF
30 out PORTA, temp
31
32 ldi ZL, LOW(menu*2) ; Adresse des Strings in den
33 ldi ZH, HIGH(menu*2) ; Z-Pointer laden
34 rcall lcd_text
35
36 lcd_init:
37 ldi temp,8 ; 30ms Power-On-Wait
38 powerupwait:
39 rcall delay5ms
40 dec temp
41 brne powerupwait
42
43 ldi temp, 0b00000010 ; pad byte
44 out LCD_PORT, temp
45 rcall lcd_enable
46 rcall delay50us
47 rcall lcd_enable
48 rcall delay50us
49 rcall lcd_enable
50 rcall delay50us
51
52
53 ldi temp, 0b01100000 ; function set
54 rcall lcd_command
55 rcall delay50us
56
57 ldi temp, 0b00001111 ; display on
58 rcall lcd_command
59 rcall delay50us
60
61 rcall lcd_clear
62
63 ldi temp, 0b00000111 ; entry mode set
64 rcall lcd_command
65 rcall delay50us
66
67 ldi ZL, LOW(menu*2) ; Adresse des Strings in den
68 ldi ZH, HIGH(menu*2) ; Z-Pointer laden
69 rcall lcd_text
70
71 loop:
72
73
74 rjmp loop
75
76 ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++;
77 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UP´s für LCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
78
79 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Befehl an LCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
80 lcd_command:
81 push temp
82 mov temp, lcd_data ; wie lcd_data, nur ohne RS zu setzen
83 mov temp1, temp
84 swap temp1
85 andi temp1, 0b00001111
86 out LCD_PORT, temp1
87 rcall lcd_enable
88
89 andi temp, 0b00001111
90 out LCD_PORT, temp
91 rcall lcd_enable
92 rcall delay50us
93 pop temp
94 ret
95
96 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Datenbyte an LCD;;;;;;;;;;;;;;;;;;;;;;;;;;;
97 lcd_send_data:
98 push temp
99 push temp1
100
101 mov temp, lcd_data
102 mov temp1, temp
103
104 swap temp1
105 andi temp1, 0b00001111
106 sbr temp1, 4
107 out LCD_PORT, temp1
108 rcall lcd_enable ; 2. Nibble, kein swap da es schon
109
110 andi temp, 0b00001111
111 sbr temp, 4
112 out LCD_PORT, temp
113 rcall lcd_enable
114 rcall delay50us
115 ret
116
117 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Befehl "Display löschen";;;;;;;;;;;;;;;;;;;;
118 lcd_clear:
119 ldi temp, 0b00000001
120 rcall lcd_command
121 rcall delay5ms
122 ret
123
124 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Befehl "Cursor Home";;;;;;;;;;;;;;;;;;;;;;;;
125 lcd_home:
126 ldi temp, 0b00000010
127 rcall lcd_command
128 rcall delay5ms
129 ret
130
131 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;LCD-Enable;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
132 lcd_enable:
133 nop
134 nop
135 sbi LCD_PORT, 5
136 nop
137 nop
138 nop
139 cbi LCD_PORT, 5
140 ret
141
142 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Text ausgeben;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
143 lcd_text:
144
145 lcd_text1:
146 lpm lcd_data, Z+
147 cpi lcd_data, 0
148 breq lcd_text2
149 rcall lcd_send_data
150 rjmp lcd_text1
151
152 lcd_text2:
153 ret
154
155 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Dezimalzahl ausgeben;;;;;;;;;;;;;;;;;;;;;;;;;;
156 lcd_number:
157 mov temp, lcd_data
158 push temp
159 push temp1
160
161 mov temp1, temp
162
163 ldi temp, '0'-1
164 lcd_number_1:
165 inc temp
166 subi temp1, 100
167 brcc lcd_number_1
168
169 subi temp1, -100
170 mov lcd_data, temp
171 rcall lcd_send_data
172
173 ;** Zehner **
174 ldi temp, '0'-1
175 lcd_number_2:
176 inc temp
177 subi temp1, 10
178 brcc lcd_number_2
179 subi temp1, -10
180
181 mov lcd_data, temp
182 rcall lcd_send_data ; die Zehnerstelle ausgeben
183
184 ;** Einer **
185 ldi temp, '0'
186 add temp, temp1
187 mov lcd_data, temp
188 rcall lcd_send_data
189 pop temp1
190 pop temp
191 ret
192 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50us Pause;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
193 delay50us:
194 push temp
195 push temp1
196 delay50us_1:
197 ldi temp, 0
198 delay50us_2:
199 dec temp
200 brne delay50us_2
201 inc temp1
202 cpi temp1, 4
203 brne delay50us_1
204
205 pop temp1
206 pop temp
207 ret
208
209 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5ms Pause;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
210 delay5ms:
211 push temp
212 push temp1
213 ldi temp, $86
214 delay5ms_1:
215 ldi temp1, $C6
216 delay5ms_2:
217 dec temp1
218 brne delay5ms_2
219 dec temp
220 brne delay5ms_1
221 pop temp1
222 pop temp
223 ret
224 ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++;
225 ;
226
227
228 menu:
229 .db "~~~~Herzlich~~~~~~~Willkommen~~~", 0
von
spess53 (Gast)
15.07.2009 16:54
Hi
>lcd_send_data:
> push temp
> push temp1
.........
> rcall lcd_enable
> rcall delay50us
> ret
MfG Spess
Alles was du per PUSH auf den Stack beförderst mußt du auch vor dem
RET wieder vom Stack per POP anholen.
Und wenn du dir mal deine Routine anschust siehst du: Da fehlt doch
was...
Ah, vielen Dank, dass habe ich nämlich nicht gesehn.
Problem gelöst.
mfg
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.