Code:
;***** STK500 Lernprogramm Nr.4d
;*** Aufgabe: die Taste an PinD0 schaltet die zugeordnete LED auf dem STK500
;*** 1. Tastendruck: LEDs einschalten
;*** 2. Tastendruck: LEDs ausschalten
;*** eine Timerroutine liest den TastenStatus ein
;*** zum Entprellen - muss die TimerRoutine 3mal hintereinander den gleichen Wert
;*** einlesen um einen Tastzustand zu erkennen, Zst_Var 0x03(log 1) bzw. 0x00(log 0)
;*** Taste nicht gedrueckt >>> log 0 in Tast_Stat(r17)
;*** Taste gedrueckt >>> log 1 in Tast_Stat(r17)
;
;
.include "m8515def.inc"
.def Temp = r16 ; Temporary Register
.def Tast_Stat = r17 ; Tasten Status
.def Tast_Stat0 = r18
.def LED_Stat = r19 ; LED Status
.def Zst_Var = r20 ; Zustandsvariable - beinhaltet eine 2Bit-Zahl zur Tastzustandserkennung
.def TOGGLE_SPRR = r21 ; Sperrt die Ausfuehrung von TastenTest wenn, keine neuer TIMER1_OVL voran gegangen
;
; TimerWerte(bei 8MHz - ca. 0,2sec)
.equ Timerwert = -60 ; Timerschritte bis zum Überlauf(fuer Simulatortest)
;.equ Timerwert = -1562 ; Timerschritte bis zum Überlauf
;
;
.equ LED_PORT = PORTB ; LEDs
.equ LED_DDR = PORTB-1 ; DataDirectory fuer LEDs
.equ TAST_PORT= PORTD ; Tasten
.equ TAST_DDR = PORTD-1 ; DataDirectory fuer TastenEingang
.equ TAST_PIN = PORTD-2 ; TastenEingang
;
;*****
;Reset and Interrupt vector ;VNr. Beschreibung
rjmp RESET ;1 POWER ON RESET
reti ;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
rjmp TIMER1_OVF ;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 temp,(1<<CS10) ; Taktfrequenz Vorteiler 1 gewaehlt (fuer Simaulatortest)
; ldi temp,(1<<CS10)|(1<<CS12) ; Taktfrequenz mit Vorteiler 1024 gewaehlt
out TCCR1B,temp
; Timer1 vorladen
ldi temp,HIGH(Timerwert)
out TCNT1H,temp
ldi temp,LOW(Timerwert)
out TCNT1L,temp
ldi temp,(1<<TOIE1) ; Timer1 Overflow aktivieren
out TIMSK,temp
ldi r16, LOW(RAMEND) ;Stack initialisieren
out SPL, r16
ldi r16, HIGH(RAMEND)
out SPH, r16
clr Temp ;Temp mit 0b00000000 bzw. 0x00 laden
out TAST_DDR, Temp ;PORTD als Eingang
ser Temp ;Temp mit 0b11111111 bzw. 0xFF laden
out TAST_PIN, temp ;STK500 schaltet gegen GND - Taste gedreuckt (Pin==0)
out TAST_PORT, temp ;PullUp an PortD einschalten
out LED_DDR,Temp ;PORTB als Ausgang
out LED_PORT, temp ;PORTB (LEDs) aus
clr Tast_Stat ;Tast_Stat auf def. Zustand
clr Zst_Var
sei ; globale Interruptfreigabe
MAIN:
sbrc TOGGLE_SPRR,0 ; kein TOGGLE, wenn Bit0 ==0
rcall TOGGLE
rjmp MAIN
TIMER1_OVF:
push TEMP ; TEMP auf Stack sichern
in TEMP,SREG ; SREG auf Stack sichern
push TEMP ;
in Tast_Stat0, PIND ; Tasten werden komplett eingelesen
com Tast_Stat0 ; invertiere
clt ; loesche T-Flag
SBRC Tast_Stat0,0 ; RegisterBit0 von TastStat ==0 ueberspringe / T-Flag wird nicht gesetzt
set ; ==1 setze T-Flag
;
; default wird -1 in temp eingetragen | springt bei nicht gesetzten T-Flag zu TastZst0
; bei gesetzten T-Flag wird +1 in temp eingetragen
;
ldi temp, 0x03 ; temp == "-1"
brtc TastZst0
ldi temp, 0x01 ; temp == "+1"
;
; TastZustand0
;
TastZst0:
cpi Zst_Var,0x00 ; vergleiche ob Zst_Var ==0
brne TastZst1 ; springe wenn ungleich
sbrs temp, 0x01 ; ueberspringe naechsten Befehl, wenn temp negativ(0x03) ist
add Zst_Var, temp ; addieren temp in Zst_Var
rjmp TastZst_Exit
;
; TastZustand1
;
TastZst1:
cpi Zst_Var, 0x01 ; vergleiche ob Zst_Var ==1
brne TastZst2
add Zst_Var, temp
rjmp TastZst_Exit
;
; TastZustand2
;
TastZst2:
cpi Zst_Var, 0x02 ; vergleiche ob Zst_Var ==2
brne TastZst3
add Zst_Var, temp
rjmp TastZst_Exit
;
; TastZustand3 ; Fehler abfangen Zst_Var darf nur Werte zwischen 0x00 und 0x03 haben
;
TastZst3:
cpi Zst_Var, 0x03 ; vergleiche ob Zst_Var ==3
brne TastZst_Error
sbrc temp, 0x01
add Zst_Var, temp
;
TastZst_Error:
;
TastZst_Exit:
andi Zst_Var, 0xFB ; eventuellen Uebertrag loeschen
;
cpi Zst_Var, 0x00 ; ueberspringe naechsten Befehl
brne Test2
cbr Tast_Stat,0x01 ; >>>>>Taste nicht gedrueckt
;
Test2:
cpi Zst_Var,0x03 ; ueberspringe naechsten Befehl
brne T0_OVL_Exit
sbr Tast_Stat,0x01 ; >>>>>Taste gedrueckt
;
T0_OVL_Exit:
; Timer1 vorladen
ldi temp,HIGH(Timerwert)
out TCNT1H,temp
ldi temp,LOW(Timerwert)
out TCNT1L,temp
;
sbr TOGGLE_SPRR,0 ; Status fuer TOGGLE 1 - TOGGLE / 0 - kein TOGGLE
pop TEMP ;
out SREG,TEMP ; SREG zurueckschreiben
pop TEMP ; TEMP zurueckschreiben
reti
TOGGLE:
cbr TOGGLE_SPRR,0 ; loesche Bit0, um TOGGLE bis zum naechsten TIMER1_OVF zu sperren
nop ; kommt spaeter
ret
Ganz zufrieden bin ich damit nicht..
Lesezeichen