; IR Receiver module ; ; ; Hardware configuration: IR receiver emits a low pulse ; when a 38kHz burst arrives from the transmitter. ; Transmitter sends every 10 mS ; Wait for 3 missed pulses before sounding alarm. 30 mS ; The output of the IR receiver connects to INT0 (PD2) ; We will set timer0 for a 30 mS period then put the MCU ; into IDLE mode to save power. ; When a pulse arrives from the IR receiver an interrupt ; is generated. The INT0 ISR will reset the timer and put ; the MCU back in IDLE mode. ; If timer0 expires, its ISR will sound a PIEZO alarm. ; Piezo is on PB4. Could use a transistor there to drive it louder. ; ; The Watchdog Timer serves a dual purpose. It will reset the CPU if an error ; occurs and neither the Timer ISR or INT0 ISR get executed. It also serves to ; time the beep at 1 second because the WDT is not reset in the beep loop. ; ; This code should work in the 90S1200 or 90S2323/43. It would be ; possible to use a lower clock frequency too. I used the 2313 and 3.6864 MHz Xtal ; because that is what I had. ; ; This code is provided as-is without warranty and is placed in the public domain ; so that it might demonstrate some of the coding requirements of the AVR controller. ; Brian Hammill - hammill@ipass.net December 1998. ; http://www.ipass.net/~hammill .include "2313def.inc" reset: rjmp startup rjmp intr0 ; ext int 0 IR Receiver reti ; ext int 1 (not used) reti ; timer1 not used reti ; reti ; rjmp timer0 reti ; UART RRF Not Used reti ; UART TRE Not Used reti ; UART TRDE Not Used reti ; analog comparator not used startup: ; setup timer0 for 30 mS period. ck/1024 ldi R16, $05 out TCCR0, R16 ldi R16, ( 256 - 120 ) ; Test long timer ;(256 - 108) out TCNT0, R16 ; 3.6864/1024)/36 = 33 Hz ; must init the stack. ; initialize stack pointer ldi R16, RAMEND out SPL,R16 ; initialize the data direction registers ;ldi R16, 144 ;out DDRB, R16 sbi DDRB, 0 ;piezo sbi DDRB, 4 ; output signal general purpose sbi DDRB, 7 ; debugging output cbi DDRD, 2 ; input from receiver sbi PORTB, 4 ; output set high. Go low on alarm. sbi PORTB, 7 ; enable timer interrupts ldi R16,$02 ; enable timer 0 interrupts out TIMSK,R16 ; Enable IDLE mode and low level triggered ; INT0 ldi R16, 0; 2 =low edge 0 = low level out MCUCR, R16 ; Enable INT0 in GIMSK ldi R16, 64 out GIMSK, R16 ; set up the watchdog timer for 2048 ms. Use this ; to terminate the beep alarm. ldi R16, 14 ;15 = 2048 mS, 14 = 1024, 13 = 512 mS out WDTCR, R16 ; globally enable interrupts sei sleep ; put the MCU to sleep until an INT0 ; timers still run in idle mode mainloop: ; loop and wait for an interrupt nop nop nop nop rjmp mainloop timer0: ; Timer0 ISR. Runs when time expires. ; sounds the PIEZO ; disable timer 0 interrupt in R0, SREG ldi R16, 0 out TIMSK, R16 ldi R16, $FF wdr ; reset the watchdog. rjmp beep out SREG, R0 reti ; return - but we shouldn't get here intr0: ; External INT0 ISR. Runs when the IR receiver ; sends a low going pulse. ; reset the timer0 count so it does not expire in R0, SREG cbi PORTB, 7 ; debug output pulse low. ldi R16, (256 - 108) ; test long timer ( 256 - 108 ) out TCNT0, R16 wdr ; reset the Watchdog timer out SREG, R0 reti BEEP: ; set up port B, 0 as an output. We have piezo buzzer connected to PB0. ;SBI DDRB, 0 CBI PORTB, 4 ; alarm low going signal LDI R19, 230 ; Beep tone constant. ;This loop takes 3 cycles to execute so the beep tone freq is ; f = XTAL/(3*R19) ; f = 3686400/(3*64) = 19200 Hz BEEP_LOOP1: dec R19 brne BEEP_LOOP1 ; toggle the bit after count goes to 0 SBIS PORTB, 0 ; Skip if bit is set rjmp set_bit0 CBI PORTB, 0 ; Clear if set rjmp BEEP set_bit0: SBI PORTB, 0 rjmp BEEP