Full Version : Seto & Yu Home Security System (ASM)
avr >>HOME & TIME & TEMPERATURE PROJECTS >>Seto & Yu Home Security System (ASM)


Admin5- 04-22-2006
Home Security System

Zachary Seto & Jackson Yu

I. Introduction:

For our final project, we designed a home security system with three detection zones. We used magnetic sensors to detect for zone faults. The magnetic switches would trigger the alarm system when opened. A 4-digit security code armed and disarmed the system. The alarm system includes the following features:

Programmable 4-digit security code: (default code = "1234")
verify old security code
enter new security code
verify new security code
Zone 1 feature: 15 second delay in sounding alarm (for the front door—allows for the homeowner to enter the front door and disarm the system before the system goes off)
Sounding of alarm upon violation of a zone
Display to LCD which zones violated
Steady green LED = "Ready…" state
Steady red LED = "Armed!!!" state
Flashing green LED = warning—some zones currently in fault
II. Design and Testing Methods:

High level design

In the initial state, the system will be in a ready status. Any zone faults occurring in this state are displayed on the LCD, and a flashing green LED is use to signify a warning. This operating state accounts for when the homeowner is at home with windows or doors opened. The system cannot be armed unless all the zones are clear of violations.

Pressing the programming key "A" while in the ready state brings us into the programming stage. The old security code is requested to verify the user. If confirmed, the system prompts for a new security code. Then it prompts for the new code again for confirmation. If any verification fails, the system returns to the ready state with no changes to the alarm code.

When no zones are in fault, the system can be armed by entering the security code. If a zone fault occurs in this state, then the zone(s) in violation are displayed on the LCD panel, and an alarm is sounded. Entering the security code again will disarm the system. Also, Zone 1 has a 15 second delay in sounding the alarm to allow for the owner to enter the front door and disarm the alarm.



Program/hardware design

For the design of our home security system, we used the following hardware:

AT90S4414 MCU
LCD Screen—wired to Port D and powered by Pin B7 (Connected as in previous labs)
4 x 4 KeyPad—wired to Port C (Connected as in previous labs)
Magnetic switches—connected to Port A for Zones (See Appendix II for schematic)
Magnets (for coupling the magnetic switches)
Green LED—wired to Pin B0 and ground (Port B)
Red LED—wired to Pin B1 and common ground with Green LED
Audio Jack and earphone—connected between Pin B6 and B8 (Connected similarly to previous labs)
Protype board
We spent a significant part of our time in trying to figure out how to implement both a NAPCO MA900 Security Panel and a RP1009 KeyPad (w/ status LEDs, 7 segment display, and keypad). The manufacturer only provided minimal documentation on the installation of the panel and no technical documentation on the actual keypad-panel interface. We tried to determine the specifics on how data was transferred to/from the KeyPanel by measuring signals outputted and by sending data signals to it. Another issue we ran into was implementing a level shift from the 5 Volt output on the Port pins to 12 Volts on the KeyPanel. A simple BJT circuit could be used to solve this issue. We would have needed 6 of these circuits for outputting to the Panel and 6 more circuits for receiving input from the Panel. With these roadblocks, we decided to design our own panel by reverting back to using the keypad and LCD display.

We used a polling method as in previous labs to decode which key was pressed on the keypad:


Set PC0-PC3 to output & pulled low
Set PC4-PC7 to input & pulled high
Read PC4-PC7
Set PC4-PC7 to output & pulled low
Set PC0-PC3 to input & pulled high
Read PC0-PC3

If a button was pressed on the keypad, then exactly one bit in each of the following will equal 0.

PC4-PC7
PC0-PC3

In each of the alarm states described above, we used the polling method to test for zone faults and to check for keypresses.

In designing our program, we used Timer0 for sounding the alarm tones for our alarm (alternating notes between c4 @ 262 Hz and f4 @ 349 Hz). A prescalar of 64 was used on Timer0 to generate the correct frequencies for the alarm notes.

Timer1 was used primarily for

