Code:
;Dieses Programm produziert ein Lauflicht. Jede halbe Sekunde geht die
;nächste LED an.
;Das Programm läuft in einer Endlosschleife durch.
.include "m8def.inc"
.equ time1 = 65536-1 ;Damit wird der Timer1 vorgeladen, für die halbe Sekunde
.def tmp = r16 ;Mein Universallregister
.def statusAmpel = r17 ;Hier wird gespeichert, welche Lampen grad leuchten
.def zeitwert = r18 ;Hier wird der Wert gespeichert, mit dem der Timer1 vorgeladen wird
.def lpm_reg = r0 ;Mein lpm-Register
.org 0x000
rjmp reset ;Interruptvektor "reset:"
.org OVF0addr
rjmp zeitum ;Interruptvektor für Timer0 Überlauf, hier springt
;das Programm hin, wenn der Timer überläuft
reset:
;Stack einrichten
ldi tmp, HIGH(RAMEND) ;HIGH-Byte der obersten RAM-Adresse
out SPH, tmp
ldi tmp, LOW(RAMEND) ;LOW-Byte der obersten RAM-Adresse
out SPL, tmp
ldi tmp, 0b11111111
out DDRB, tmp ;PortB als Ausgang
ldi statusAmpel, 0b00000010
out PORTB, statusAmpel ;Am Anfang LEDrot an
;Timer Register für halbe Sekunde werden belegt, hier Timer1
ldi tmp, (1<<CS12) | (1<<CS10) ;Prescaler ist 1024
out TCCR1B, tmp
ldi tmp, HIGH(time1) ;Für den Timer1 (16Bit) benötigen
out TCNT1H, tmp ;wir 2 Register, in denen wir den Wert
ldi tmp, LOW(time1) ;für die 1/2 speichern ->
out TCNT1L, tmp ;"TCNT1H" und TCNT2L"
ldi tmp, (1<<TOIE1) ;Hier werden Interrupts nach Timer1 Überlauf eingeschaltet
out TIMSK, tmp ;Register TIMSK ist dafür zuständig
;Z-Register mit DB "timerwerte" füllen
ldi ZH, HIGH(timerwerte * 2)
ldi ZL, LOW(timerwerte * 2)
sei ;Interrupts zulassen
main:
rjmp main ;Immer wieder die main durchlaufen
zeitum:
push tmp ;tmp auf Stack sichern
in tmp, SREG
push tmp ;SREG auf Stack sichern
cpi statusAmpel, 0b00000010 ;Ist rot an?
breq rotgelban ;JA -> gelb dazuschalten
cpi statusAmpel, 0b00000110 ;Ist rot UND gelb an?
breq gruenan ;JA -> grün anmachen
cpi statusAmpel, 0b00001000 ;Ist grün an?
breq gelban ;JA -> gelb anmachen
;Wenn alle drei Rechnungen != 0 ergeben, dann ist gelb an
rotan:
sbiw ZL, 1 ;nimm den vorherigen Wert aus der db (lange Zeit)
ldi statusAmpel, 0b00000010 ;rot an
rjmp ende
rotgelban:
adiw ZL, 1 ;nimm den nächsten Wert aus der db (kurze Zeit)
ldi statusAmpel, 0b00000110 ;rot und gelb an
rjmp ende
gruenan:
sbiw ZL, 1 ;nimm den vorherigen Wert aus der db (lange Zeit)
ldi statusAmpel, 0b00001000 ;grün an
rjmp ende
gelban:
adiw ZL, 1 ;nimm den nächsten Wert aus der db (kurze Zeit)
ldi statusAmpel, 0b00000100 ;gelb an
ende:
lpm ;Wert aus der db in r0 schreiben
mov zeitwert, lpm_reg ;den aktuellen Zeitwert aus r0 lesen
;TIMER1 wird neu geladen
ldi tmp, HIGH(time1) ;Für den Timer1 (16Bit) benötigen
out TCNT1H, tmp ;wir 2 Register, in denen wir den Wert
ldi tmp, LOW(time1) ;für die 1 Sekunde speichern ->
out TCNT1L, tmp ;"TCNT1H" und TCNT2L"
out PORTB, statusAmpel ;Ampel richtig umschalten
pop tmp ;SREG vom Stack holen
out SREG, tmp
pop tmp ;tmp vom Stack holen
reti ;spring dahin zurück, wo du hergekommen bist
timerwerte:
.db 65536-7200, 65536-1800
Diese beide Zeilen:
Lesezeichen