Hallo mare_crisium,
habe den Code zum Tasten_3 nach Deinen Vorschlaegen angepasst.
Teil 1war ja im Prinzip nur das Sichern der Register in den Unterprogrammen.
Das Register 17 kann ich nicht mit Sichern, da ich es als Zaehlvariable in der ISR benutze.
Mit R16 – temp kein Problem. Funktioniert:
Der 2. Tipp macht mir jedoch Kopfzerbrechen(Seite 5- TESTE_02 bzw. TESTE_03)Code:;***** STK500 Lernprogramm Nr.3c ;*** Aufgabe: alle LEDs mit einem Taster auf dem STK500 schalten ;*** 1. Tastendruck: LEDs einschalten ;*** 2. Tastendruck: LEDs blinken ;*** 3. Tastendruck: LEDs ausschalten ;*** zum Entprellen soll ein Interrupt(Int0) benutzt werden ;*** .include "m8515def.inc" .def Temp = r16 ; Temporary register .def Tast_Stat = r17 ; Zaehler fuer Taste in ISR .def Delay = R18 ; Wartezeit .def Delay2 = R19 ; Wartezeit ;***** ;Reset and Interrupt vector ;VNr. Beschreibung rjmp RESET ;1 POWER ON RESET rjmp INT0_ISR ;2 Int0-Interrupt reti ;3 Int1-Interrupt reti ;4 TC1 Capture reti ;5 TC1 Compare Match A TC2 Overflow reti ;6 TC1 Compare Match B TC1 Capture reti ;7 TC1 Overflow TC1 Compare Match A reti ;8 TC0 Overflow TC1 Compare Match B reti ;9 SPI, STC Serial Transfer Complete TC1 Overflow reti ;10 UART Rx Complete TC0 Overflow reti ;11 UART Data Register Empty SPI, STC Serial Transfer Complete reti ;12 UART Tx Complete UART Rx Complete reti ;13 Analog Comparator reti ;14 Int2-Interrupt reti ;15 Timer 0 Compare Match reti ;16 EEPROM Ready reti ;17 Store Program Memory Ready RESET: ldi r16, LOW(RAMEND) ;Stack initialisieren out SPL, r16 ldi r16, HIGH(RAMEND) out SPH, r16 ldi temp, (1<<ISC00)|(1<<ISC01) out MCUCR, temp ;Interrupt INT0 konfiguriert ldi temp, 1 << INTF0 ;InterruptFlagregister geloescht out GIFR, temp ldi temp, 1 << INT0 ;Interrupt INT0 aktiviert out GICR, temp clr Temp ;Temp mit 0b00000000 bzw. 0x00 laden out DDRD, Temp ;PORTD als Eingang ser Temp ;Temp mit 0b11111111 bzw. 0xFF laden out PORTD, temp ;PullUp an PortD einschalten out DDRB,Temp ;PORTB als Ausgang out PORTB, temp ;PORTB (LEDs) aus sei ;Interrupts zulassen MAIN: rcall TESTE rjmp MAIN TESTE: push r16 in r16,SREG push r16 clr temp ;loesche temp inc temp ;increment von temp - "1" cp Tast_Stat,temp ;ist TastStat = 1 dann Rufe Sub LED_AN auf, sonst ueberspringe naechsten Befehl breq LED_AN inc temp ;increment von temp - "2" cp Tast_Stat,temp ;ist TastStat = 2 dann Rufe Sub LED_BLINK auf, sonst ueberspringe naechsten Befehl breq LED_BLINK inc temp ;increment von temp - "3" cp Tast_Stat,temp ;ist TastStat = 3 dann Rufe Sub LED_AUS auf, sonst ueberspringe naechsten Befehl breq LED_AUS rjmp TESTE_EXIT LED_AN: ;loesche temp clr temp ;setze alle Bit in temp (0b00000000 bzw. 0x00) out PORTB, temp ;Ausgabe an PortB rjmp TESTE_EXIT LED_BLINK: in temp,PORTB ;lese PORTB in temp com temp ;Einercomplement von temp (ist 0b00000000 > 0b11111111 oder umgekehrt) out PORTB,temp ;Ausgabe an PortB Tot_Zeit: dec Delay ;zaehle ein Register R18 - 0b0000000 runter und springe danach aus der Schleife brne Tot_Zeit ;dec Delay2 ;zaehle ein Register R19 - 0b0000000 runter und springe danach aus der Schleife ;brne Tot_Zeit rjmp TESTE_EXIT LED_AUS: ser temp ;setze alle Bits in temp (0b11111111 bzw. 0xFF) out PORTB,temp ;Ausgabe an PORTB clr Tast_Stat ;Loesche Tast_Stat sleep rjmp TESTE_EXIT TESTE_EXIT: pop r16 out SREG,r16 pop r16 ret INT0_ISR: push R16 ;Inhalt von R16 auf Stack ablegen in R16, SREG ;Statusregister in R16 lesen push R16 ;Inhalt von R16(SREG) auf den Stack ablegen inc Tast_Stat pop R16 ;Ruecksichern von R16(SREG) out SREG, R16 ;Ruecksichern von SREG pop R16 ;Ruecksichern von R16 reti
Beim Simulieren im AVR-Studio bekomme ich Speicherfehler, da das Programm den STACK durcheinander bringt...?)
eventuell habe ich auch einen Bug mit eingebaut.Code:;***** STK500 Lernprogramm Nr.3b ;*** Aufgabe: alle LEDs mit einem Taster auf dem STK500 schalten ;*** 1. Tastendruck: LEDs einschalten ;*** 2. Tastendruck: LEDs blinken ;*** 3. Tastendruck: LEDs ausschalten ;*** zum Entprellen soll ein Interrupt(Int0) benutzt werden ;*** .include "m8515def.inc" .def Temp = r16 ; Temporary register .def Tast_Stat = r17 ; Zaehler fuer Taste .def Delay = R18 ; Wartezeit .def Delay2 = R19 ; Wartezeit ;***** ;Reset and Interrupt vector ;VNr. Beschreibung rjmp RESET ;1 POWER ON RESET rjmp INT0_ISR ;2 Int0-Interrupt reti ;3 Int1-Interrupt reti ;4 TC1 Capture reti ;5 TC1 Compare Match A TC2 Overflow reti ;6 TC1 Compare Match B TC1 Capture reti ;7 TC1 Overflow TC1 Compare Match A reti ;8 TC0 Overflow TC1 Compare Match B reti ;9 SPI, STC Serial Transfer Complete TC1 Overflow reti ;10 UART Rx Complete TC0 Overflow reti ;11 UART Data Register Empty SPI, STC Serial Transfer Complete reti ;12 UART Tx Complete UART Rx Complete reti ;13 Analog Comparator reti ;14 Int2-Interrupt reti ;15 Timer 0 Compare Match reti ;16 EEPROM Ready reti ;17 Store Program Memory Ready RESET: ldi r16, LOW(RAMEND) ;Stack initialisieren out SPL, r16 ldi r16, HIGH(RAMEND) out SPH, r16 ldi temp, (1<<ISC00)|(1<<ISC01) out MCUCR, temp ;Interrupt INT0 konfiguriert ldi temp, 1 << INTF0 ;InterruptFlagregister geloescht out GIFR, temp ldi temp, 1 << INT0 ;Interrupt INT0 aktiviert out GICR, temp clr Temp ;Temp mit 0b00000000 bzw. 0x00 laden out DDRD, Temp ;PORTD als Eingang ser Temp ;Temp mit 0b11111111 bzw. 0xFF laden out PORTD, temp ;PullUp an PortD einschalten out DDRB,Temp ;PORTB als Ausgang out PORTB, temp ;PORTB (LEDs) aus sei ;Interrupts zulassen MAIN: rcall TESTE rjmp MAIN TESTE: push r16 in r16,SREG push r16 ; In Abhängigkeit von Tast_Stat Aktivität auswählen clr temp ; inc temp ; temp := Vergleichszahl; Anfangswert Eins cp Tast_Stat,temp brne TESTE_02 ; Sprung, wenn TastStat <> 1 rcall LED_EIN rjmp TESTE_EXIT TESTE_02: ; Tast_Stat > 1 inc temp cp Tast_Stat,temp ; Vergleichszahl := 2 brne TESTE_03 ; Sprung, wenn TastStat <> 2 rcall LED_BLINK rjmp TESTE_EXIT TESTE_03: ; Tast_Stat > 3 inc temp ; Vergleichszahl := 3 cp Tast_Stat,temp brne TESTE_EXIT ; Sprung, wenn TastStat <> 3 rcall LED_AUS LED_EIN: ;loesche temp clr temp ;setze alle Bit in temp (0b00000000 bzw. 0x00) out PORTB, temp ;Ausgabe an PortB rjmp TESTE_EXIT LED_BLINK: in temp,PORTB ;lese PORTB in temp com temp ;Einercomplement von temp (ist 0b00000000 > 0b11111111 oder umgekehrt) out PORTB,temp ;Ausgabe an PortB ;Tot_Zeit: ;dec Delay ;zaehle ein Register R18 - 0b0000000 runter und springe danach aus der Schleife ;brne Tot_Zeit ;dec Delay2 ;zaehle ein Register R19 - 0b0000000 runter und springe danach aus der Schleife ;brne Tot_Zeit rjmp TESTE_EXIT LED_AUS: ser temp ;setze alle Bits in temp (0b11111111 bzw. 0xFF) out PORTB,temp ;Ausgabe an PORTB clr Tast_Stat ;Loesche Tast_Stat rjmp TESTE_EXIT TESTE_EXIT: pop r16 out SREG,r16 pop r16 ret INT0_ISR: push R16 ;Inhalt von R16 auf Stack ablegen in R16, SREG ;Statusregister in R16 lesen push R16 ;Inhalt von R16(SREG) auf den Stack ablegen inc Tast_Stat pop R16 ;Ruecksichern von R16(SREG) out SREG, R16 ;Ruecksichern von SREG pop R16 ;Ruecksichern von R16 reti
Nach dem 1. Abarbeiten der ISR kommt das LED_EIN.
Hier wird wieder durch das rjmp der Programmzaehler auf den Stack abgelegt.
Danach der Sprung zum TESTE_EXIT.
Dabei wird ins SREG 0X00 (ein Teil vom Programmzaehler - rjmp LED_EIN) rein geschrieben.
-muesste da nicht doch LED_EIN mit „ret“ beendet werden?







Zitieren

Lesezeichen