Implementing our delay loops to debounce our keypad
Delaying the sounding of alarm upon entry in zone 1
Blinking the LED.
We used a prescalar of 256 for the debounce delay loop, which gave us 15ms of wait time, while a prescalar of 1024 gave us the .5s of wait time for controlling the blinking of LEDs and the 15s wait time for entry in zone 1.

For the alarm zones, we tried to use Pins A0,2,4 as output (5V) and to poll Pins A1,3,5 (set to input). However, we ran into the issue where we could not get our zones to trigger a fault because Pins A1,3,5 would not go low if a zone fault occurred when a magnetic switch was opened. So, we had to modify our circuit and code so that zone faults occur when Pins A1,3,5 go high. With normally closed switchs, the Pins get pulled low when the door/window is closed.

III . Analysis:

Results of Design

We were successful in implementing our home alarm system. We ran into a minor issue of requiring the zone faults to occur simultaneously in order be recognized. It is a minor issue because a zone violation has occurred whether it is one or more zones. This occurs only when the system is armed. In the ready state, zone status is current for all times. We were only able to implement three detection zones instead of eight as in our final project proposal. The limitation came from the number of ports we had available and the number of magnetic switches we were able to obtain. We also had some problems with the alarm tones where they would mysteriously stop sounding. We tried to debug this problem, but could find no problem with the code (a straight forward implementation from Lab 3) nor any other problems. This isn't too big an issue because, in all practicality, the Port would be connected to an external siren horn which would have a siren oscillator built in. The Napco MA900 panel doesn't even implement this feature; it simply provides power to the speaker pins for a siren oscillator. However, we implemented the siren tones for expository purposes.

Future Improvements

A limitation in our design is that zone faults must happen simultaneously (when the system is armed) to get displayed on the LCD screen. In the future, we would like to show multiple zone faults on the LCD panel when they occur in the armed state. Some other features that we may include are:

Ability to shunt certain zones—arm only the downstairs part of a house, so that windows in the upstairs bedrooms may be open for ventilation.
Include more zones—offers more flexibility in grouping different rooms, windows, and doors detection together and more coverage.
Telephone dialing—automatic contact of local authorities upon triggering of alarm.
RS232 Interface—ability to arm and disarm the alarm remotely; monitor system by local security agency; computer interface/uplinking.
Entry Buzz—implement a buzzer during the entry delay, after zone 1 has been tripped.
LED zones—use LEDs to pinpoint zone faults similar to system used in fire alarms for large buildings.

Link: http://instruct1.cit.cornell.edu/courses/e...cts/s1999/seto/

CODE

; ************************************
; Zachary Seto & Jackson Yu
; Final Project - EE476
; Home Alarm System
; ************************************
; Port A - Zones
; Port B - LED's
; Port C - Keypad
; Port D - LCD(?)

.include "c:\users\z&j\4414def.inc"



.device AT90S4414



.def    codel   =r1;lower two digits of user code
.def    codeh   =r2;upper two digits of user code
.def    incodel =r3;input code, lower two digits
.def    incodeh =r4;input code, upper two digits
.def    lowtemp =r5;lower temp reg
.def    tempcdl =r6;lower temp code
.def    tempcdh =r7;upper temp code
.def    zones   =r8;zone fault codes
.def    temp    =r16   ;temporary register

.def    temp2   =r17   ;temporary register 2
.def    savSREG =r18   ;save the status register
.def    keyraw  =r19   ;the raw keyscan code

.def    key =r20   ;keeps track of what key was pressed
.def    charcnt =r21   ;keeps track of the number of characters written to the LCD
.def    wreg    =r22   ;temp for delay
.def    flag    =r23   ;generic flag
.def    audio   =r24   ;audio on/off flag and hi/lo tone
.def    count   =r25   ;count for timer0 overflow


.equ    azero   ='0'   ;0x30 ascii '0'
.equ    lcdrs   =PD6   ;LCD rs pin connected to PD6
.equ    lcdrw   =PD5   ;LCD r/w pin connected to PD5
.equ    lcde    =PD4   ;LCD enable pin connected to PD4
.equ    lo  =137   ;define low tone: C4
.equ    hi  =166   ;define hi tone: F4


;**************************************

