Code:
.equ zeit = 1700 ;für die MS10 routine, 10ms warteschleife
.equ schleife_durch = 10 ;10 ;für entprellroutine durchläufe
.equ schleife_sleep = 4 ;4 ;schleifendurchläufe für timer. 1 durchlauf = 67 sekunden.
.equ slep_tcnt_vorladen = 1 ;zum vorladen des register tcnt des timers 1, um feiner abstufungen zu erreichen. Normal=0
.equ adc_wert = 130 ;100 ;vergleichswert für adc und lichtsensor
.equ Zeit_hochfahren = 33 ;33 ;Wert zur einstellung der Zeit, die für das hochfahren der klappe verantwortlich ist.
.equ Zeit_runterfahren = 24 ;24 ;wert zur einstellung der Zeit für das Herunterfahren
;4 => 1 sec. (1zyklus = 261,1 ms)
; = 4.22V am LDR = 21.14Uhr am 24.07.09
; 4.66V am LDR = 21.23Uhr
; differenz rund 0.44 V
;***definitionsdatei***
.include "m8def.inc"
;***interrupt adressen***
.org 0x000 rjmp reset ;Programm start
;.org 0x001 rjmp stop ;Näherungsschalter
;.org 0x002 rjmp aus ;Interrupt schalter
.org 0x008 rjmp timer ;Timer für sicherheit, wird aktiviert nach dem schalten der ausgänge
.org 0x009 rjmp timer0 ;Timer0 für das hoch/runterfahren der tür
; Stack initialisieren
reset:
ldi r16, LOW(RAMEND)
out SPL, r16
ldi r16, HIGH(RAMEND)
out SPH, r16
;Ein/Ausgänge konfigurieren
ser r16 ;ausgang
out DDRB, r16
clr r16 ;Eingang
out DDRC, r16
out DDRD, r16
;sleep mode aktivieren
ldi r16, 0b10000000; 0b10001111
out MCUCR, r16
;ldi r16, 0b00000001
;out GICR, r16
;variable für ersten durchlauf ins register kopieren
ldi r16, 1
mov r2, r16
sei ;interrupts frei
Haupt:
;ADC konfig, ADC0
ldi r16, 0b01100000
out admux, r16
ldi r16, 0b11000011
out adcsra, r16
adcrun:
in r10, adcsra
sbrc r10, 6
rjmp adcrun
;adc werte in reg. schreiben
in r17, ADCL
in r18, ADCH
;ACHTUNG, unteren WERT ebenfalls ändern
cpi r18, adc_wert ;hier einstellwert für sreg
in r16, SREG ;SREG speichern
andi r16, 0b00000001
mov r1, r16
eor r1, r0
mov r0, r16
sbrc r2, 0
rjmp erstedurchgang
breq slep
;ACHTUNG, oberen Wert ebenfalls ändern
cpi r18, adc_wert ;hier einstellwert
brlo ab1 ;hier tor zu
brsh auf1 ;hier tor auf
rjmp slep
;unterprogramme
slep: ;schlafen legen, und alle 10 min wieder wecken
ldi r16, 0b00000101 ;teiler
out TCCR1B, r16
ldi r16, 0b00000100
out TIMSK, r16
ldi r30, schleife_sleep ;schleifendurchläufe für wartezeit
clr r31
slep1:
;wdr ;watchdog reset
ldi r16, low(slep_tcnt_vorladen) ;63535 ins register laden = 2 sekunden
ldi r17, high(slep_tcnt_vorladen)
out TCNT1H, r17
out TCNT1L, r16
sleep
nop
tst r30
brne slep1
rjmp haupt
erstedurchgang:
clr r2
rjmp haupt
auf1:
ldi r16, 0b00000101
out PORTB, r16
rcall zeitaktiv_auf ;Timer1 für Sicherheitszeit aktivieren
;warten bis schalter betätigt
warten1:
sbrc r31, 0 ;wenn timer1 interrupt fahrt beendet
rjmp slep ;dann springt wieder nach slep zurück
in r16, PIND
sbrc r16, 3
rjmp entprellen
rjmp warten1
ab1:
ldi r16, 0b00000110
out PORTB, r16
rcall zeitaktiv_ab ;Timer1 für Sicherheitszeit aktivieren
;warten bis schalter betätigt
warten2:
sbrc r31, 0 ;wenn timer1 interrupt fahrt beendet
rjmp slep ;dann springt wieder nach slep zurück
in r16, PIND
sbrc r16, 2
rjmp entprellen
rjmp warten2
;entprell routine
entprellen:
push r16
ldi r17, schleife_durch ;schleifendurchläufe
in r16, PIND
mov r3, r16
aus1:
in r16, PIND
mov r2, r16
eor r2, r3
mov r3, r16
push r16
rcall ms10
pop r16
dec r17
tst r17
brne aus1
sbrc r16, 3
rjmp aus2
sbrc r16, 2
rjmp aus2
rcall ms10
clr r17
pop r16
rjmp slep
aus2:
clr r16
clr r17
clr r19
out PORTB, r16
out TCCR0, r16 ;timer deaktivieren
out TCNT0, r16 ;timer0 zählregister nullen
pop r16
rjmp slep
;timer0 fürs bewegen der Tür aktivieren
zeitaktiv_auf:
;r29 zum herunterzählen beladen.
ldi r29, zeit_hochfahren
ldi r16, 0b00000101 ;teiler
out TCCR0, r16
ldi r16, 0b00000001 ;interrupt starten
out TIMSK, r16
ret
zeitaktiv_ab:
;r29 zum herunterzählen beladen.
ldi r29, zeit_runterfahren
ldi r16, 0b00000101 ;teiler
out TCCR0, r16
ldi r16, 0b00000001 ;interrupt starten
out TIMSK, r16
ret
;***********Warteschleife*********
ms10: ;taster entprellen
;wdr
push r17
push r18
ldi r16, low(zeit)
ldi r17, byte2(zeit)
ldi r18, byte3(zeit)
ms101:
subi r16, low(1) ;1 Takt
sbci r17, byte2(1) ;1 Takt
sbci r18, byte3(1) ;1 Takt
sbrs r18, 0 ;1 takt
breq ms102 ;
rjmp ms101 ;2 takte
ms102:
pop r18
pop r17
ret
;*************************interrupt handler***************************
;sleep-timer, 16 bit
timer:
dec r30
reti
;nach abgelaufener zeit motor aus, timer0, 8bit
timer0:
dec r29
tst r29
breq timer0_stop
reti
timer0_stop:
push r16
clr r16
out PORTB, r16
out TCCR0, r16
out TCNT0, r16
sbr r31,1
pop r16
reti
Lesezeichen