;*************************************************************** ;* Car Alarm System * ;* Main Unit * ;* Version 01 * ;* 1996 * ;*************************************************************** LIST P=PIC16C84, R=HEX INCLUDE "f:\mpasm\include\p16C84.inc" __CONFIG _XT_OSC & _WDT_OFF & _CP_OFF ;----- Port A bits ----- AlarmSW equ 4 Relay equ 3 Beep equ 2 Lights equ 1 LED equ 0 ;----- Port B bits ----- HiJackSW equ 7 IgnitionSW equ 6 MainSW equ 5 DelaySW equ 4 AlarmON equ 3 AlarmOFF equ 2 Lock equ 1 IRInp equ 0 ;----- AlarmFlags bits ----- OFF_Flag equ 7 ON_Flag equ 6 NullFlag equ 5 IRFlag equ 4 AlarmFlag equ 3 IntrusionFlag equ 2 DelayFlag equ 1 BeepFlag equ 0 ;----- Password ----- PASS1 equ 0x03 PASS2 equ 0xc2 PASS3 equ 0xa7 PASS4 equ 0x4f PASS5 equ 0xe9 PASS6 equ 0x85 PASS7 equ 0x6b PASS8 equ 0x1d ;----- Local DATA ----- DelayCountLow equ 0x0c DelayCountHi equ 0x0d Count equ 0x0e IRCount equ 0x0f AlarmFlags equ 0x10 TempW equ 0x11 TempSTATUS equ 0x12 IRCorrection equ 0x13 Dig1 equ 0x14 Dig2 equ 0x15 Dig3 equ 0x16 Dig4 equ 0x17 Dig5 equ 0x18 Dig6 equ 0x19 Dig7 equ 0x1a Dig8 equ 0x1b ;----- CODE ----- org 0 goto Start ; ------------ I N T E R R U P T R O U T I N E ------------- org 0x04 ;min3-max4 mks movwf TempW ;save W and STATUS movf STATUS,W movwf TempSTATUS btfss INTCON,INTF goto WatchSwitch clrf Dig1 clrf Dig2 clrf Dig3 clrf Dig4 clrf Dig5 clrf Dig6 clrf Dig7 clrf Dig8 movlw 0xc2 call IRDelay ;delay 194*3-1+5=586 mks call IRDelay ;delay 194*3-1+5=586 mks nop nop clrf IRCorrection ;reset correction btfsc PORTB,IRInp ;set correction -3 mks goto RestoreIntFlag incf IRCorrection,F btfsc PORTB,IRInp ;set correction -2 mks goto SetCorrection incf IRCorrection,F btfsc PORTB,IRInp ;set correction -1 mks goto SetCorrection incf IRCorrection,F btfsc PORTB,IRInp ;set correction 0 mks delay 3 mks goto SetCorrection incf IRCorrection,F btfsc PORTB,IRInp ;set correction +1 mks goto SetCorrection incf IRCorrection,F btfsc PORTB,IRInp ;set correction +2 mks goto SetCorrection goto RestoreIntFlag SetCorrection: movlw 0x7e ;~4 mks after start call IRDelay ;delay 126*3-1+5=382 mks nop nop bsf STATUS,C ;this STOP bit will end the loop NextDigit: rrf Dig8,F rrf Dig7,F rrf Dig6,F rrf Dig5,F rrf Dig4,F rrf Dig3,F rrf Dig2,F rrf Dig1,F btfsc STATUS,C ;check for STOP bit goto Compare bsf AlarmFlags,NullFlag ;Set the null flag RetryDigit: bcf AlarmFlags,IRFlag ;1 mks Reset bit read flag nop nop nop btfsc PORTB,IRInp ;5th mks look for a bit bsf AlarmFlags,IRFlag ;Set if bit read movlw 0x05 movwf IRCount StartCorrection: ;Delay 35+IRCorrection mks movf IRCount,W ;for T=400 mks delay 38 mks subwf IRCorrection,W btfsc STATUS,C goto AddCorrection AddCorrection: decfsz IRCount,F goto StartCorrection nop movlw 0x6e call IRDelay ;Delay 110*3-1+5=334 mks btfss AlarmFlags,IRFlag goto ResetFlag btfsc AlarmFlags,NullFlag ;If flag is clear it was "1" goto Set0 nop bsf STATUS,C ;Set an overflow flag to read "1" goto NextDigit Set0: bcf STATUS,C ;Reset an overflow flag to read "0" goto NextDigit ResetFlag: movlw 0x02 call IRDelay ;Delay 2*3-1+5=10 mks btfss AlarmFlags,NullFlag ;Error if an overflow flag already reset goto RestoreIntFlag bcf AlarmFlags,NullFlag goto RetryDigit Compare: nop ;401th mks nop nop nop btfsc PORTB,IRInp ;405th mks watch for clear bit goto RestoreIntFlag movlw 0x05 movwf IRCount StartCorrection1: ;Delay 35+IRCorrection mks movf IRCount,W ;for T=400 mks delay 38 mks subwf IRCorrection,W btfsc STATUS,C goto AddCorrection1 AddCorrection1: decfsz IRCount,F goto StartCorrection1 nop movlw PASS8 xorwf Dig8,W btfss STATUS,Z goto BadCode movlw PASS7 xorwf Dig7,W btfss STATUS,Z goto BadCode movlw PASS6 xorwf Dig6,W btfss STATUS,Z goto BadCode movlw PASS5 xorwf Dig5,W btfss STATUS,Z goto BadCode movlw PASS4 xorwf Dig4,W btfss STATUS,Z goto BadCode movlw PASS3 xorwf Dig3,W btfss STATUS,Z goto BadCode movlw PASS2 xorwf Dig2,W btfss STATUS,Z goto BadCode movf Dig1,W andlw b'00001111' xorlw PASS1 btfss STATUS,Z goto BadCode movlw 0x6a ;480 mks call IRDelay ;delay 106*3-1+5=322 mks nop nop btfsc PORTB,IRInp ;805 mks goto RestoreIntFlag movlw 0x05 movwf IRCount StartCorrection2: ;Delay 35+IRCorrection mks movf IRCount,W ;for T=400 mks delay 38 mks subwf IRCorrection,W btfsc STATUS,C goto AddCorrection2 AddCorrection2: decfsz IRCount,F goto StartCorrection2 nop movlw 0x75 call IRDelay ;delay 117*3-1+5=355 mks nop nop btfss PORTB,IRInp ;5th mks look for a STOP bit goto RestoreIntFlag movlw b'11000000' andwf Dig1,W btfsc STATUS,Z goto RestoreIntFlag iorwf AlarmFlags,F ;Save a valid function (ON/OFF) btfss AlarmFlags,ON_Flag goto TestOFF btfss PORTA,AlarmSW goto SetBeep ;Toggle beep flag bcf AlarmFlags,OFF_Flag ;ON flag has the highest priority goto SetAlarm TestOFF: btfss AlarmFlags,OFF_Flag goto RestoreIntFlag btfsc PORTA,AlarmSW goto SetBeep ;Toggle beep flag movlw 0x32 ;Set 50 ms delay call SystemAlarm ;Beep and Lights for 100 ms bsf PORTB,Lock ;Set an open door relay movlw 0xff call Delay ;wait for 512 ms call Delay btfss AlarmFlags,AlarmFlag ;Another alarm if intrusion flag was set goto SetAlarm movlw 0x32 ;Set 50 ms delay call SystemAlarm movlw 0xff call Delay ;wait for 512 ms call Delay SetAlarm: movlw 0x32 ;Set 50 ms delay call SystemAlarm movlw 0x03 movwf IRCount ;Set 3 attempts to switch a distance relay RetrySetAlarm: bsf PORTA,Relay movlw 0xc8 call Delay ;wait for 200 ms btfsc AlarmFlags,ON_Flag bsf PORTB,AlarmON btfsc AlarmFlags,OFF_Flag bsf PORTB,AlarmOFF call Delay ;wait for 200 ms bcf PORTA,Relay call Delay ;wait for 200 ms bcf PORTB,AlarmON bcf PORTB,AlarmOFF btfss AlarmFlags,ON_Flag goto WatchOFF btfss PORTA,AlarmSW goto Main goto WatchDone WatchOFF: btfsc PORTA,AlarmSW goto Main WatchDone: movlw 0xff call Delay ;wait for 512 ms call Delay decfsz IRCount,F goto RetrySetAlarm goto Main SetBeep: movlw b'00000001' ;toggle beep flag xorwf AlarmFlags,F movlw 0x64 ;set delay for 100 ms call SystemAlarm movlw b'00111111' andwf AlarmFlags,F ;reset ON and OFF flags goto RestoreIntFlag BadCode: bsf AlarmFlags,IntrusionFlag ;Set an intrusion flag for bad code RestoreIntFlag: bcf PORTB,Lock ;Turn off the open lock relay bcf INTCON,INTF WatchSwitch: btfss INTCON,RBIF goto RestoreStatus movf PORTB,W ;read switches bcf INTCON,RBIF ;reset flag andlw b'11110000' btfsc STATUS,Z ;all switches open goto RestoreStatus movlw 0x1e call Delay movf PORTB,W ;read switches again bcf INTCON,RBIF ;reset flag andlw b'11110000' btfsc STATUS,Z ;a less than 30 ms pulse was detected goto RestoreStatus bsf AlarmFlags,IntrusionFlag ;Set an intrusion if some switches closed RestoreStatus: movf TempSTATUS,W ;Restore W and STATUS movwf STATUS movf TempW,W retfie ; ------------ S U B R O U T I N E S ------------- Delay ;W mks delay with 4MHz oscilator movwf DelayCountHi clrf DelayCountLow DelayLoop: nop incfsz DelayCountLow,F goto DelayLoop decfsz DelayCountHi,F goto DelayLoop return IRDelay movwf IRCount ;delay W*3-1+5 mks DelayStart: decfsz IRCount,F goto DelayStart return SystemAlarm btfss AlarmFlags,BeepFlag bsf PORTA,Beep bsf PORTA,Lights call Delay call Delay bcf PORTA,Beep bcf PORTA,Lights return ; ------------ M A I N ------------- Start: clrf PORTA clrf PORTB clrf EEDATA clrf EEADR clrf AlarmFlags bsf STATUS,RP0 ;set bank 1 movlw b'00010000' ;Port A movwf TRISA movlw b'11110001' ;Port B movwf TRISB movlw b'11111111' ;disable pull-up movwf OPTION_REG bcf STATUS,RP0 ;set bank 0 Main: clrf PORTA ;clear Port A movlw b'00000001' andwf AlarmFlags,F ;Reset everything but BeepFlag btfss PORTA,AlarmSW goto ON_Set goto OFF_Set OFF_Set: movlw b'10010000' ;enable interrupts movwf INTCON OFF_Loop: goto OFF_Loop ON_Set: movlw 0x0a movwf Count ;set alarm count for 10 movlw b'10011000' ;enable interrupts movwf INTCON bsf INTCON,RBIF ;watch switches ON_Loop: movlw 0x64 ;Make LED blink twice per second bsf PORTA,LED btfsc AlarmFlags,IntrusionFlag goto Intrusion call Delay bcf PORTA,LED call Delay bsf PORTA,LED btfsc AlarmFlags,IntrusionFlag goto Intrusion call Delay bcf PORTA,LED movlw 0xff call Delay call Delay movlw 0xbc call Delay goto ON_Loop Intrusion: bcf INTCON,RBIE ;disable switch interrupt bsf AlarmFlags,AlarmFlag ;save intrusion bcf AlarmFlags,DelayFlag btfsc PORTB,HiJackSW bsf AlarmFlags,DelayFlag movlw 0xfa call SystemAlarm btfss PORTB,HiJackSW bcf AlarmFlags,DelayFlag btfss AlarmFlags,BeepFlag bsf PORTA,Beep call Delay bcf PORTA,Beep btfss PORTB,HiJackSW goto SkipHiJack btfss AlarmFlags,DelayFlag goto SkipHiJack bsf AlarmFlags,OFF_Flag goto TestOFF SkipHiJack: call Delay decfsz Count,F goto Intrusion bcf AlarmFlags,IntrusionFlag ;clear intrusion flag goto ON_Set org 0x3ff goto Start ;Restart if got here end