Hallo,
ich bin gerade dabei, mich in die Programmierung für AVRs einzuarbeiten.
Ich habe hier ein STK500, darin steckt ein ATMEGA8515.
Ich bin kein Programmierneuling, aber mit ASM habe ich bisher nicht
gearbeitet. Daher also Newbie und ich bitte um Nachsicht.
Ich bin im AVR-Tutorial nun beim Thema Stack angelangt. Das Programm,
dass dort gezeigt wird:
1 | .include "m8def.inc"
|
2 |
|
3 | .def temp = r16
|
4 |
|
5 | ldi temp, HIGH(RAMEND) ; HIGH-Byte der obersten RAM-Adresse
|
6 | out SPH, temp
|
7 | ldi temp, LOW(RAMEND) ; LOW-Byte der obersten RAM-Adresse
|
8 | out SPL, temp
|
9 |
|
10 | rcall sub1 ; sub1 aufrufen
|
11 |
|
12 | loop: rjmp loop
|
13 |
|
14 |
|
15 | sub1:
|
16 | ; hier könnten ein paar Befehle stehen
|
17 | rcall sub2 ; sub2 aufrufen
|
18 | ; hier könnten auch Befehle stehen
|
19 | ret ; wieder zurück
|
20 |
|
21 | sub2:
|
22 | ; hier stehen normalerweise die Befehle,
|
23 | ; die in sub2 ausgeführt werden sollen
|
24 | ret ; wieder zurück
|
Hier bekomme ich an der Stelle rcall sub1 die Meldung "AVR Simulator:
Uninitialized stack pointer used at 0x0004". Soso, der Stackpointer ist
nicht initialisiert? Aber das hab ich oben doch gemacht...?
Funktionieren scheint das Programm trotzdem ordnungsgemäß, auf jeden
Fall im Simulator.
Damit man etwas sieht, und um ein bisschen zu üben, hab ich mir
folgendes Programm zusammengeklöppelt:
1 | .include "m8def.inc"
|
2 |
|
3 | init:
|
4 | ldi r16, HIGH(RAMEND) ; HIGH-Byte der obersten RAM-Adresse
|
5 | out SPH, r16
|
6 | ldi r16, LOW(RAMEND) ; LOW-Byte der obersten RAM-Adresse
|
7 | out SPL, r16
|
8 |
|
9 | ldi r16, 0xFF ; PortB ist Ausgang
|
10 | out DDRB, r16
|
11 |
|
12 | ldi r16, 0x00 ; PortD ist Eingang
|
13 | out DDRD, r16
|
14 |
|
15 | ldi r16, 0xFF ; Alle LEDs ausschalten
|
16 | out PORTB, r16
|
17 |
|
18 | mainloop: ; Schalter einlesen
|
19 |
|
20 | sbis PIND, 0
|
21 | rcall sub1
|
22 |
|
23 | sbis PIND, 1
|
24 | rcall sub2
|
25 |
|
26 | sbis PIND, 2
|
27 | rcall sub3
|
28 |
|
29 | rjmp mainloop
|
30 |
|
31 | sub1: ldi r17, 0b00000000
|
32 | out PORTB, r17
|
33 | ret
|
34 |
|
35 | sub2: ldi r17, 0b11111111
|
36 | out PORTB, r17
|
37 | ret
|
38 |
|
39 | sub3: ldi r17, 0b10101010
|
40 | out PORTB, r17
|
41 | ret
|
Hier bekomme ich bei jedem rcall die selbe Fehlermeldung, aber wieder
scheint das Programm korrekt zu funktionieren. Übertrag ich es aber in
den µC, dann springt das Programm bei jedem ret wieder komplett an den
Programmanfang. Das ist daran zu erkennen, dass wenn man z.B. SW0
drückt, die LEDs sofort wieder ausgehen, wenn man den Taster loslässt.
Aber eigentlich sollten die LEDs ja solange anbleiben, bis man den
nächsten Taster drückt.
Woran liegt das, wo liegt mein Fehler?
Danke!
Jens