summaryrefslogtreecommitdiff
path: root/Bewegungsmelder.asm
diff options
context:
space:
mode:
Diffstat (limited to 'Bewegungsmelder.asm')
-rw-r--r--Bewegungsmelder.asm153
1 files changed, 153 insertions, 0 deletions
diff --git a/Bewegungsmelder.asm b/Bewegungsmelder.asm
new file mode 100644
index 0000000..a87f8d0
--- /dev/null
+++ b/Bewegungsmelder.asm
@@ -0,0 +1,153 @@
+/*
+ * Bewegungsmelder.asm
+ *
+ * Created: 12.01.2015 13:13:40
+ * Author: Erich
+ */
+
+.INCLUDE "tn24def.inc"
+
+; auf internen 128kHz-Oszillator stellen!
+
+.DEF statusBits = r25 ; 0: hell, 1: akku voll, 2: akku nicht leer
+.EQU hellBit = 0
+.EQU akkuVollBit = 1
+.EQU akkuNLeerBit = 2
+.EQU hellSpannung = 0x80 ; Schwellwert, ab dem es hell ist
+.EQU akkuVollSpannung = 0xb9 ; Schwellwert, ab dem der Akku voll ist (= 14,4V)
+.EQU akkuLeerSpannung = 0x99 ; Schwellwert, ab dem der Akku leer ist (= 12,0V)
+.EQU zaehlerschritte = 0xffff - 0x2d00 ; 90s?
+
+ rjmp RESET
+ reti
+ reti
+ reti
+ reti
+ reti
+ reti
+ reti
+ rjmp TIMER1_OVERFLOW ; Timer1 ist übergelaufen
+ reti
+ reti
+ reti
+ reti
+ rjmp ADC_INTERRUPT ; ADC-Conversion Interrupt
+ reti
+ reti
+ reti
+
+ RESET:
+ ldi r16,low(RAMEND) ; Stackpointer initialisieren
+ out SPL,r16
+
+ sbi DIDR0,ADC0D ; digitalen Eingang an ADC0 (Phototransistor) deaktivieren
+ sbi DIDR0,ADC1D ; digitalen Eingang an ADC1 (Akkuspannung) deaktivieren
+ ldi r16,0x00
+ out ADMUX,r16 ; VCC als Spannungsreferenz und ADC0 zur Single-Ended-Messung wählen
+ ldi r16,0x10
+ out ADCSRB,r16 ; linksbündige Ergebnisse, (free-running Mode wählen - wenn Auto-Trigger "an" wäre)
+ ldi r16,0xc8
+ out ADCSRA,r16 ; ADC an, Wandlung starten, Auto-Tigger aus, (Interrupt-Flag), ADC-Interrupt an, Vorteiler = 2 (=> 64kHz)
+
+ ldi r16,0x06
+ out PRR,r16 ; Clocks: Timer/Counter 1 an, Timer/Counter 0 aus, USI aus, ADC an ... zum Stromsparen
+ ldi r16,0x00
+ out WDTCSR,r16 ; Watchdog aus
+
+ ldi r16,0x05
+ out TCCR1B,r16 ; Timer/Counter 1: Vorteiler auf 1024
+ ldi r16,0x01
+ out TIMSK1,r16 ; Timer/Counter 1: Overflow-Interrupt an
+
+ ldi r16,0x04
+ out PORTA,r16 ; LED2 aus, (3x n.d.), LED1 aus, Akku ein, kein Pull-up an PORTA1 (Akkuspannung) & PORTA0 (Phototransistor)
+ ldi r16,0x04
+ out PORTB,r16 ; Pull-up an PORTB2 (Bewegungsmelder-Signal), Licht aus, Laden aus
+ ldi r16,0x8c
+ out DDRA,r16 ; Ausgänge: PORTA7 (LED2), PORTA3 (LED1), PORTA2 (Akkuschalter)
+ ldi r16,0x03
+ out DDRB,r16 ; Ausgänge: PORTB1 (Licht), PORTB0 (Ladeschalter)
+
+ sei ; Interrupts an
+
+MAINLOOP:
+ sbrs statusBits,akkuNLeerBit ; Akku leer?
+ cbi PORTA,2 ; JA! -> Akku abklemmen
+ sbrc statusBits,akkuNLeerBit ; Akku leer?
+ sbi PORTA,2 ; nein -> Akku an
+
+ sbrs statusBits,akkuNLeerBit
+ sbi PORTA,3
+ sbrc statusBits,akkuNLeerBit
+ cbi PORTA,3
+
+ sbrs statusBits,akkuVollBit ; Akku voll?
+ rjmp AKKU_NICHT_VOLL ; nein!
+
+ sbi PORTA,7 ; LED2 an
+ sbi PORTB,0 ; Akkuladeschaltung deaktivieren
+
+ rjmp BEWEGUNG_AUSWERTEN
+AKKU_NICHT_VOLL:
+ cbi PORTA,7 ; LED2 aus
+ cbi PORTB,0 ; Akkuladeschaltung aktivieren
+
+BEWEGUNG_AUSWERTEN:
+ sbic PINB,2 ; Signal am Bewegungsmelder?
+ rjmp MAINLOOP ; nein!
+
+ sbrc statusBits,hellBit ; ist es hell?
+ rjmp MAINLOOP ; ja!
+
+ ldi r16,high(zaehlerschritte)
+ ldi r17,low(zaehlerschritte)
+ out TCNT1H,r16
+ out TCNT1L,r17 ; Timer/Counter 1 resetten
+ sbi PORTB,1 ; Licht an!
+; sbi PORTA,3 ; LED1 an
+
+ rjmp MAINLOOP
+
+ADC_INTERRUPT:
+ push r16 ; r16 und SREG pushen
+ in r16,SREG
+ push r16
+
+ in r16,ADCH ; Spannungswert holen
+
+ sbis ADMUX,MUX0
+ rjmp ADC_PHOTO
+ADC_AKKU: ; Akkuspannung wurde gemessen
+ cbi ADMUX,MUX0 ; als nächstes Phototransistor messen
+
+ cbr statusBits,((1<<akkuNLeerBit) | (1<<akkuVollBit))
+
+ cpi r16,akkuLeerSpannung
+ brcs ADC_ENDE ; r16 <= akkuLeerSpannung?
+ sbr statusBits,(1<<akkuNLeerBit); nein!
+
+ cpi r16,akkuVollSpannung
+ brcs ADC_ENDE ; r16 <= akkuVollSpannung?
+ sbr statusBits,(1<<akkuVollBit) ; nein!
+
+ rjmp ADC_ENDE
+
+ADC_PHOTO: ; Phototransistorspannung wurde gemessen
+ sbi ADMUX,MUX0 ; als nächstes Akkuspannung messen
+
+ sbr statusBits,(1<<hellBit)
+ cpi r16,hellSpannung
+ brcs ADC_ENDE ; r16 <= hellSpannung?
+ cbr statusBits,(1<<hellBit) ; nein!
+
+ADC_ENDE:
+ pop r16 ; SREG und r16 popen
+ out SREG,r16
+ pop r16
+ sbi ADCSRA,ADSC ; nächste Wandlung starten
+ reti ; ADC_INTERRUPT
+
+TIMER1_OVERFLOW:
+ cbi PORTB,1 ; Licht aus!
+; cbi PORTA,3 ; LED1 aus
+ reti ; TIMER1_OVERFLOW