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