.cseg



.org $0000

   rjmp    RESET  ;reset entry vector

   reti        

   reti

   reti

   reti

   reti

   rjmp    t1ovfl

   rjmp    t0int

   reti        

   reti
   reti
   reti
   reti       ;analog comparator



;define fixed strings to be tranmitted from flash- zero terminated

ready:  .db "Ready...",0x00
armed:  .db "Armed!!!",0x00
zone:   .db "Zone Fault-",0x00
oldcd:  .db "Enter Old Code",0x00
newcd1: .db "Enter New Code",0x00

newcd2: .db "Verify New Code",0x00

errorcd:.db "ERROR: Bad Code",0x00



RESET:  ldi temp, LOW(RAMEND);setup stack pointer

   out     SPL, temp

   ldi temp, HIGH(RAMEND)

   out SPH, temp



;initial conditions

   ser temp       ;set PORTB to be

   out DDRB,temp  ;all outputs
   out PORTB,temp ;turn off all LED's
   cbi PORTB,6

   ldi temp,0b00010101;setup PORTA direction
   out DDRA,temp  ;output to DDRA
   out PORTA, temp
   ser audio      ;init audio off
   clr count      ;init counter for timer0 ovfl
   
;init timers
   ldi temp,0x82  ;setup timer0/1 overflow interrupt
   out TIMSK,temp ;output to TIMSK
   ldi temp,0
   out TCCR1B,temp;turn off timer1
   out     TCCR0,temp ;turn off timer0

;init user code
   ldi temp,0x35
   mov codel,temp
   ldi temp,0x12
   mov codeh,temp

   sei


;bring up LCD
;power down the LCD
   cbi PORTB,7
   ldi temp,100   ;then Wait 1.5 second with LCD power off
   ldi temp2,0    ;Delay 15 mS
offwait:dec temp
   brne    offwait

;now power up LCD
   sbi PORTB,7
   ldi temp,100   ;Wait 1.5 second for LCD power up
   ldi temp2,0    ;Delay 15 mS
puwait: dec temp
   brne    puwait

;hopefully by now the LCD has rebooted
   rcall   lcdinit        ;Initialize LCD module

;send "Ready..." to LCD
TOP:    rcall   lcdclr
   clr charcnt
   ldi ZL, LOW(ready<<1)

   ldi ZH, HIGH(ready<<1)

   rcall   nextc
   sbi PORTB,0    ;turn on the ready LED
   cbi PORTB,1    ;turn off armed LED
   ser flag

;Check for Zone Faults
CHECK:  rcall   zfault
;if faults display trouble zones until ready
   cpi temp,0xff
   breq    NOFAULT
;output error zones until ready
rFAULT: rcall   lcdclr
   clr charcnt
   ldi ZL, LOW(zone<<1)   ;show zone to LCD
   ldi ZH, HIGH(zone<<1)
   rcall   nextc
   rcall   blink
fcont:  sbrc    zones,1        ;check for zone 1 fault
   rjmp    fcont1
   ldi temp,0x31      ;load 1 for LCD output
   rcall   lcdput
   inc charcnt
fcont1: sbrc    zones,3        ;check for zone 2 fault
   rjmp    fcont2
   cpi charcnt,12     ;check for prev. zone output
   brlo    char2
   ldi temp,0x2c      ;if so, output comma
   rcall   lcdput
   inc charcnt
char2:  ldi temp,0x32      ;load 2 for LCD output
   rcall   lcdput
   inc charcnt
fcont2: sbrc    zones,5        ;check for zone 3 fault
   rjmp    fcont3
   cpi charcnt,12     ;check for prev. zone output
   brlo    char3
   ldi temp,0x2c      ;if so, output comma
   rcall   lcdput
   inc charcnt
char3:  ldi temp,0x33      ;load 3 for LCD output
   rcall   lcdput
   inc charcnt
fcont3: brtc    fcont4         ;check T flag, branch if clear
   clt
   sbrs    flag,7         ;if flag is clear, turn on led
   sbi PORTB,0
   sbrc    flag,7         ;if flag is set, turn off LED
   cbi PORTB,0
   com flag           ;switch flag value
   rcall   blink          ;setup blink delay again
