Anfänger mit STK500 und Assembler
Hallo Leute,
beschäftige mich mit der Programmierung des STK500 mit Assembler.
Naja vielleicht sollte ich lieber schreiben, ein Newbi möchte sich mit der Assemblerprogrammierung des STK500 beschäftigen.
Als Software benutze ich die mitgelieferte AVR-Studio.
Habe im Vorfeld schon einiges in Foren und Büchern gelesen.
So als Einstieg und zum besseren Erlernen möchte ich mir kleine Aufgaben stellen und diese dann umsetzen.
Den Code werde ich hier posten und wäre sehr an euren Meinungen, Vorschlägen und Kritiken interessiert.
Zu den Code werde ich immer Kommentare anfügen, damit man versteht was ich damit bezwecke.
Anfangen möchte ich mit einer einfachen Tastenschaltung.
Bei dieser sollen die 8 LEDs des STK500 mit einer Taste entprellt an- bzw. ausgeschaltet werden.
Das STK500 habe ich mit einen ATMega8515 bestückt. PORTB ist mit den Tastern und PORTD mit den LEDs verbunden.
Code:
;***** STK500 Lernprogramm
;*** Aufgabe: alle LEDs mit einem Taster auf dem STK500 an bzw. ausschalten
;*** zum Entprellen soll ein Interrupt(Int0) benutzt werden
;***
.include "m8515def.inc"
.def Temp = r16 ; Temporary register
.def LED_STAT = r17 ; LED sind mit PortB verbunden
;*****
;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 << INT0 ;Interrupt INT0 aktiviert
out GICR, temp
ldi temp, 1 << ISC00 ;Interrupt INT0 konfiguriert
ori temp, 1 << ISC01
out MCUCR, 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:
rjmp MAIN ;Die Schleife ruft mit dem Sprungbefehl
;rjmp sich ständig selbst auf.(endlos)
INT0_ISR:
cli ;Interrupts sperren
in LED_STAT, PORTB ;PORTB auslesen in LED_STAT
com LED_STAT ;Invertieren von LED_STAT
out PORTB, LED_STAT ;Ausgabe von temp an PORTB -> LEDs aus
reti
Das Programm habe ich zum STK500 übertragen und tut auch das was es soll.
verstehe ich das so richtig?
Hallo mare_crisium,
habe mein Listing angepasst.
Beim Testen im Simulator habe ich mir den Datenspeicher mit als Fenter anzeigen lassen und den Verlauf verglichen.
Das erste was nach Eintreten der ISR auf den Stack kommt ist der Programmcounter(zaehler). Dann werden die Registerinhalte, wie ich sie sichere, nach unten gestapelt und spaeter wieder ausgelesen.
Die Speicherinhalte vom Datenspeicher bleiben bestehen, bis sie von erneuten Aufrufen der ISR ggf. ueberschrieben werden.
Code:
;***** STK500 Lernprogramm
;*** Aufgabe: alle LEDs mit einem Taster auf dem STK500 an bzw. ausschalten
;*** zum Entprellen soll ein Interrupt(Int0) benutzt werden
;***
.include "m8515def.inc"
.def Temp = r16 ; Temporary register
.def LED_STAT = r17 ; LED sind mit PortB verbunden
;*****
;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 << INT0 ;Interrupt INT0 aktiviert
out GICR, temp
ldi temp, 1 << ISC00 ;Interrupt INT0 konfiguriert
ori temp, 1 << ISC01
out MCUCR, 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:
rjmp MAIN ;Die Schleife ruft mit dem Sprungbefehl
;rjmp sich ständig selbst auf.(endlos)
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
push R17 ;Inhalt von R17 auf den Stack ablegen
cli ;Interrupts sperren
in LED_STAT, PORTB ;PORTB auslesen in LED_STAT
com LED_STAT ;Invertieren von LED_STAT
out PORTB, LED_STAT ;Ausgabe von LED_STAT an PORTB -> LEDs an bzw. aus
pop R17 ;Ruecksichern von R17
pop R16 ;Ruecksichern von R16(SREG)
out SREG, R16 ;Ruecksichern von SREG
pop R16
reti