summaryrefslogtreecommitdiff
path: root/Bewegungsmelder.asm
blob: a87f8d0263d6ea81b21e16af60e28638f4a932cf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
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