fcont4: mov temp2,zones
   rcall   zfault
   cpi temp,0xff      ;exit if no faults
   breq    TOP
   cp  temp,temp2
   breq    fcont3         ;keep checking if no change
   rjmp    rFAULT         ;rewrite if change

NOFAULT:rcall   debnce
;Check for programming code
   cpi key,4      ;'A' button
   breq    PROG0
;Check for user code (only if no faults)
   rcall   code
   tst temp
   brne    ARM    ;ARM system
   rjmp    CHECK
;if user code, arm system; else back to code scan

ARM:    rcall   lcdclr
   clr charcnt
   sbi PORTB,1
   cbi PORTB,0
   clr flag
   ldi ZL, LOW(armed<<1)  ;send "Armed" to LCD
   ldi ZH, HIGH(armed<<1)
   rcall   nextc

;check for zone faults
ARMPOLL:rcall   zfault
   cpi temp,0xff
   brne    FAULT
;if no faults, check for alarm code
   rcall   debnce         ;check for button push
   tst key
   breq    ARMPOLL
   rcall   code           ;if button push, check for code
   tst temp
   breq    ARMPOLL
;if code, disarm system
   rjmp    TOP

PROG0:  rjmp    PROG
;if fault, alarm, show problem zone(s)
;Zone 1 gives 15 sec. delay, others alarm instantly

;check for user code
;if code, goto ready
;else goto zone

FAULT:  sbrc    zones,1        ;check for zone 1 fault
   rjmp    f1
   clt
   rcall   entry          ;start 15 sec. entry delay
f0: rcall   debnce         ;check for first button push
   tst key
   breq    f0a
   rcall   code           ;check for correct code input
   sbrc    temp,7
   rjmp    TOP        ;if so, change alarm state to ready
f0a:    brtc    f0         ;if not, check for T flag (timeout)
f1: rcall   alrmon
   rcall   lcdclr
   clr charcnt
   ldi ZL, LOW(zone<<1)   ;show zone to LCD
   ldi ZH, HIGH(zone<<1)
   rcall   nextc
   sbrc    zones,1        ;check for zone 1 fault
   rjmp    f2
   ldi temp,0x31      ;load 1 for LCD output
   rcall   lcdput
   inc charcnt
f2: sbrc    zones,3        ;check for zone 2 fault
   rjmp    f3
   cpi charcnt,12     ;check for prev. zone output
   brlo    fchar2
   ldi temp,0x2c      ;if so, output comma
   rcall   lcdput
   inc charcnt
fchar2: ldi temp,0x32      ;load 2 for LCD output
   rcall   lcdput
   inc charcnt
f3: sbrc    zones,4        ;check for zone 3 fault
   rjmp    f4
   cpi charcnt,12     ;check for prev. zone output
   brlo    fchar3
   ldi temp,0x2c      ;if so, output comma
   rcall   lcdput
   inc charcnt
fchar3: ldi temp,0x33      ;load 3 for LCD output
   rcall   lcdput
   inc charcnt
f4: rcall   debnce
   tst key
   breq    f4
   rcall   code
   tst temp
   breq    f4
   rcall   alrmoff
   rjmp    TOP

PROG:  ;*********** PROGRAM USER CODE *************
  ; enter old user code
  ; if not user code, goto ready
  ; if user code...
  ; enter new user code
  ; verify new user code
  ; goto ready


   rcall   lcdclr
   clr charcnt
   ldi ZL, LOW(oldcd<<1)  ;prompt for old code
   ldi ZH, HIGH(oldcd<<1)
   rcall   nextc
prog1:  rcall   debnce
   tst key
   breq    prog1
   rcall   code
   tst temp
   breq    ERROR
   rcall   lcdclr
   clr charcnt
   ldi ZL, LOW(newcd1<<1) ;prompt for new code
   ldi ZH, HIGH(newcd1<<1)
   rcall   nextc
