;***************************************************************
;* 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