;************************ Alarm.asm ***************************************** ; Written by: Mike Skypek ; 1787 Wiggins Circle ; Conyers, Ga 30094 ; ;This software is made available to Talking Electronics and may be used freely, without ;permission by the copyright owner, by indviduals for themselves. ; ; ; Read this documentation first - it will be difficult to figure out what the ; software does by reading the code. Once you understand the functions this sofware ; performs, the code simply "explains" how it is done. ; ; This is the software creating a two-zone, two stage alarm for the PICLICK-1 module ; using a Microchip PIC16F628-04. If you use a PIC16F628-20 or other processor with ; a different speed, you will need to change the timer values associated with each function. ; ; A two zone alarm means the alarm has two seperate 'detection' circuits and can ; identify which circuit was triggered. This alarm software uses RA1 and RA2 as 'detectors'. ; Currently this capability is used only to allow the operator to select whether the ; detector(s) on RA2 are ignored or processed. This allows the operator to turn-off the ; garage alarm for example but leave the toolbox alarm on. ; ; Two stage means that the alarm recognizes when it has been triggered more than once ; and reacts differently. "Warning/subdued" devices are tiggered the first time the ; alarm is set-off and then "Intruder/loud" devices are triggered everytime thereafter. ;---------------------------------------------------------------------------------- ; Alarm is controlled by a push-switch. The Alarm powers-up in disarmed mode (off). ; The possible modes are: Disarm, Enabled, Yellow, and Red. The three commands ; that can be entered via the push-switch are: ; ; 1. A double click while in any mode puts the alarm in Enabled mode (on). ; Going into Enabled mode resets everything. If already in Enabled mode - ; any clicks are counted toward triple clicks (see triple clicks later). ; 2. Holding the control button for 3 seconds while in any mode puts it ; back to disarm mode. If already in disarm mode - nothing happens. ; Going into disarm mode essential turns off all output/alarm devices and ; disables the movement/intruder detection functions. ; 3. Triple clicking is possible only while in Enabled mode, which causes ; the alarm to ignore the 2nd detection zone (RA2). Triple clicking ; again causes the alarm to resume processing of 2nd motion detector. ; Triple clicking in any mode other than Enable mode is interpreted ; as a double click (see above) with an additional extraneous click. ; After the alarm is enabled, the alarm can be triggered by RA1 or RA2. ; if triggered the first time - the alarm goes to Yellow Alert Mode. ; if triggered the second time - the alarm goes to Red Alert Mode. ; if triggered anytime afterward the alarm stays in Red Alert Mode. ; The Alarm Status is displayed via LEDs. They are like traffic lights, ; with Red - Yellow - Green. ; Green - Disabled (Okay to walk about freely) ; Blinking sequence1 (Red, Yellow, Green) - Enabled with both detectors ; Blinking sequence2 (Green, Yellow, Red) - Enabled only with RA1 detector ; Yellow - Alarm is on and has been triggered once. ; Red - Alarm is on and has been triggered 2 or more times ; ; The program has a main loop which checks for a high on RA0 from ; the push-switch and for changes from the two motion detectors (Low to High ; on RA1 or RA2). It then turns on appropriate flag-bits and sets ; timer values for functions that the isr (interrupt service routine) performs. ; The program uses an isr (interrupt service routine) that executes off TRM0 interrupts ; every 7.9 microseconds. The isr performs all functions that are timed, ; such as maintaining the debounce-on flag, turning off various ; alarm components after certain time intervals have elapsed, giving someone who has ; entered the room time 40 seconds disable the alarm or giving someone who has ;enabled the alarm 40 seconds to leave the room... ; ; To have the isr perform a function, the software generally sets the appropriate ; flag-bit and sets the appropriate variable with the number of 7.9 microseconds ;interrupts that the isr is to perform that function. The isr clears that flag-bit after the ;function has been performed for the specified number of times. ;---------------------------------------------------------------------- ; Alarm Input - RA0 thru RA2 ; ; RA0 - Control switch which enables or disables alarm ; RA1 - Motion Detector 1 ; RA2 - Motion Detector 2 (can be turn-off by triple clicking in 'Enabled Mode') ; ; Alarm outputs - RA3, RB0 thru RB7 ; ; RA3 - Control power-on switch for power amplifier (used by voice messages) ; RB0 - Green LED status light ; RB1 - Yellow LED status light ; RB2 - Red LED status light ; RB3 - Strobe light - used everytime alarm is triggered ; RB4 - Horn/Buzzer (Loud) - used only when entering or in red alert ; RA5 - Siren Warning (subdued to moderate) - used only when entering yellow alert ; RA6 - Verbal Warning - used only when entering yellow alert (uses amplifier) ; RB7 - Barking Dogs - used everytime alarm is triggered (uses amplifier) ;------------------------------------------------------------------------------ LIST P=PIC16F628 ;include __CONFIG _CP_OFF & _LVP_OFF & _PWRTE_OFF & _WDT_OFF & _INTRC_OSC_CLKOUT & _MCLRE_off & _BODEN_off ;Ports: PORTA equ 0x05 PORTB equ 0x06 ;All others: CMCON equ 0x1F INTCON equ 0x0B INTF equ 1 OPTION_REG equ 0x81 PCL equ 0x02 RP0 equ 5 RP1 equ 6 STATUS equ 0x03 T0IF equ 2 TMR0 equ 0x01 TRISA equ 0x85 TRISB equ 0x86 Z equ 2 ;Configuration Bits: _BODEN_ON EQU H'3FFF' _BODEN_OFF EQU H'3FBF' _CP_ALL EQU H'03FF' _CP_75 EQU H'17FF' _CP_50 EQU H'2BFF' _CP_OFF EQU H'3FFF' _PWRTE_OFF EQU H'3FFF' _PWRTE_ON EQU H'3FF7' _WDT_ON EQU H'3FFF' _WDT_OFF EQU H'3FFB' _LVP_ON EQU H'3FFF' _LVP_OFF EQU H'3F7F' _MCLRE_ON EQU H'3FFF' _MCLRE_OFF EQU H'3FDF' _ER_OSC_CLKOUT EQU H'3FFF' _ER_OSC_NOCLKOUT EQU H'3FFE' _INTRC_OSC_CLKOUT EQU H'3FFD' _INTRC_OSC_NOCLKOUT EQU H'3FFC' _EXTCLK_OSC EQU H'3FEF' _LP_OSC EQU H'3FEC' _XT_OSC EQU H'3FED' _HS_OSC EQU H'3FEE' ;----------- Misc variables Alarm_state equ 0x22 ; Contains alarm state Stat_sav equ 0x24 W_sav equ 0x25 tmr_Flg1 equ 0x27 ; Register of timer flags tmr_Flg2 equ 0x28 ; Register of more timer flags Puls_flgs equ 0X29 ; Pulse LED flags mi_Flgs equ 0x2A ; miscellaneous flags cnt_Clicks equ 0x2C tbl_i equ 0x2D ; table index ;-------------Miscellaneous flags flg_RAoff equ 0 ; Used to insure a double-click flg_Zone2 equ 1 ; Used to turn off motion detector (ZONE) 2 flg_Deboun equ 2 ; debouncing in progress ;-------------Alarm State flags (bit number) flg_Dis equ 0 ; Set State of alarm = "disable" flg_Ena equ 1 ; Set State of alarm = "enable" flg_Yellow equ 2 ; Set State of alarm = "yellow alert" flg_Red equ 3 ; Set state of alarm = "red alert" ;PORTA bits bit_In equ 0 ;switch input bit_Z1 equ 1 ;motion detector (ZONE) 1 bit_Z2 equ 2 ;motion detector (ZONE) 2 bit_Amp_On equ 3 ;power amplifier ;PORTB bits bit_Red equ 0 ; red led bit_Yel equ 1 bit_Gre equ 2 bit_Strobe equ 3 bit_Buzz equ 4 bit_Siren equ 5 bit_Verb equ 6 ; verbal warning bit_Dog equ 7 ; barking dog ;----------- Timer flags flg_Clk equ 0 ;timer-1 flags flg_Verb equ 1 flg_Strobe equ 2 flg_Buzz equ 3 flg_Dog equ 4 flg_Siren equ 5 flg_Disarm equ 6 flg_Waita equ 0 ;timer-2 flags flg_Waitb equ 1 ; " " flg_Trig equ 2 ; " " flg_Amp_On equ 4 ;----------- Timer intervals ;- tmr register variables are decremented & processed during interrupt ; processing if it's corresponding flg is set in tmr_Flg1. Must use two register ; variables to have intervals more a couple of seconds. tmr_Clk equ 0x30 ;time between control clicks tmr_Deboun equ 0x31 ;Debounce interval tmr_Blink equ 0x32 ;interval that a blinking LED in on tmr_Trig equ 0x33 ;interval that an alarm trigger must be active tmr_Siren equ 0x34 ;Siren interval tmr_Buzz1 equ 0x35 ;Buzzer interval tmr_Buzz2 equ 0x36 ;Number of intervals Buzzer is "on" tmr_Disarm1 equ 0x37 tmr_Dog1 equ 0x3A ;Barking Dogs warning interval tmr_Strobe1 equ 0x3C tmr_Strobe2 equ 0x3D tmr_Verb1 equ 0x3F ;Verbal warning interval tmr_Delay1 equ 0x42 ;shared by the isr routines that delay tmr_Delay2 equ 0x43 ;triggering and enabling alarm tmr_Amp_On1 equ 0x46 ;amplifier remain-on interval tmr_Amp_On2 equ 0x47 tmr_Rearm1 equ 0x48 tmr_Rearm2 equ 0x49 tmr_Rearm3 equ 0x4A ExitDel1 equ 0x4B ;timing for duration of entry/exit beep ExitDel2 equ 0x4C ;timing for duration of entry/exit beep ; The following constants are the number of 8 microseconds intervals or 2.1 second intervals allowed. lmt_Strobe2 equ 0x16 ;2.1 second intervals for strobe light lmt_Amp_On2 equ 0x20 ;2.1 second intervals for amp to remain on lmt_Disarm equ 0xFF ;8 microsecond interval (2.1 seconds) lmt_Blink equ 0x7E ;8 microsecond intervals for one blink of the rotating LEDs ; (7E = approximately one second) lmt_Deboun equ 0x20 ;8 microsecond intervals to debounce (1/4 seconds) lmt_Clk equ 0xA0 ;time when 2nd click becomes a double-click ;------------------------------------------------------------ ORG 0 GOTO Main ORG 4 ;interrupts always vector to here GOTO isr ;----- Code Table for siren intervals (makes siren wail at uneven intervals) ;----- If you move the call to this table from the isr routine to another memory location or ; move this table, check Microchip pub ANS556 to avoid some possible problems. tableS addwf PCL,1 retlw 0x0A0 ; 1 retlw 0x025 ; 2 retlw 0x0A0 ; 3 retlw 0x035 ; 4 retlw 0x0A0 ; 5 retlw 0x070 ; 6 retlw 0x020 ; 7 retlw 0x050 ; 8 retlw 0x0A0 ; 9 retlw 0x030 ; A retlw 0x0A0 ; B retlw 0x050 ; C retlw 0x090 ; D retlw 0x050 ; E retlw 0x0A0 ; F retlw 0x070 ;10 retlw 0x0A0 ;11 retlw 0x050 ;12 retlw 0x020 ;13 retlw 0x050 ;14 retlw 0x020 ;15 retlw 0x050 ;16 ;------Interrupt Service Routine (ISR). Servicing TMR0 interrupts only. ; This ISR allow the main program to turn on an output port, set up a ; counter that specifies how many timer interrupts (7.9 microseconds intervals) a ; function is to remain on. 126 (0x07E) intervals is about 1 second. ; This ISR is also used for other functions that need something done ; after a certain time interval such as ; - setting a 'debounce-off' flag ; - implement a delay before enabling the alarm (to allow someone to leave) ; - implement a delay before going to a Yellow or Red Alert mode. ; - maintaining a time-out interval for "double clicks" on RA0 input, .... ; isr MOVWF W_sav ; first save critical registers SWAPF STATUS,W BCF STATUS,RP0 ; always change to bank 0 MOVWF Stat_sav BTFSS Alarm_state, flg_Dis ; is alarm disabled? GOTO isr_0 ; no DECFSZ tmr_Rearm3,1 ; GOTO isr_0 DECFSZ tmr_Rearm2,1 ; GOTO isr_0 ; This code eventually enables the alarm DECFSZ tmr_Rearm1,1 ; in a few hours. I put this in because I GOTO isr_0 ; would get distracted and forget to enable CALL Enable ; the alarm after I left the garage. isr_0 BTFSS mi_Flgs, flg_Deboun ; Debouncing? GOTO isr_1 ; no DECFSZ tmr_Deboun,1 ; time up? GOTO isr_2 ; no BCF mi_Flgs, flg_Deboun ; Turn off "debounce in progress" flag isr_1 BTFSS tmr_Flg1, flg_Clk ; looking for a double click? GOTO isr_2 DECFSZ tmr_Clk,1 ; count down GOTO isr_2 BCF tmr_Flg1, flg_Clk ; yes - time is up isr_2 BTFSS tmr_Flg1, flg_Verb ; verbal warning timer on? GOTO isr_3 ; no DECFSZ tmr_Verb1,1 ; GOTO isr_3 ; BCF tmr_Flg1, flg_Verb BCF PORTB, bit_Verb ; turn off verbal warning isr_3 BTFSS tmr_Flg1, flg_Strobe ; strobe light timer on? GOTO isr_4 ; no DECFSZ tmr_Strobe1,1 GOTO isr_4 DECFSZ tmr_Strobe2,1 ; count-down reached? GOTO isr_4 BCF tmr_Flg1, flg_Strobe BCF PORTB, bit_Strobe ; turn off strobe isr_4 BTFSS tmr_Flg1, flg_Buzz ; Buzzer/Horn handling ? GOTO isr_5 ; no DECFSZ tmr_Buzz1,1 GOTO isr_5 MOVLW 0x10 ; buzzer/horn bit XORWF PORTB,1 ; reverse PORTB Buzzer State MOVLW 0x0FF ; set buzzer-on interval BTFSS PORTB, bit_Buzz ; is buzzer on? MOVLW 0x080 ; yes, set buzzer-off interval MOVWF tmr_Buzz1 ; DECFSZ tmr_Buzz2,1 ; count down times buzzer is turned on and off GOTO isr_5 ; limit not reached BCF tmr_Flg1, flg_Buzz ; BCF PORTB, bit_Buzz ; turn off buzzer isr_5 BTFSS tmr_Flg1, flg_Dog ; Barking dogs handling? (Amplifier should be on) GOTO isr_6 DECFSZ tmr_Dog1,1 GOTO isr_6 BCF tmr_Flg1, flg_Dog BCF PORTB, bit_Dog ; turn off barking dogs isr_6 BTFSS tmr_Flg1, flg_Siren ; Siren handling? GOTO isr_7 ; no DECFSZ tmr_Siren, 1 GOTO isr_7 MOVLW 0x20 ; Siren bit XORWF PORTB,1 ; Reverse PORTB Siren State MOVF tbl_i,0 ; CALL tableS ; Call Siren table MOVWF tmr_Siren ; set siren interval timer DECFSZ tbl_i,1 GOTO isr_7 BCF tmr_Flg1, flg_Siren BCF PORTB, bit_Siren ; turn off siren isr_7 BTFSS tmr_Flg1, flg_Disarm ; Disarm? GOTO isr_8 DECFSZ tmr_Disarm1,1 ; has switch been closed long enough? GOTO isr_8 BCF tmr_Flg1, flg_Disarm ; yes - we have a Disarm command CALL SetDis MOVLW 0xFF ; give user 2.1 seconds to release MOVWF tmr_Deboun ; switch after Disarm is triggered BSF mi_Flgs, flg_Deboun ; before more RA0 inputs are processed isr_8 BTFSS tmr_Flg2, flg_Waita ; Waiting to set off alarm GOTO isr_9 ; no DECFSZ tmr_Delay1,1 ; wait several seconds in case someone GOTO isr_9 ; entered to turn off alarm. DECFSZ tmr_Delay2,1 ; count-down reached? GOTO isr_9 ; no BCF tmr_Flg2, flg_Waita CALL Beep BTFSS Alarm_state, flg_Yellow GOTO isr_8a CALL SetYel ; yellow alert GOTO isr_9 isr_8a BTFSC Alarm_state, flg_Red CALL SetRed ; red alert isr_9 ; If the alarm is in "enabled" mode, then blink lights from ; from top to bottom (or bottom to top if Zone 2 is disabled) BTFSS Alarm_state, flg_Ena ; is alarm in enabled mode? GOTO isr_10 ; no DECFSZ tmr_Blink,1 ; time to blink a different color? GOTO isr_10 ; no BTFSS tmr_Flg2, flg_Waitb ; Are we waiting to enable alarm? GOTO isr_9a ; no MOVLW b'00000100' ; set green as default color BTFSC PORTB, bit_Gre ; was PortB green led already on? MOVLW b'00000000' ; no then set W = no leds IORWF PORTB, 1 ; update PORTB with new LED display GOTO isr_9z isr_9a BTFSS mi_Flgs,flg_Zone2 ; Zone 2 disabled? GOTO isr_9b ; no reverse order lights blink MOVLW b'00000100' ; set green as default color BTFSC PORTB, bit_Gre ; was PortB green led already on? MOVLW b'00000010' ; then set W = yellow led BTFSC PORTB, bit_Yel ; was PortB yellow led already on? MOVLW b'00000001' ; then set W = Red GOTO isr_9z isr_9b MOVLW b'00000100' ; Blink lights in reverse order of isr_9 BTFSC PORTB, bit_Gre ; was PortB green led already on? MOVLW b'00000001' ; then set W = Red BTFSC PORTB, bit_Red ; was PortB yellow led already on? MOVLW b'00000010' ; then set W = yellow led isr_9z BCF PORTB, bit_Gre BCF PORTB, bit_Yel BCF PORTB, bit_Red IORWF PORTB, 1 ; update PORTB with new LED display MOVLW lmt_Blink MOVWF tmr_Blink ; Reset count-down timer isr_10 ; Allow time for someone to leave before clearing flg_Waitb. ; All motion detector input is ignored until flg_Waitb is clear. BTFSS tmr_Flg2, flg_Waitb ; Flag set? GOTO isr_11 ; no DECFSZ tmr_Delay1, 1 ; wait for another interrupt? GOTO isr_11 ; yes DECFSZ tmr_Delay2, 1 ; yet some more? GOTO isr_11 ; yes BCF tmr_Flg2, flg_Waitb ; clear flag isr_11 NOP ; not used isr_12 ; Power off the amplifier after the specified time. BTFSS tmr_Flg2, flg_Amp_On ; Is amplifier on? GOTO isr_13 ; no DECFSZ tmr_Amp_On1,1 GOTO isr_13 DECFSZ tmr_Amp_On2,1 GOTO isr_13 BCF tmr_Flg2, flg_Amp_On BSF PORTA, bit_Amp_On ; turn off amplifier isr_13 BCF INTCON,T0IF BCF INTCON,INTF SWAPF Stat_sav,W MOVWF STATUS ; restore status (and Bank used at time of interrupt) SWAPF W_sav,F SWAPF W_sav,W ; restore w without changing status RETFIE Beep BSF PORTB,4 MOVLW 0x80 MOVWF ExitDel2 Beep1 DECFSZ ExitDel1 GOTO Beep1 DECFSZ ExitDel2 GOTO Beep1 BCF PORTB,4 RETURN ;---------Main program - Setup Main CLRF PORTA ; clear Port A MOVLW 0x07 ; turn comparators off and enable MOVWF CMCON ; pins for I/O functions CLRF PORTB ; clear Port B BCF STATUS, RP1 BSF STATUS, RP0 ; select bank 1 MOVLW b'00000111' ; RA0, RA1, RA2 = input MOVWF TRISA ^ 0x080 CLRF TRISB ^ 0x080 ; Port B - all output CLRWDT ; clear WDT and prescaler MOVLW b'00000100' ; prescaler (1:32) ; MOVLW b'00000001' ; ----------- prescaler - for debugging only MOVWF OPTION_REG ^ 0x080 ; TMR0 interrupts = 6 microseconds apart BCF STATUS, RP0 ; bank 0 CLRF TMR0 ; clear Timer0 register CALL SetDis ; startup in disabled mode MOVLW 0xA0 ; set GIE <7> and T0IE <5> MOVWF INTCON ; enable Interrupts CLRF mi_Flgs ; miscellaneous flags BSF mi_Flgs,flg_RAoff ; Set button released flag ;------------ Main program - Loop Loop BTFSC mi_Flgs, flg_Deboun ; debounce in progress? GOTO M_look ; yes - skip RA0 input processing BTFSS tmr_Flg1, flg_Disarm ; disarm in progress? GOTO Check ; no - do normal RA0 input processing BTFSS PORTA,0 ; still in progress? GOTO Check1 ; no - do normal RA0 input processing Call Deboun ; Yes - debounce here to implement a 'sampling' effect GOTO M_look ; skip RA0 input processing Check ; Main Loop - Check for command input (commands entered via the momentary switch) BTFSC PORTA,0 ; check RA0 (command input) GOTO Input ; RA0 is high so go process it Check1 BTFSC mi_Flgs,flg_RAoff ; RA0 is low - just released? GOTO M_look ; No - it has been low CALL Deboun ; Debounce BSF mi_Flgs,flg_RAoff ; Set "RA0 is low" flag BCF tmr_Flg1, flg_Disarm ; turn any off disarm-in-progress GOTO M_look Input ; Main Loop - Process command input. BTFSS mi_Flgs,flg_RAoff ; just turned on? GOTO Input3 ; no - this can happen only on 2nd click of a double-click CALL Deboun ; Yes - so debounce it BCF mi_Flgs,flg_RAoff ; Set "RA0 is high" flag BTFSS Alarm_state,flg_Ena ; is alarm enabled? GOTO Input1 ; No INCF cnt_Clicks,1 ; --- MOVLW 0x03 ; --- number Clicks = 3 SUBWF cnt_Clicks,0 ; --- while in enabled mode? BTFSS STATUS,Z ; --- GOTO Input4 ; MOVLW b'00000010' ; XORWF mi_Flgs,flg_Zone2 ; reverse Zone2 enabled/disabled status CLRF cnt_Clicks GOTO Input4 ; Input1 BTFSS tmr_Flg1, flg_Clk ; were we waiting for a double click? GOTO Input2 ; no CALL Enable GOTO M_look Input2 MOVLW lmt_Clk ; get double-click interval MOVWF tmr_Clk BSF tmr_Flg1, flg_Clk ; start the double click timer Input3 BTFSC Alarm_state, flg_Dis ; is alarm already disabled? GOTO Loop ; yes, Input4 MOVLW lmt_Disarm ; start 'disarm-in-progress' MOVWF tmr_Disarm1 BSF tmr_Flg1, flg_Disarm ; start the disable command timer M_look ; Main Loop - looks for input from the motion detectors. BTFSC Alarm_state, flg_Dis ; is alarm disabled? GOTO Loop ; yes - don't look for an intruder BTFSC tmr_Flg2, flg_Waita ; giving someone time to enter & turn off alarm? GOTO Loop ; BTFSC tmr_Flg2, flg_Waitb ; giving someone time to enable & leave room? GOTO Loop ; yes BTFSC tmr_Flg2, flg_Trig ; already processing a motion trigger? GOTO Loop ; yes BTFSC tmr_Flg1, flg_Strobe ; is strobe light on ? GOTO Loop ; yes, let existing alarm complete BTFSC mi_Flgs,flg_Zone2 ; is zone-2 disabled? GOTO M_Look1 ; yes - check zone-1 BTFSC PORTA,bit_Z2 ; zone-2 low? (normally low) GOTO M_trig ; zone-2 detected M_Look1 BTFSS PORTA,bit_Z1 ; Zone-1 high? (normally low) GOTO Loop M_trig CALL Alrm_go ; Zone 1 or 2 detected GOTO Loop ; Subroutines - Logic in the Main Loop was simplified by moving code that performed a ; well-defined function to a subroutine. Sometimes that is the sole ; purpose of a subroutine, and, in fact does not shorten the program or ; improve anything but readability. Enable ;----Subroutine - Enable/Reset the alarm CLRF 4Eh ;clear flag file CLRF cnt_Clicks CLRF tmr_Flg1 CLRF tmr_Flg2 CLRF PORTB ; clear Port B - stop all alarms BSF PORTA, bit_Amp_On ; turn off amplifier MOVLW 0x00 MOVWF INTCON ;turn off interrupts MOVLW 30h ;number of beeps/flashes MOVWF 4Dh Exit BSF 06,2 ;turn on green LED BSF 06,4 ;turn on beeper CALL Del2 ;short delay BCF 06,4 ;turn off beeper CALL Del1 ;call long delay BCF 06,2 CALL Del1 BTFSS 4Eh,0 GOTO Exit1 BCF 4Eh,0 ;reset the flag GOTO Exit2 Exit1 DECFSZ 4Dh,1 GOTO Exit Exit2 MOVLW 0x0A0 MOVWF INTCON ;turn on interrupts CLRF tmr_Delay1 ; set delay MOVLW 0x03 ; wait another 2 seconds to enable MOVWF tmr_Delay2 CLRF Alarm_state ; BSF Alarm_state, flg_Ena ; Set alarm to enabled mode BCF tmr_Flg2,flg_Waita BSF tmr_Flg2,flg_Waitb RETURN Del1 MOVLW 0A0h ;long delay MOVWF 4Bh ;file to decrement Del1A NOP MOVLW 2Ch ;allow 3 beeps before button detected SUBWF 4Dh,0 BTFSC 03,0 ;test carry flag. Will be set if more GOTO Del1B BTFSC 05,0 BSF 4E,0 ;button has been detected- flag it Del1B DECFSZ 4C,1 GOTO Del1A DECFSZ 4B,1 GOTO Del1A RETURN Del2 MOVLW 20h ;short delay MOVWF 4Bh ;file to decrement Del2A NOP MOVLW 2Ch ;allow 3 beeps before button detected SUBWF 4Dh,0 BTFSC 03,0 ;test carry flag. Will be set if more GOTO Del2B BTFSC 05,0 BSF 4E,0 ;button has been detected- flag it Del2B DECFSZ 4C,1 GOTO Del2A DECFSZ 4B,1 GOTO Del2A RETURN ;----- Subroutine - Turn on Alarm - Set delay time and flags for isr routine. Alrm_go CALL Beep BCF PORTB, bit_Gre BCF PORTB, bit_Red BCF PORTB, bit_Yel BTFSS Alarm_state, flg_Ena ; previously triggered? GOTO Alrm_r ; yes CLRF Alarm_state BSF Alarm_state, flg_Yellow BSF PORTB, bit_Yel ; set LEDs to yellow alert GOTO Alrm_z Alrm_r CLRF Alarm_state BSF Alarm_state, flg_Red BSF PORTB, bit_Red ; set LEDs to Red alert Alrm_z CLRF 4Eh ;clear flag file MOVLW 0x00 MOVWF INTCON ;turn off interrupts MOVLW 30h ;48 beeps/flashes for entry MOVWF 4Dh BCF 06,1 ;clear orange LED Entry BSF 06,0 ;turn on red LED BSF 06,4 ;turn on beeper CALL Del2 ;short delay BCF 06,4 ;turn off beeper CALL Del2 ;short delay BSF 06,4 ;turn on beeper CALL Del2 ;short delay BCF 06,4 ;turn off beeper CALL Del1 ;call long delay BCF 06,0 CALL Del1 BTFSS 4Eh,0 ;test button-detect flag GOTO Entry1 BCF 4Eh,0 ;clear button-detect flag in delay routine GOTO Entry2 Entry1 DECFSZ 4Dh,1 GOTO Entry Entry2 MOVLW 0x0A0 MOVWF INTCON ;turn on interrupts MOVLW 0x0FF ; Set delay time for two extra seconds MOVWF tmr_Delay1 MOVLW 0x02 MOVWF tmr_Delay2 BCF tmr_Flg2, flg_Waitb ;clear exit delay flag BSF tmr_Flg2, flg_Waita ; Set entry delay flag BCF PORTA, bit_Amp_On ; turn on amp (Yes - turn it off to turn amp on) CLRF tmr_Amp_On1 ; Set 'Power-on' flag & timer MOVLW lmt_Amp_On2 MOVWF tmr_Amp_On2 BSF tmr_Flg2, flg_Amp_On RETURN ;--------Subroutine - Go to Yellow Alert SetYel CLRF tmr_Strobe1 ; length of time strobe is to remain on MOVLW lmt_Strobe2 MOVWF tmr_Strobe2 BSF tmr_Flg1, flg_Strobe ; flag interrupt service routine (ISR) to handle BSF PORTB, bit_Strobe ; turn on strobe light. MOVLW 0x01 MOVWF tmr_Siren ; time interval to turn Siren on MOVLW 0x015 MOVWF tbl_i ; set table index - defines 'wailing' intervals BSF tmr_Flg1, flg_Siren ; TMR0 interrupts to handle siren MOVLW 0x040 ; 'verbal warning' needs only a pulse to trigger it MOVWF tmr_Verb1 BSF tmr_Flg1, flg_Verb ; tmr0 interrupts will handle verbal warning BSF PORTB, bit_Verb ; start verbal warning (amp should be powered up) MOVLW 0x040 ; 'barking dog' needs only a pulse to trigger it MOVWF tmr_Dog1 ; BSF tmr_Flg1, flg_Dog ; set timer BSF PORTB, bit_Dog ; start barking RETURN ;--------Subroutine - Go to Red Alert SetRed CLRF tmr_Strobe1 ; length of time strobe is to remain on MOVLW lmt_Strobe2 MOVWF tmr_Strobe2 BSF tmr_Flg1, flg_Strobe ; flag 'strobe' ISR handling BSF PORTB, bit_Strobe ; turn on strobe light. MOVLW 6 ; start with short pulse (Load Buzzer) MOVWF tmr_Buzz1 ; MOVLW 19 ; number of pulses to generate MOVWF tmr_Buzz2 ; count-down timer BSF tmr_Flg1, flg_Buzz ; so tmr0 interrupts will handle buzzer BCF PORTB, bit_Buzz ; start with buzzer off MOVLW 0x040 ; barking dog module needs MOVWF tmr_Dog1 ; only need a pulse to start it BSF tmr_Flg1, flg_Dog ; set timer BSF PORTB, bit_Dog ; start barking (amp should be powered up by now) RETURN ;---------------- Subroutine - Set Alarm Disabled SetDis MOVLW 1 MOVWF Alarm_state ; set Alarm state to disabled CLRF tmr_Flg1 ; turn off anything that is on CLRF tmr_Flg2 ; turn off anything that is on CLRF cnt_Clicks MOVLW b'00000010' ; turn on ORANGE LED MOVWF PORTB BSF PORTA, bit_Amp_On ; turn off amplifier MOVLW 0x0FF MOVWF tmr_Rearm1 MOVWF tmr_Rearm2 ; Set automatic re-arm alarm timer to 4 hours MOVLW 0x01A ; 9 minutes intervals per count here MOVWF tmr_Rearm3 RETURN ;--------------- Subroutine - Turn on Debounce Deboun MOVLW lmt_Deboun MOVWF tmr_Deboun ; set Debounce interval BSF mi_Flgs, flg_Deboun ; start the Debounce timer RETURN END