prog2:  rcall   debnce
   tst key
   breq    prog2
   rcall   code
   mov tempcdl,incodel    ;copy new code
   mov tempcdh,incodeh
   rcall   lcdclr
   clr charcnt
   ldi ZL, LOW(newcd2<<1) ;prompt for new code again
   ldi ZH, HIGH(newcd2<<1)
   rcall   nextc
prog3:  rcall   debnce
   tst key
   breq    prog3
   rcall   code
   cp  incodel,tempcdl    ;make sure code was verified
   brne    ERROR
   cp  incodeh,tempcdh
   brne    ERROR
   mov codel,incodel      ;store new code
   mov codeh,incodeh
   rjmp    TOP
ERROR:  rcall   lcdclr
   clr charcnt
   ldi ZL, LOW(errorcd<<1);prompt for new code
   ldi ZH, HIGH(errorcd<<1)
   rcall   nextc
   ldi temp,100       ;Delay 1.5 Sec
erwait: rcall   delay
   dec temp
   brne    erwait
   rjmp    TOP


;*****************************

;LCD Stuff

;Clear entire LCD
lcdclr: ldi     temp,1         ;Clear LCD command
       rcall   lcdcmd
       ret

================================================
;       Initialize LCD module
lcdinit:ldi     temp,0         ;Setup port pins
       out     PORTD,temp     ;Pull all pins low
       ldi     temp,0xff      ;All pins are outputs
       out     DDRD,temp
       rcall   delay

;       LCD specs call for 3 repetitions as follows
       ldi     temp,3         ;Function set
       out     PORTD,temp     ;to 8-bit mode
       nop                    ;nop is data setup time
       sbi     PORTD,lcde     ;Toggle enable line
       cbi     PORTD,lcde

       rcall   delay

       ldi     temp,3         ;Function set
       out     PORTD,temp
       nop
       sbi     PORTD,lcde     ;Toggle enable line
       cbi     PORTD,lcde

       rcall   delay

       ldi     temp,3         ;Function set
       out     PORTD,temp
       nop
       sbi     PORTD,lcde     ;Toggle enable line
       cbi     PORTD,lcde

       rcall   delay

       ldi     temp,2         ;Function set, 4 line interface
       out     PORTD,temp
       nop
;       rcall   strobe         ;Toggle enable line
       sbi     PORTD,lcde     ;Toggle enable line
       cbi     PORTD,lcde

       ldi     temp,0b11110000;Make 4 data lines inputs
       out     DDRD,temp
       
;       Finally,
;       At this point, the normal 4 wire command routine can be used

       ldi     temp,0b00100000;Function set, 4 wire, 1 line, 5x7 font
       rcall   lcdcmd

       ldi     temp,0b00001100;Display on, no cursor, no blink
       rcall   lcdcmd

       ldi     temp,0b00000110;Address increment, no scrolling
       rcall   lcdcmd
       ret

============================================
;       Wait for LCD to go unbusy
lcdwait:ldi     temp,0xF0      ;Make 4 data lines inputs
       out     DDRD,temp
       sbi     PORTD,lcdrw    ;Set r/w pin to read
       cbi     PORTD,lcdrs    ;Set register select to command
waitloop:
       sbi     PORTD,lcde     ;Toggle enable line
       cbi     PORTD,lcde
       in      wreg,PIND   ;Read busy flag
      ;Read, and ignore lower nibble
       sbi     PORTD,lcde     ;Toggle enable line
       cbi     PORTD,lcde

       sbrc    wreg,3      ;Loop until done
       rjmp    waitloop
       ret

=============================================
;       Send command in temp to LCD
lcdcmd: push    temp           ;Save character
       rcall   lcdwait        ;Wait for LCD to be ready
       ldi     temp,0xFF      ;Make all port D pins outputs
       out     DDRD,temp
       pop     temp           ;Get character back
       push    temp           ;Save another copy
       swap    temp           ;Get upper nibble
       andi    temp,0x0F      ;Strip off upper bits
       out     PORTD,temp     ;Put on port
       nop                    ;wait for data setup time
       sbi     PORTD,lcde     ;Toggle enable line
       cbi     PORTD,lcde

       pop     temp           ;Recall character
       andi    temp,0x0F      ;Strip off upper bits
       out     PORTD,temp     ;Put on port
       nop
       sbi     PORTD,lcde     ;Toggle enable line
       cbi     PORTD,lcde

       ldi     temp,0xF0      ;Make 4 data lines inputs
       out     DDRD,temp
       ret

