; Simple Alarm System (Main Unit) ; Version 1.1 RC6 ; (c)1997-2008 ; Author: Kirill Yelizarov ; *** HOW TO MAKE *** ;1.Select desired processor in MPLAB ;2.Select IR receiver in _IR_REC ;3.Compile ;Possible processor selections: ;12C508, 12C508A, 12C509, 12C509A, 12CE518, 12CE519, 12F508, 12F509, 16F84, 16F84A ;PICs 16F84 and 16F84A are used for debug ;----------- S E L E C T --- Y O U R --- R E C E I V E R ----------- ;Possible IR receiver selections: _TBA_2800 EQU .1 ;_TBA_2800 - TBA 2800 (Micronas Intermetall GmbH http://www.intermetall.de) _BRM_1020 EQU .2 ;_BRM_1020 - BRM-1020 (Bright LED Electronics Corp. http://www.brtled.com) _TSOP_1738 EQU .3 ;_TSOP_1738 - TSOP-1738 (Vishay SemiconductorsGmbH http://www.vishay.com) _TSOP_2156 EQU .4 ;_TSOP_2156 - TSOP-2156 (Vishay SemiconductorsGmbH http://www.vishay.com) ; _IR_REC EQU _TBA_2800 ;IR receiver selection ;IR receiver logic output _IR_NEG EQU .1 ;Negative output when a pulse received _IR_POS EQU .2 ;Positive output when a pulse recieved IF _IR_REC==_TBA_2800 _IR_PHASE EQU _IR_POS ;TBA2800 has negative output too ELSE _IR_PHASE EQU _IR_NEG ENDIF ;------------------------------------------------------------------- ;Debug _DEBUG EQU .0 ;no debug, normal operation ;Debug levels for 16F84 and 16F84A only ;Some pins are used another way in debug mode ;Check code before using this option ;_DEBUG EQU .1 ;debug level #1 disable high timer ;_DEBUG EQU .2 ;debug level #2 check IR receiver routine ;_DEBUG EQU .3 ;debug level #3 check IR receiver routine and password ;_DEBUG EQU .4 ;debug level #3 check IR receiver routine, password, and CRC _12C508 EQU .1 _12C508A EQU .2 _12C509 EQU .3 _12C509A EQU .4 _12CE518 EQU .5 _12CE519 EQU .6 _16F84 EQU .7 _16F84A EQU .8 _12F508 EQU .9 _12F509 EQU .10 IFDEF __12C508 LIST P=PIC12C508 INCLUDE p12c508.inc _PIC_CPU equ _12C508 _PIC_MEM equ 0x07 ENDIF IFDEF __12C508A LIST P=PIC12C508A INCLUDE p12c508a.inc _PIC_CPU equ _12C508A _PIC_MEM equ 0x07 ENDIF IFDEF __12C509 LIST P=PIC12C509 INCLUDE p12c509.inc _PIC_CPU equ _12C509 _PIC_MEM equ 0x07 ENDIF IFDEF __12C509A LIST P=PIC12C509A INCLUDE p12c509a.inc _PIC_CPU equ _12C509A _PIC_MEM equ 0x07 ENDIF IFDEF __12CE518 LIST P=PIC12CE518 INCLUDE p12ce518.inc _PIC_CPU equ _12CE518 _PIC_MEM equ 0x07 ENDIF IFDEF __12CE519 LIST P=PIC12CE519 INCLUDE p12ce519.inc _PIC_CPU equ _12CE519 _PIC_MEM equ 0x07 ENDIF IFDEF __12F508 LIST P=PIC12F508 INCLUDE p12f508.inc _PIC_CPU equ _12F508 _PIC_MEM equ 0x07 ENDIF IFDEF __12F509 LIST P=PIC12F509 INCLUDE p12f509.inc _PIC_CPU equ _12F509 _PIC_MEM equ 0x07 ENDIF IFDEF __16F84 LIST P=PIC16F84 INCLUDE p16f84.inc _PIC_CPU equ _16F84 _PIC_MEM equ 0x0c ENDIF IFDEF __16F84A LIST P=PIC16F84A INCLUDE p16f84a.inc _PIC_CPU equ _16F84A _PIC_MEM equ 0x0c ENDIF IFDEF _PIC_CPU IFDEF _IR_REC IF (_PIC_CPU==_12C508)||(_PIC_CPU==_12C508A)||(_PIC_CPU==_12C509)||(_PIC_CPU==_12C509A)||(_PIC_CPU==_12CE518)||(_PIC_CPU==_12CE519)||(_PIC_CPU==_12F508)||(_PIC_CPU==_12F509) __CONFIG _IntRC_OSC & _WDT_OFF & _CP_OFF & _MCLRE_OFF ENDIF IF (_PIC_CPU==_16F84)||(_PIC_CPU==_16F84A) __CONFIG _XT_OSC & _WDT_OFF & _CP_OFF & _PWRTE_OFF ENDIF INCLUDE "password.inc" #define OK 0x00 #define Wait 0xff #define ACTIVATE b'10000000' #define BEEP b'00100000' #define LIGHT b'00010000' #define UNLOCK b'00000010' #define LOCK b'00000001' IF (_PIC_CPU==_16F84)||(_PIC_CPU==_16F84A) #define GPIO PORTB ENDIF #define OutsidePin GPIO,5 ;two stage sensors (outside zone) #define InsidePin GPIO,4 ;two stage sensors (inside zone) #define IR GPIO,3 ;IR input pin #define Immob GPIO,2 ;immobilizer #define UnlockPin GPIO,1 ;doors lock unlock trigger #define LockPin GPIO,0 ;doors lock lock trigger ;----- Local DATA ----- CBLOCK _PIC_MEM AlarmTris ;alarm TRIS register ENDC #define ArmLight AlarmTris,7 ; #define DisarmLight AlarmTris,6 #define OutsideTris AlarmTris,5 #define InsideTris AlarmTris,4 #define BatteryWeak AlarmTris,3 #define SilentMode AlarmTris,2 #define UnlockTris AlarmTris,1 #define LockTris AlarmTris,0 CBLOCK AlarmFlags ;Alarm flags ENDC #define LockedFlag AlarmFlags,7 #define ArmedFlag AlarmFlags,6 #define AlarmInside AlarmFlags,5 #define AlarmOutside AlarmFlags,4 #define AlarmMemory AlarmFlags,3 #define KillAll AlarmFlags,2 ;Kill all current tasks flag #define THO AlarmFlags,1 ;High Timer overflow flag #define ArmTrigger AlarmFlags,0 CBLOCK LockUnlockSW ;Lock/Unlock switch flags ENDC #define UnlockSW_E LockUnlockSW,7 #define UnlockSW_F LockUnlockSW,6 #define UnlockSW_P LockUnlockSW,5 #define UnlockSW LockUnlockSW,4 #define LockSW_E LockUnlockSW,3 #define LockSW_F LockUnlockSW,2 #define LockSW_P LockUnlockSW,1 #define LockSW LockUnlockSW,0 CBLOCK AlarmSW ;Inside and Outside zones flags & arm/disarm flags ENDC #define ArmBeep AlarmSW,7 #define OutsideSW_F AlarmSW,6 #define OutsideSW_P AlarmSW,5 #define OutsideSW AlarmSW,4 #define DisarmBeep AlarmSW,3 #define InsideSW_F AlarmSW,2 #define InsideSW_P AlarmSW,1 #define InsideSW AlarmSW,0 CBLOCK TimerHigh ;High timer IRStatus ;bits<7-0> IR pin samples with a 2us step BitStatus ;bit<7> recieving data Dig1 ;password Dig2 Dig3 Dig4 Dig5 Dig6 Dig7 Dig8 Dig9 ;command and CRC Out1Pin Out1Counter Out1Duration Out2Pin Out2Counter Out2Duration Out3Pin Out3Counter Out3Duration ENDC _END_PIC_MEM EQU Out3Duration ;last RAM cell ;-------- ROM --------- org 0x00 goto Main IF (_PIC_CPU==_16F84)||(_PIC_CPU==_16F84A) org 0x04 goto Main ENDIF ;Get empty Output ------------------------------------------------------ GetEmptyOutput movlw Out1Pin movwf FSR btfss INDF,7 ;check for an empty output 1 retlw OK movlw Out2Pin movwf FSR btfss INDF,7 ;check for an empty output 2 retlw OK movlw Out3Pin movwf FSR btfss INDF,7 ;check for an empty output 3 retlw OK retlw Wait ;Output Task ------------------------------------------------------------ Output movwf FSR ;save OutXPin offset btfss INDF,7 ;check if output activated retlw OK ;if not then return incf FSR,F ;move offset to OutXCounter btfsc KillAll ;check for a kill all command goto StopOutput decfsz INDF,F ;if zero not reached goto $+2 ;go to set output else release pin goto StopOutput ;and branch to StopOutput to release pin decf FSR,F ;move back to OutXPin comf INDF,W ;move to W complement value of OutXPin andwf AlarmTris,F ;clear the necessary bit in AlarmTris movf AlarmTris,W ;and make the changes to tris itself iorlw b'11001000' ;mask 3 system flags bits<7,6,3> andlw b'11111011' ;mask 4th system flag bit<2> IF (_PIC_CPU==_16F84)||(_PIC_CPU==_16F84A) bsf STATUS,RP0 ;select bank1 movwf TRISB bcf STATUS,RP0 ;select bank0 ENDIF IF (_PIC_CPU==_12C508)||(_PIC_CPU==_12C508A)||(_PIC_CPU==_12C509)||(_PIC_CPU==_12C509A)||(_PIC_CPU==_12CE518)||(_PIC_CPU==_12CE519)||(_PIC_CPU==_12F508)||(_PIC_CPU==_12F509) tris GPIO ENDIF incf FSR,F incf FSR,F ;move to OutXDuration bcf STATUS,C ;Clear Carry btfsc INDF,7 ;if bit 7 of OutXDuration set bsf STATUS,C ;then set Carry rlf INDF,F ;rotate OutXDuration btfsc STATUS,C ;check Carry goto RiseOutput ;if set then jump to RiseOutput decf FSR,F decf FSR,F ;move back to OutXPin comf INDF,W ;move to W complement value of OutXPin andwf GPIO,F ;clear the necessary bit in GPIO retlw OK RiseOutput: decf FSR,F decf FSR,F ;move back to OutXPin movf INDF,W ;move to W value of OutXPin iorwf GPIO,F ;set the necessary bit in GPIO retlw OK StopOutput: decf FSR,F ;move back to OutXPin bcf INDF,7 ;clear bit 7 comf INDF,W ;move to W complement value of OutXPin andwf GPIO,F ;clear the necessary bit in GPIO movf INDF,W ;move to W value of OutXPin iorwf AlarmTris,F ;set the necessary bit in AlarmTris movf AlarmTris,W ;and make the changes to tris itself iorlw b'11001000' ;mask 3 system flags bits<7,6,3> andlw b'11111011' ;mask 4th system flag bit<2> IF (_PIC_CPU==_16F84)||(_PIC_CPU==_16F84A) bsf STATUS,RP0 ;select bank1 movwf TRISB bcf STATUS,RP0 ;select bank0 ENDIF IF (_PIC_CPU==_12C508)||(_PIC_CPU==_12C508A)||(_PIC_CPU==_12C509)||(_PIC_CPU==_12C509A)||(_PIC_CPU==_12CE518)||(_PIC_CPU==_12CE519)||(_PIC_CPU==_12F508)||(_PIC_CPU==_12F509) tris GPIO ENDIF retlw OK ;Button Tester ------------------------------------------------------------ ;this routine uses three flags (P, F and pressed button flag) TestSwitch btfss STATUS,Z ;check the button is pressed goto ResetButton ;if not jump to ResetButton btfss INDF,2 ;check flag F state (First occurence) goto SetButton btfsc INDF,1 ;check flag P state retlw OK movlw b'00000011' iorwf INDF,F ;set P flag (Pressed condition) and button flag retlw OK SetButton: movlw b'00000100' iorwf INDF,F ;set F flag retlw OK ResetButton: movlw b'11111001' andwf INDF,F ;clear P, F flags (Button flag can be cleared in software only) retlw OK ;Check IR input pin --------------------------------------------------------- CheckIR btfss TMR0,7 goto CheckIR CheckZeroTMR: btfsc TMR0,7 goto CheckZeroTMR decfsz TimerHigh,F goto SkipSetTH bsf THO SkipSetTH: clrf IRStatus IF _IR_PHASE==_IR_NEG btfss IR ELSE btfsc IR ENDIF bsf IRStatus,6 nop nop nop nop IF _IR_PHASE==_IR_NEG btfss IR ELSE btfsc IR ENDIF incf IRStatus,F IF _IR_PHASE==_IR_NEG btfss IR ELSE btfsc IR ENDIF incf IRStatus,F IF _IR_PHASE==_IR_NEG btfss IR ELSE btfsc IR ENDIF incf IRStatus,F IF _IR_PHASE==_IR_NEG btfss IR ELSE btfsc IR ENDIF incf IRStatus,F IF _IR_PHASE==_IR_NEG btfss IR ELSE btfsc IR ENDIF incf IRStatus,F IF _IR_PHASE==_IR_NEG btfss IR ELSE btfsc IR ENDIF incf IRStatus,F btfsc IRStatus,2 ;Check at least 4 samples are high goto PulseFound ;If IRStatus>3 then jump to PulseFound bsf BitStatus,6 ;Pause found then set pause flag incf BitStatus,F ;else increase BitStatus (bit analyzer counter) btfsc BitStatus,2 ;check overflow condition goto NoiseFound ;else noise found (overflow) retlw OK ;It's not an overflow, normal return PulseFound: nop IF _IR_PHASE==_IR_NEG btfss IR ELSE btfsc IR ENDIF bsf IRStatus,7 movlw .20 btfss IRStatus,6 subwf TMR0,F btfss IRStatus,7 addwf TMR0,F btfss BitStatus,7 ;else check first pulse flag goto FirstPulse ;if it is cleared then raise it and return btfss BitStatus,6 ;Was pause flag raised goto FirstPulse ;if not then jump to FirstPulse (maybe this one is real) btfss BitStatus,0 ;check analyzer counter bit 0 goto Bit1Found ;This is a bit "1" in a message so jump to Bit1Found btfss BitStatus,1 ;check analyzer counter bit 1 goto Bit0Found ;This is a bit "0" in a message so jump to Bit0Found btfsc BitStatus,5 ;Start bit found goto FirstPulse ;if it is set already then it's a noise or a real first pulse bsf BitStatus,5 ;enable Start Bit flag bsf STATUS,C ;Start bit, once rotated through Dig0 it will stop incomming message goto NextDigit Bit1Found: btfss BitStatus,5 goto FirstPulse ;If start bit is not set this maybe a real first pulse bsf STATUS,C ;set incoming bit goto NextDigit Bit0Found: btfss BitStatus,5 goto FirstPulse ;If start bit is not set this maybe a real first pulse bcf STATUS,C ;clear incoming bit NextDigit: movlw b'10111000' andwf BitStatus,F rlf Dig9,F rlf Dig8,F rlf Dig7,F rlf Dig6,F rlf Dig5,F rlf Dig4,F rlf Dig3,F rlf Dig2,F rlf Dig1,F btfss STATUS,C ;is start bit popped out retlw OK ;if not then return IF (_DEBUG==.2)&&((_PIC_CPU==_16F84)||(_PIC_CPU==_16F84A)) movf Dig9,W andlw b'00110000' movwf Dig8 rlf Dig9,F rlf Dig9,F rlf Dig9,W andlw b'00000011' iorwf Dig8,W movwf PORTB retlw OK ENDIF movlw PASS8 ;time to check message xorwf Dig8,W btfss STATUS,Z goto NoiseFound movlw PASS7 xorwf Dig7,W btfss STATUS,Z goto NoiseFound movlw PASS6 xorwf Dig6,W btfss STATUS,Z goto NoiseFound movlw PASS5 xorwf Dig5,W btfss STATUS,Z goto NoiseFound movlw PASS4 xorwf Dig4,W btfss STATUS,Z goto NoiseFound movlw PASS3 xorwf Dig3,W btfss STATUS,Z goto NoiseFound movlw PASS2 xorwf Dig2,W btfss STATUS,Z goto NoiseFound movlw PASS1 xorwf Dig1,W btfss STATUS,Z goto NoiseFound IF (_DEBUG==.3)&&((_PIC_CPU==_16F84)||(_PIC_CPU==_16F84A)) movf Dig9,W andlw b'00110000' movwf Dig8 rlf Dig9,F rlf Dig9,F rlf Dig9,W andlw b'00000011' iorwf Dig8,W movwf PORTB retlw OK ENDIF movf Dig9,W movwf IRStatus ;save command and CRC andlw b'11110000' ;cut CRC movwf Dig9 ;and place back to Dig9 movlw .72 movwf BitStatus ;this is CRC_Counter movlw b'00110000' ;set poly (4bit CRC poly=10011) CRCBit: bcf STATUS,C rlf Dig9,F rlf Dig8,F rlf Dig7,F rlf Dig6,F rlf Dig5,F rlf Dig4,F rlf Dig3,F rlf Dig2,F rlf Dig1,F btfsc STATUS,C xorwf Dig1,F decfsz BitStatus,F goto CRCBit movf IRStatus,W ;Check CRC movwf Dig9 andlw b'00001111' swapf Dig1,F xorwf Dig1,W btfss STATUS,Z goto NoiseFound IF (_DEBUG==.4)&&((_PIC_CPU==_16F84)||(_PIC_CPU==_16F84A)) movf Dig9,W andlw b'00110000' movwf Dig8 rlf Dig9,F rlf Dig9,F rlf Dig9,W andlw b'00000011' iorwf Dig8,W movwf PORTB retlw OK ENDIF btfsc IRStatus,7 bsf SilentMode btfsc IRStatus,7 bsf ArmTrigger btfsc IRStatus,5 bsf ArmTrigger btfsc IRStatus,4 bsf BatteryWeak goto NoiseFound NoiseFound: clrf BitStatus ;erase BitStatus EraseMessage: clrf Dig9 ;erase message buffer clrf Dig8 clrf Dig7 clrf Dig6 clrf Dig5 clrf Dig4 clrf Dig3 clrf Dig2 clrf Dig1 retlw OK ;and return FirstPulse: clrf BitStatus ;erase BitStatus bsf BitStatus,7 goto EraseMessage ; ------------ M A I N ------------- Main: clrf STATUS IF (_PIC_CPU==_12C508)||(_PIC_CPU==_12C508A)||(_PIC_CPU==_12C509)||(_PIC_CPU==_12C509A)||(_PIC_CPU==_12CE518)||(_PIC_CPU==_12CE519)||(_PIC_CPU==_12F508)||(_PIC_CPU==_12F509) movlw b'11001000' ;Dissable weak pull-ups and wake up on pin change option ;and set Timer0 prescaller 1:1 movlw b'00111011' ;All pins are set as input on initialize except GP2 tris GPIO ENDIF IF (_PIC_CPU==_16F84)||(_PIC_CPU==_16F84A) movlw b'00000000' movwf INTCON ;disable interrupts movlw b'10001000' ;disable weak pull-up on PortB bsf STATUS,RP0 ;select bank1 movwf OPTION_REG movlw b'11111111' ;all pins are input movwf TRISA movlw b'11111011' ;except RB2 movwf TRISB bcf STATUS,RP0 ;select bank0 ENDIF clrf GPIO ;Reset GPIO EraseRAM: movlw _PIC_MEM movwf FSR EraseNext: clrf INDF IF (_PIC_CPU==_12C508)||(_PIC_CPU==_12C508A)||(_PIC_CPU==_12CE518) movlw _END_PIC_MEM + b'11100000' ENDIF IF (_PIC_CPU==_12C509)||(_PIC_CPU==_12C509A)||(_PIC_CPU==_12CE519) movlw _END_PIC_MEM + b'11000000' ENDIF IF (_PIC_CPU==_16F84)||(_PIC_CPU==_16F84A) movlw _END_PIC_MEM ENDIF xorwf FSR,W btfsc STATUS,Z goto EndEraseRAM incf FSR,F goto EraseNext EndEraseRAM: movlw b'00110011' movwf AlarmTris ;initiate tris register bsf ArmedFlag ;Main unit always armed when powered on IF ((_DEBUG==.2)||(_DEBUG==.3)||(_DEBUG==.4))&&((_PIC_CPU==_16F84)||(_PIC_CPU==_16F84A)) bsf STATUS,RP0 ;select bank1 movlw b'11001100' ;set RB0,RB1,RB4,RB5 as output for debug output movwf TRISB bcf STATUS,RP0 ;select bank0 DebugLevel2: call CheckIR ;!!!!!!!!!! Check IR input state goto DebugLevel2 ;for debug only!!!!!!!!!!!!!!!! ENDIF clrf TMR0 Loop: ; --------------- Input States --------------------- CheckInsideZone: call CheckIR ;!!!!!!!!!! Check IR input state btfss InsideTris ;Check the inside zone trigger is set for input goto EndCheckInsideZone movlw AlarmSW ;save AlarmSW offset to FSR movwf FSR bcf STATUS,Z btfss InsidePin ;check inside zone trigger condition bsf STATUS,Z ;if level is low set Zero flag call TestSwitch EndCheckInsideZone: CheckOutsideZone: call CheckIR ;!!!!!!!!!! Check IR input state btfss OutsideTris ;Check the outside zone trigger is set for input goto EndCheckOutsideZone swapf AlarmSW,F ;swap nibbles movlw AlarmSW ;save AlarmSW offset to FSR movwf FSR bcf STATUS,Z btfss OutsidePin ;check outside zone trigger condition bsf STATUS,Z ;if level is low set Zero flag call TestSwitch swapf AlarmSW,F ;swap nibbles back EndCheckOutsideZone: CheckLockSW: call CheckIR ;!!!!!!!!!! Check IR input state btfss LockTris ;Check the lock switch is set for input goto EndCheckLockSW movlw LockUnlockSW ;save LockUnlockSW offset to FSR movwf FSR bcf STATUS,Z btfss LockPin ;check Lock switch condition bsf STATUS,Z ;if level is low set Zero flag call TestSwitch EndCheckLockSW: CheckUnlockSW: call CheckIR ;!!!!!!!!!! Check IR input state btfss UnlockTris ;Check the unlock switch is set for input goto EndCheckUnlockSW swapf LockUnlockSW,F ;swap nibbles movlw LockUnlockSW ;save LockUnlockSW offset to FSR movwf FSR bcf STATUS,Z btfss UnlockPin ;check Unlock switch condition bsf STATUS,Z ;if level is low set Zero flag call TestSwitch swapf LockUnlockSW,F ;swap nibbles back EndCheckUnlockSW: ;------------ Alarm logic ------------- CheckFlags: call CheckIR ;!!!!!!!!!! Check IR input state btfsc ArmedFlag ;Armed? 1-Armed 0-not goto CheckToDisarm CheckToArm: btfss ArmTrigger goto CheckArmFlag bsf ArmedFlag ;System armed now bcf InsideSW_P bcf InsideSW_F bcf InsideSW ;clear inside zone triggers bcf OutsideSW_P bcf OutsideSW_F bcf OutsideSW ;clear outside zone triggers bcf ArmTrigger ;clear lock flag bsf KillAll ;Kill all current tasks btfss SilentMode bsf ArmBeep ;enable arm visualization bcf SilentMode bsf ArmLight goto Lock CheckToDisarm: btfss ArmTrigger goto CheckArmFlag bcf ArmedFlag ;System disarmed now bcf ArmTrigger ;clear lock flag bsf KillAll ;Kill all current tasks btfss SilentMode bsf DisarmBeep ;enable disarm visualization bcf SilentMode bsf DisarmLight goto Unlock CheckArmFlag: btfss ArmedFlag goto Disarmed bcf Immob ;immobilizer relay off btfss InsideSW ;inside trigger set? goto CheckOutsideTrigger bcf InsideSW bsf AlarmInside ;Turn alarm inside zone on CheckOutsideTrigger: btfss OutsideSW ;outside trigger set? goto CheckComplete bcf OutsideSW bsf AlarmOutside ;Turn alarm outside zone on goto CheckComplete Disarmed: bsf Immob ;immobilizer relay on btfsc InsideSW ;inside trigger set? bcf AlarmMemory ;then clear memory btfsc LockedFlag ;Doors locked? 1-Doors locked 0-unlocked goto CheckToUnlock CheckToLock: btfss LockSW ;Lock enabled? goto CheckComplete btfsc UnlockSW ;Check the unlock flag goto CheckComplete ;Skip situation when both flags raised Lock: bsf LockSW_E ;if its a lock command set Lock enable flag bsf LockedFlag ;Doors locked now goto CheckComplete CheckToUnlock: btfss UnlockSW ;Unlock enabled? goto CheckComplete btfsc LockSW ;Check the lock flag goto CheckComplete ;Skip situation when both flags raised Unlock: bsf UnlockSW_E ;if YES set Unlock enable flag bcf LockedFlag ;Doors unlocked now CheckComplete: bcf LockSW ;clear lock flag bcf UnlockSW ;clear unlock flag ; --------------------- Output States ------------------------ CheckOut1Pin: call CheckIR ;!!!!!!!!!! Check IR input state movlw Out1Pin call Output ;check output cell #1 CheckOut2Pin: call CheckIR ;!!!!!!!!!! Check IR input state movlw Out2Pin call Output ;check output cell #2 CheckOut3Pin: call CheckIR ;!!!!!!!!!! Check IR input state movlw Out3Pin call Output ;check output cell #3 bcf KillAll ;clear command ; -------------------- Set States --------------------------- EnableInsideAlarm: call CheckIR ;!!!!!!!!!! Check IR input state btfss AlarmInside ;Check inside zone alarm enable flag goto EndEnableInsideAlarm call GetEmptyOutput ;Find empty output cell xorlw Wait ;check an empty output cell found btfsc STATUS,Z goto EndEnableInsideAlarm ;if not skip the rest and wait bcf AlarmInside ;Clear alarm enable flag movlw LIGHT+BEEP+ACTIVATE movwf INDF incf FSR,F movlw .80 ;duration 65ms*80= movwf INDF incf FSR,F movlw b'11110000' movwf INDF bcf InsideSW_P bcf InsideSW_F bsf AlarmMemory EndEnableInsideAlarm: EnableOutsideAlarm: call CheckIR ;!!!!!!!!!! Check IR input state btfss AlarmOutside ;Check outside zone alarm enable flag goto EndEnableOutsideAlarm call GetEmptyOutput ;Find empty output cell xorlw Wait ;check an empty output cell found btfsc STATUS,Z goto EndEnableOutsideAlarm ;if not skip the rest and wait bcf AlarmOutside ;Clear alarm enable flag movlw BEEP+ACTIVATE movwf INDF incf FSR,F movlw .8 ;duration 65ms*4=260ms movwf INDF incf FSR,F movlw b'10000000' ;beep duration 65ms*1=65ms movwf INDF bcf OutsideSW_P bcf OutsideSW_F EndEnableOutsideAlarm: EnableBeep: call CheckIR ;!!!!!!!!!! Check IR input state btfsc ArmBeep ;Check arm beep enable flag goto Beep btfss DisarmBeep ;Check disarm beep enable flag goto EndEnableBeep Beep: call GetEmptyOutput ;Find empty output cell xorlw Wait ;check an empty output cell found btfsc STATUS,Z goto EndEnableBeep ;if not skip the rest and wait movlw BEEP+ACTIVATE movwf INDF incf FSR,F movlw .8 ;duration 65ms*8=520ms (1 beep) btfsc DisarmBeep movlw .16 ;duration 65ms*16=1040ms (2 beeps) btfsc AlarmMemory movlw .24 movwf INDF incf FSR,F movlw b'11100000' ;beep duration 65ms*3=195ms movwf INDF bcf ArmBeep ;Clear beep enable flag bcf DisarmBeep EndEnableBeep: DoorLock: call CheckIR ;!!!!!!!!!! Check IR input state btfsc LockSW_E ;Check Lock enable flag goto EnableDoorLock btfsc UnlockSW_E ;Check unlock enable flag goto EnableDoorLock goto EndEnableDoorLock EnableDoorLock: call GetEmptyOutput ;Find empty output cell xorlw Wait ;check an empty output cell found btfsc STATUS,Z goto EndEnableDoorLock ;if not skip the rest and wait movlw LOCK+ACTIVATE btfsc UnlockSW_E movlw UNLOCK+ACTIVATE movwf INDF ; bcf LockSW_E ;Clear lock enable flag bcf UnlockSW_E ;Clear unlock enable flag incf FSR,F movlw 0x02 ;set duration 128ms movwf INDF incf FSR,F movlw b'11000000' ;set bit map movwf INDF EndEnableDoorLock: EnableLight: call CheckIR ;!!!!!!!!!! Check IR input state btfsc ArmLight ;Check light enable flag goto Light btfss DisarmLight goto EndEnableLight Light: call GetEmptyOutput ;Find empty output cell xorlw Wait ;check an empty output cell found btfsc STATUS,Z goto EndEnableLight ;if not skip the rest and wait movlw LIGHT+ACTIVATE movwf INDF ; incf FSR,F movlw .8 ;duration 65ms*8=520ms (1 blink) btfsc DisarmLight movlw .16 ;duration 65ms*16=1040ms (2 blinks) btfsc AlarmMemory movlw .24 movwf INDF incf FSR,F movlw b'11110000' btfsc BatteryWeak movlw b'11111111' movwf INDF bcf BatteryWeak bcf ArmLight ;Clear light enable flag bcf DisarmLight EndEnableLight: _Wait: IF (_DEBUG==.1)&&((_PIC_CPU==_16F84)||(_PIC_CPU==_16F84A)) goto Loop ;for debug only!!!!!!!!!!!!!!!! ENDIF call CheckIR ;!!!!!!!!!! Check IR input state btfss THO goto _Wait bcf THO goto Loop IF (_PIC_CPU==_12C508)||(_PIC_CPU==_12C508A)||(_PIC_CPU==_12CE518)||(_PIC_CPU==_12F508) org 0x1ff movlw b'01110000' ;set OSCCAL ENDIF IF (_PIC_CPU==_12C509)||(_PIC_CPU==_12C509A)||(_PIC_CPU==_12CE519)||(_PIC_CPU==_12F509) org 0x3ff movlw b'01110000' ;set OSCCAL ENDIF ELSE Error "IR Receiver not selected. Check code" ENDIF ELSE Error "Wrong PIC selected. [Configure]->[Select Device...]" ENDIF end