Code:
;**********************************************************************************
;Beschreibung:
;Dieses Programm lässt verschiedene "Licht-Programme" an PortB und Port D des
;des Mikrocontrollers ablaufen. Timer1 ist der "Programm-Timer" und
;Timer0 der BlinkTimer für die Programme. Timer2 dient zum LED-Fading als PWM.
;**********************************************************************************
.include "m8def.inc" ;Die Definitionsdatei des ATmega8 einfügen.
.def temp = R16 ;Es werden in diesem Programm 2 Arbeitsregister benötigt.
.def temp2 = R17 ;benötigt: R16 und R17 (ginge auch mit nur einem).
.def prog = R18 ;Aktuelles Programm
.def runs = R19 ;Erster Timerdurchlauf
rjmp RESET ; Reset Handler
reti ; IRQ0 Handler
reti ; IRQ1 Handler
rjmp Timer2_CompareHandler ; Timer2 Compare Handler => Zur LED-Dimmung
reti ; Timer2 Overflow Handler
reti ; Timer1 Capture Handler
reti ; Timer1 CompareA Handler
reti ; Timer1 CompareB Handler
rjmp Timer1_Overflow ; Timer1 Overflow Handler => Programmwechsel
rjmp Timer0_Overflow ; Timer0 Overflow Handler => zyklischer Programmablauf (blinken, aufsteigend, absteigend, ...)
reti ; SPI Transfer Complete Handler
reti ; USART RX Complete Handler
reti ; UDR Empty Handler
reti ; USART TX Complete Handler
reti ; ADC Conversion Complete Handler
reti ; EEPROM Ready Handler
reti ; Analog Comparator Handler
reti ; Two-wire Serial Interface Handler
reti ; Store Program Memory Ready Handler
reset:
ldi temp, LOW(RAMEND) ;Initialisieren des StackPointers:
out SPL, temp
ldi temp, HIGH(RAMEND)
out SPH, temp
;============================ Int. Oszillator kalibrieren ============================
ldi temp, $C2 ;Diesen Wert im STK500-Steuerpanel ablesen unter "Advanced" (dort wird
out OSCCAL, temp ;auch die gewünschte Frequenz des int. Oszillators eingestellt).
;============================ Timer0 ============================ (Erstmal auskommentiert, denn Timer0 soll in Timer1 gestartet werden)
;ldi temp, 0b101 ;Timer0 starten mit Vorteiler 1:1024 (Teilt die Blinkfrequenz durch 1024)
;out TCCR0, temp ;TCCR0 ist das Kontrollregister des Timers 0
;============================ Timer ============================
ldi temp, 1<<TOIE1 | 1 <<TOIE0 ; Timer0-Overflow und Timer1-Overflow "erlauben"
out TIMSK, temp
ldi temp, 0xFF ; Timer1 "vorspulen"
out TCNT1H, temp
ldi temp, 0xFE
out TCNT1L, temp
ldi temp, 1<<CS12|1<<CS10 ;Timer1 starten mit Vorteiler 1:1024 (Teilt die Frequenz durch 1024)
;ldi temp, 1<<CS11 ; nur zu Debug-Zwecken
out TCCR1B, temp
ser temp ;Arbeitsregister "temp" mit Einsern füllen.
out DDRB, temp ;Datenrichtungsregister des Ports B mit Einsern aus "temp" füllen (= alle Pins des Ports als AUSGANG)
out PORTB, temp ;Alle Pins des Ports auf's High-Level bringen
out DDRD, temp ; Alle Pins von PortD als Ausgang festlegen
out PORTD, temp ; Alle Pins auf HIGH setzen
ldi prog, 4 ; Bei Programm 0 beginnen
sei ;Interrupts freigeben
;------------------------------
; ============================ Hauptprogramm ============================
loop:
;Warten auf Timer0/1-Überlauf in einer Endlosschleife.
rjmp loop
; ============================ Hauptprogramm Ende ============================
; ============================ Programmwechsel-Timer ============================
Timer1_Overflow:
push temp ; Sichern von "TEMP" im Stack
in temp, SREG ; Einlesen des SREG
push temp ; Schreiben von SREG im Stack (KOPIE)
cpi prog, 5 ; Programmüberlauf?
BRGE resetProg
rjmp continue
resetProg:
CLR prog
continue:
ldi temp, 0b000 ; Timer0 beenden (Kein Blinken)
out TCCR0, temp
ldi temp, 0xFF ; LEDs jetzt an
out PORTB, temp
out PORTD, temp
ldi runs, 0
cpi prog, 0
brne Prog1
;Prog0 ausfuehren: LEDs an (schon geschehen)
rjmp ende
Prog1:
cpi prog, 1
brne Prog2
;Prog1 ausfuehren: LEDs blinken
ldi temp, 0xFE
out TCNT0, temp
ldi temp, 0b101 ;Timer0 starten
out TCCR0, temp
rjmp ende
Prog2:
cpi prog, 2
brne Prog3
;Prog2 ausfuehren: LEDs absteigend
ldi temp, 0xFF
out TCNT0, temp
ldi temp, 0b101 ;Timer0 starten mit Vorteiler 1:1024 (Teilt die Blinkfrequenz durch 1024)
out TCCR0, temp
rjmp ende
Prog3:
cpi prog, 3
brne Prog4
;Prog3 ausfuehren: LEDs aufsteigend
ldi temp, 0xFF
out TCNT0, temp
ldi temp, 0b101
out TCCR0, temp
ldi temp, 0
out PORTB, temp
out PORTD, temp
rjmp ende
Prog4:
cpi prog, 4
brne ende
; Prog4 ausfuehren: Test-Fading
ldi temp, 0x01 ; Zur Kontrolle die ersten beiden LEDs einschalten
out PORTB, temp
out PORTD, temp
ldi temp, 1<<OCIE2 | 1<<TOIE1 | 1 <<TOIE0 ; Timer0-Overflow und Timer1-Overflow und Timer2-Compare "erlauben"
out TIMSK, temp
ldi temp, 1 << COM20 | 1 << WGM21 | 0 << CS22 | 1 << CS21 | 0 << CS20 ; Phasenkorrekte PWM und Prescaler setzen
out TCCR2, temp
ldi temp, 0x00 ; Irgendein Startwert fuer OCR2 (Unsere Helligkeit)
out OCR2, temp
rjmp ende
ende:
inc prog
pop temp ; LESEN von SREG vom STACK (KOPIE)
out SREG, temp ; Wiederherstellen von SREG
pop temp ; Wiederherstellen von "TEMP"
reti
; ============================ Programmwechsel-Timer Ende ============================
; ============================ Timer0 Overflow (Blinken) ============================
Timer0_Overflow: ;Die Blink-ISR lässt die LED am Pin 0 am PORTB (=PB0) blinken.
push temp ; Sichern von "TEMP" im Stack
in temp, SREG ; Einlesen des SREG
push temp ; Schreiben von SREG im Stack (KOPIE)
; ==== Programmreihenfolge ====
cpi prog, 2
breq blinken
cpi prog, 3
breq absteigend
cpi prog, 4
breq aufsteigend
cpi prog, 5
breq fading
rjmp end
blinken:
sbic PORTB, 0 ;Nächsten Befehl überspringen, falls Bit0 abm PortB ist AUS (= LED ist EIN)
rjmp led_ein ;Ansonsten LED einschalten (s. unten).
sbis PORTB,0 ;Überspringen, falls Bit0 abm PortB ist EIN (= LED ist AUS)
rjmp led_aus ;Ansonsten LED ausschalten (s. unten).
led_ein: ;Zum Einschalten:
ldi temp, 0x00
out PORTB, temp
out PORTD, temp
rjmp end ;und beenden.
led_aus: ;Zum Ausschalten:
ldi temp, 0xFF
out PORTB, temp
out PORTD, temp
rjmp end
absteigend:
in temp, PORTB ; Aktuellen Zustand holen
LSL temp ; Linksshift
out PORTB, temp ; Ausgeben
out PORTD, temp
cpi temp, 0
breq absteigend2
rjmp end
absteigend2:
LDI temp, 0xFF
out PORTB, temp
out PORTD, temp
rjmp end
aufsteigend:
in temp, PORTB ; Aktuellen Zustand holen
COM temp
LSL temp ; 0 rein
COM temp ; Aus reingekommener 0 eine 1 machen
out PORTB, temp ; Ausgeben
out PORTD, temp
cpi temp, 0xFF
breq aufsteigend2
rjmp end
aufsteigend2:
LDI temp, 0
out PORTB, temp
out PORTD, temp
rjmp end
fading: ; ==== TODO ====
; Hier später Helligkeit variieren
end:
inc runs
rjmp exit
exit:
pop temp ; LESEN von SREG vom STACK (KOPIE)
out SREG, temp ; Wiederherstellen von SREG
pop temp ; Wiederherstellen von "TEMP"
reti ; ISR beenden.
; ============================ Timer0 Overflow (Blinken) Ende ============================
Timer2_CompareHandler:
; Hier später LEDs an PORTB und D togglen
reti
(Am interessantesten sollte wohl die Prog4-Headline oder Prog4-Marke oder Prog4-Label oder wie das heißt sein)
Lesezeichen