=============================================
;Send character data in temp to LCD
lcdput: push    temp           ;Save character
   rcall   lcdwait        ;Wait for LCD to be ready
   ldi     temp,0xFF      ;Make all port D pins outputs
   out     DDRD,temp

   pop     temp           ;Get character back
   push    temp           ;Save another copy
   swap    temp           ;Get upper nibble
   andi    temp,0x0F      ;Strip off upper bits
   out     PORTD,temp     ;Put on port
   sbi     PORTD,lcdrs    ;Register select set for data
   nop
   sbi     PORTD,lcde     ;Toggle enable line
   cbi     PORTD,lcde

       pop     temp           ;Recall character
       andi    temp,0x0F      ;Strip off upper bits
       out     PORTD,temp     ;Put on port
       sbi     PORTD,lcdrs    ;Register select set for data
       nop
       sbi     PORTD,lcde     ;Toggle enable line
       cbi     PORTD,lcde
      ;cbi    PORTD,lcdrs    ;--

       ldi     temp,0xF0      ;Make 4 data lines inputs
       out     DDRD,temp
       ret

nextc:  lpm                    ;Get next character from ROM
       tst     R0             ;See if at end of message
       breq    end1           ;If so, next message
       cpi     charcnt,8      ;addressing changes at char #8!
       brne    wrtit          ;at char 8, fix it
       ldi     temp,0xC0      ;Set address to last 8 chars
       rcall   lcdcmd  
wrtit:  mov     temp,R0        ;Send it to the LCD
       rcall   lcdput
       adiw    ZL,1           ;Increment Z-pointer
       inc     charcnt        ;keep track of chars on display
       rjmp    nextc          ;Loop for more
end1:   ret

;***** Delay 15 milliseconds using timer 1
delay:  in      wreg,SREG      ;Save status register
       push    wreg
       clt                    ;Clear T
   ldi temp2,0xff ;preload timer1
   out TCNT1H,temp2   ;write high part of timer1
   ldi temp2,0x15 ;preload timer1
   out TCNT1L,temp2   ;write low part of timer1
       ldi     wreg,4     ;Timer 1 prescaler, CK / 256
   out TCCR1B,wreg
dwait:  brtc    dwait          ;Wait for timer 0 interrupt to set T
       pop     wreg           ;Restore status register
       out     SREG,wreg
       ret

;*****************************
;keypad polling routine
;keypad on PORTC

keytbl: .db 0b11101110, 0b11101101, 0b11101011, 0b11100111
   .db     0b11011110, 0b11011101, 0b11011011, 0b11010111
   .db 0b10111110, 0b10111101, 0b10111011, 0b10110111
   .db 0b01111110, 0b01111101, 0b01001011, 0b01110111

KeyPoll:ldi temp, 0x0f
   out     DDRC, temp
   ldi     temp, 0xf0
   out PORTC, temp
   nop
   nop
   nop
   nop
   in  temp, PINC
   mov keyraw,temp
   ldi temp, 0xf0
   out DDRC, temp
   ldi     temp, 0x0f
   out     PORTC, temp
   nop
   nop
   nop
   nop
   in  temp, PINC
   or  keyraw, temp
   ldi     ZL, low(keytbl*2)
   ldi     ZH, high(keytbl*2)
   ldi     key, 0
tbllp:  lpm
   cp  keyraw, r0
   breq    foundit
   inc     key
   cpi key, 0x10
   breq    illegal
   adiw    ZL, 1
   rjmp    tbllp
foundit:subi    key, -1
   ret
illegal:clr key
   ret

