Code:
;Dieses Programm zeigt eine Ampel auf drei LEDs.
;Es wird mit dem Timer1 realisiert und im Flash sind die Timerwerte gespeichert.
;Je nachdem, welcher Wert gebraucht wird, wird aus "timerwerte:" gelesen
.include "m8def.inc"
.equ time1 = 65536-7200 ;Damit wird der Timer1 vorgeladen, für die 2 Sekunden
.def tmp = r16 ;Mein Universallregister
.def statusAmpel = r17 ;Hier wird gespeichert, welche Lampen grad leuchten
.def lpm_reg = r0 ;Mein lpm-Register
.org 0x000
rjmp reset ;Interruptvektor "reset:"
.org OVF1addr
rjmp zeitum ;Interruptvektor für Timer1 Ü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:
ldi statusAmpel, 0b00000010 ;rot an
rjmp ende
rotgelban:
adiw ZL, 2
ldi statusAmpel, 0b00000110 ;rot und gelb an
rjmp ende
gruenan:
ldi statusAmpel, 0b00001000 ;grün an
rjmp ende
gelban:
adiw ZL, 2
ldi statusAmpel, 0b00000100 ;gelb an
ende:
;TIMER1 wird neu geladen
lpm ;Wert aus dw in r0 schreiben
mov tmp, r0
push tmp ;LOW-Byte speichern
adiw ZL, 1
lpm
mov tmp, r0
out TCNT1H, tmp ;HIGH-Byte in Timer1 laden
pop tmp ;LOW-Byte wiederholen
out TCNT1L, tmp ;LOW-Byte in Timer1 laden
ldi ZH, HIGH(timerwerte * 2) ;Zeiger wieder auf den ersten Wert setzen
ldi ZL, LOW(timerwerte * 2)
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:
.dw 65536-7200, 65536-1800
Wer Fragen zum Code hat, kann sie natürlich jederzeit stellen. Am besten vielleicht per PN, damit der Thread hier übersichtlicht bleibt. Dies gilt natürlich auch für die ganzen anderen Codes, die wir hier reingestellt haben.
Lesezeichen