;***************************************************************
;* Car Alarm System *
;* Power Relay & Central Lock *
;* Version 2 *
;* 1996 *
;***************************************************************
LIST P=PIC16C84, R=HEX
INCLUDE "f:\mpasm\include\p16C84.inc"
__CONFIG _XT_OSC & _WDT_OFF & _CP_OFF
;----- Port A bits -----
RelaySW equ 4
DoorLock equ 3
PowerOFF equ 2
PowerON equ 1
DoorUnlock equ 0
;----- Port B bits -----
CloseSW equ 5
OpenSW equ 4
DataIn equ 0
;----- PowerFlags bits -----
ON_Flag equ 7
OFF_Flag equ 6
LockFlag equ 5
UnlockFlag equ 4
DataFlag equ 3
NullFlag 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
DataCount equ 0x0f
PowerFlags equ 0x10
OldPowerFlags equ 0x11
TempW equ 0x12
TempSTATUS equ 0x13
DataCorrection equ 0x14
Dig1 equ 0x15
Dig2 equ 0x16
Dig3 equ 0x17
Dig4 equ 0x18
Dig5 equ 0x19
Dig6 equ 0x1a
Dig7 equ 0x1b
Dig8 equ 0x1c
;----- 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 DataCorrection ;reset correction
btfsc PORTB,DataIn ;set correction -3 mks
goto RestoreIntFlag
incf DataCorrection,F
btfsc PORTB,DataIn ;set correction -2 mks
goto SetCorrection
incf DataCorrection,F
btfsc PORTB,DataIn ;set correction -1 mks
goto SetCorrection
incf DataCorrection,F
btfsc PORTB,DataIn ;set correction 0 mks delay 3 mks
goto SetCorrection
incf DataCorrection,F
btfsc PORTB,DataIn ;set correction +1 mks
goto SetCorrection
incf DataCorrection,F
btfsc PORTB,DataIn ;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 PowerFlags,NullFlag ;Set the null flag
RetryDigit:
bcf PowerFlags,DataFlag ;1 mks Reset bit read flag
nop
nop
nop
btfsc PORTB,DataIn ;5th mks look for a bit
bsf PowerFlags,DataFlag ;Set if bit read
movlw 0x05
movwf DataCount
StartCorrection: ;Delay 35+DataCorrection mks
movf DataCount,W ;for T=400 mks delay 38 mks
subwf DataCorrection,W
btfsc STATUS,C
goto AddCorrection
AddCorrection:
decfsz DataCount,F
goto StartCorrection
nop
movlw 0x6e
call IRDelay ;Delay 110*3-1+5=334 mks
btfss PowerFlags,DataFlag
goto ResetFlag
btfsc PowerFlags,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 PowerFlags,NullFlag ;Error if an overflow flag already reset
goto RestoreIntFlag
bcf PowerFlags,NullFlag
goto RetryDigit
Compare:
nop ;401th mks
nop
nop
nop
btfsc PORTB,DataIn ;405th mks watch for clear bit
goto RestoreIntFlag
movlw 0x05
movwf DataCount
StartCorrection1: ;Delay 35+DataCorrection mks
movf DataCount,W ;for T=400 mks delay 38 mks
subwf DataCorrection,W
btfsc STATUS,C
goto AddCorrection1
AddCorrection1:
decfsz DataCount,F
goto StartCorrection1
nop
movlw PASS8
xorwf Dig8,W
btfss STATUS,Z
goto RestoreIntFlag
movlw PASS7
xorwf Dig7,W
btfss STATUS,Z
goto RestoreIntFlag
movlw PASS6
xorwf Dig6,W
btfss STATUS,Z
goto RestoreIntFlag
movlw PASS5
xorwf Dig5,W
btfss STATUS,Z
goto RestoreIntFlag
movlw PASS4
xorwf Dig4,W
btfss STATUS,Z
goto RestoreIntFlag
movlw PASS3
xorwf Dig3,W
btfss STATUS,Z
goto RestoreIntFlag
movlw PASS2
xorwf Dig2,W
btfss STATUS,Z
goto RestoreIntFlag
movf Dig1,W
andlw b'00001111'
xorlw PASS1
btfss STATUS,Z
goto RestoreIntFlag
movlw 0x6a ;480 mks
call IRDelay ;delay 106*3-1+5=322 mks
nop
nop
btfsc PORTB,DataIn ;805 mks
goto RestoreIntFlag
movlw 0x05
movwf DataCount
StartCorrection2: ;Delay 35+DataCorrection mks
movf DataCount,W ;for T=400 mks delay 38 mks
subwf DataCorrection,W
btfsc STATUS,C
goto AddCorrection2
AddCorrection2:
decfsz DataCount,F
goto StartCorrection2
nop
movlw 0x75
call IRDelay ;delay 117*3-1+5=355 mks
nop
nop
btfss PORTB,DataIn ;5th mks look for a STOP bit
goto RestoreIntFlag
movlw b'11000000'
andwf Dig1,W
btfsc STATUS,Z
goto RestoreIntFlag
iorwf PowerFlags,F ;Save a valid function (ON/OFF)
clrf PORTA
btfss PowerFlags,ON_Flag
goto TestOFF
btfsc PORTA,RelaySW
goto RestoreIntFlag
TestOFF:
btfss PowerFlags,OFF_Flag
goto TestDone
bcf PowerFlags,ON_Flag ;OFF_Flag has the highest priority
btfss PORTA,RelaySW
goto RestoreIntFlag
TestDone:
movlw 0x03
movwf DataCount ;Set 3 attempts to switch a distance relay
RetrySetPower:
movlw 0xff
btfsc PowerFlags,ON_Flag
bsf PORTA,DoorUnlock
btfsc PowerFlags,OFF_Flag
bsf PORTA,DoorLock
call Delay ;wait for 256ms
btfsc PowerFlags,ON_Flag
bsf PORTA,PowerON
btfsc PowerFlags,OFF_Flag
bsf PORTA,PowerOFF
call Delay ;wait for 256ms
clrf PORTA
btfss PowerFlags,ON_Flag
goto WatchOFF
btfsc PORTA,RelaySW
goto RestoreIntFlag
goto RelayNotSet
WatchOFF:
btfss PORTA,RelaySW
goto RestoreIntFlag
RelayNotSet:
movlw 0xff
call Delay ;wait for 512ms
call Delay
decfsz DataCount,F
goto RetrySetPower
RestoreIntFlag:
bcf INTCON,INTF
movf PORTB,F
goto RestoreStatus
WatchSwitch:
btfss INTCON,RBIF
goto RestoreStatus
comf PORTB,W ;read switches
bcf INTCON,RBIF ;reset flag
andlw b'00110000'
btfsc STATUS,Z ;all switches open
goto RestoreStatus
movlw 0x64
call Delay
comf PORTB,W ;read switches again
bcf INTCON,RBIF ;reset flag
andlw b'00110000'
btfsc STATUS,Z ;a less than 100 ms pulse was detected
goto RestoreStatus
xorlw b'00110000'
btfsc STATUS,Z
goto RestoreStatus
xorlw b'00110000'
iorwf PowerFlags,F ;Save a valid function (Lock/Unlock)
xorwf OldPowerFlags,W
btfsc STATUS,Z
goto RestoreStatus
btfss PORTA,RelaySW
goto RestoreStatus
movlw 0xff
btfsc PowerFlags,UnlockFlag
bsf PORTA,DoorUnlock
btfsc PowerFlags,LockFlag
bsf PORTA,DoorLock
call Delay ;wait for 512ms
call Delay
clrf PORTA
movf PowerFlags,W
movwf OldPowerFlags
RestoreStatus:
bcf INTCON,RBIF
clrf PowerFlags
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 DataCount ;delay W*3-1+5 mks
DelayStart:
decfsz DataCount,F
goto DelayStart
return
; ------------ M A I N -------------
Start:
clrf PORTA
clrf PORTB
clrf EEDATA
clrf EEADR
clrf PowerFlags
clrf OldPowerFlags
bsf STATUS,RP0 ;set bank 1
movlw b'00010000' ;Port A
movwf TRISA
movlw b'11111111' ;Port B
movwf TRISB
movlw b'11111111' ;disable pull-up
movwf OPTION_REG
bcf STATUS,RP0 ;set bank 0
movf PORTB,F
movlw b'10011000' ;enable interrupts
movwf INTCON
Loop:
goto Loop
org 0x3ff
goto Start ;Restart if got here
end