debnce: clr key    ;clear the key pressed variable
   rcall   KeyPoll    ;check for button push
   tst key
   breq    nokey      ;if no button, exit
   mov lowtemp,key;store first key read
   rcall   delay      ;wait 15ms
   rcall   delay      ;wait 15ms
   rcall   KeyPoll    ;wait for button still push
   cp  key,lowtemp;check to see that the same button was still pushed
   brne    nokey
   rcall   delay      ;wait 15ms
   rcall   delay      ;wait 15ms
hold:   rcall   KeyPoll
   tst key
   brne    hold
   mov key,lowtemp;restore key
   ret
nokey:  ldi key,0      ;clear key
   ret

;************************
; Check for Zone Fault

zfault: in  temp,PINA      ;get pin values
   com temp
   ori temp,0b11010101    ;set the output to 1's, zone bits 0 if fault
                  ;bit 1 = Zone 1, bit 3 = Zone 2, bit 5 = Zone 3
   mov zones,temp
   ret

code:  ;assume that the first key is preloaded in key
  ;rcall  debnce         ;setup first digit
   tst key
   breq    NOCODE
   swap    key
   mov incodeh,key
code1:  rcall   debnce         ;setup second digit
   tst key
   breq    code1
   or  incodeh,key
code2:  rcall   debnce         ;setup third digit
   tst key
   breq    code2
   swap    key
   mov incodel,key
code3:  rcall   debnce         ;setup fourth digit
   tst key
   breq    code3
   or  incodel,key
   cp  incodeh,codeh      ;compare upper two digits
   brne    NOCODE
   cp  incodel,codel      ;compare lower two digits
   brne    NOCODE
   ser temp           ;set for correct code
   ret
NOCODE: clr temp           ;clear for incorrect code
   ret

;***** Delay 15 seconds using timer 1
entry:  in      wreg,SREG      ;Save status register
   ldi temp2,0x1B ;preload timer 1 to 6941
       out     TCNT1H,temp2
   ldi temp2,0x1D ;preload timer 1 to 6941
       out     TCNT1L,temp2
       clt                    ;Clear T
       ldi     temp2,5    ;Timer 0 prescaler, CK / 1024
       out     TCCR1B,temp2   ;Run timer
       out     SREG,wreg
       ret

;***** Delay 1 sec using timer 1
blink:  in      wreg,SREG      ;Save status register
   ldi temp2,0xf8 ;preload timer 1 to 61629
       out     TCNT1H,temp2
   ldi temp2,0x5e ;preload timer 1 to 61629
       out     TCNT1L,temp2
   clt
       ldi     temp2,5    ;Timer 1 prescaler, CK / 1024
       out     TCCR1B,temp2   ;Run timer
       out     SREG,wreg
       ret

;***** Timer 0 overflow interrupt handler
t0int:  in  savSREG,SREG   ;save the status reg
   ldi wreg,0xf0  ;load xor value
   eor audio,wreg ;toggle audio output
   sbrs    audio,7    ;if flag is clear, turn on audio
   sbi PORTB,6
   sbrc    audio,7    ;if flag is set, turn off audio
   cbi PORTB,6
   sbrc    audio,3    ;check for hi flag
   ldi     wreg,hi    ;reload the timer with hi
   sbrs    audio,3    ;check for lo flag
   ldi wreg,lo    ;reload the timer with lo
   out TCNT0,wreg
   cpi count,90   ;~.25 sec
   brlo    tcont
   clr count
   ldi wreg,0x0f  ;load xor value
   eor audio,wreg ;toggle hi/lo tone
tcont:  inc count      ;increment the duration counter
   out SREG,savSREG   ;restore status reg
   reti           ;return from ISR

;***** Timer 1 overflow interrupt handler
t1ovfl: ldi wreg,0     ;turn off Timer 1
   out TCCR0,wreg
   set
   reti

;***** Start alarm tones
alrmon: ldi     temp,3     ;prescale timer by 64

   out     TCCR0,temp ;turn on timer0
   ori audio,0xf0 ;turn on audio
   ret

;***** Stop alarm tones
alrmoff:ldi     temp,0

   out     TCCR0,temp ;turn off timer0
   andi    audio,0x0f ;turn off audio
   ret




Forumer™ is Voted #1 Free Forum Hosting provider
Build your own community today with the largest message board hosting company.