include __config _XT_OSC & _WDT_OFF & _PWRTE_ON ;====Security Doorbell===== ;Author: Tim Hamel ;Date: 12/20/00 ;Basic Operation: ;This little device will activate a relay when the correct ;code is entered in a morse-code fashion. ;====================== d1 equ 15 d2 equ 16 d3 equ 17 count equ 18 x equ 19 key equ 20 ;The key we use inp equ 21 ;the key the user entered tmr equ 22 z equ 24 mkcnt equ 23 r equ 25 org 0 goto main ;=====4mS Delay========= dly4 movlw 0x1c movwf d1 Delay_00 movlw 0x2e movwf d2 Delay_01 decfsz d2, f goto Delay_01 decfsz d1, f goto Delay_00 movlw 0x07 movwf d1 Delay_10 decfsz d1, f goto Delay_10 nop return ;======================= ;====20mS Delay -- Uses 4mS delay routine========= dly20 movlw .5 movwf tmr dly20a call dly4 decfsz tmr,1 goto dly20a return ;======================= ;=======Master-Key Programming Routine===== ; prgm bsf PORTB,0 ;Turn on LED btfsc PORTA,1 ;Debounce the PGM switch goto tstb call dly20 btfsc PORTA,1 ;Finishing up the debounce goto tstb goto gcode ;If in fact the PGM switch is pressed, ;enter programming mode. gcode call dly20 ;delay.... btfsc PORTA, 0 ;Was the enter switch pressed? goto tstt ;No... incf mkcnt,f ;Yes, increment counter ;each increment = 20mS goto gcode ;Do it all over tstt movf x,w ;x = 15, and 15 x 20mS = 300mS subwf mkcnt,w ;Simple compare routine btfsc STATUS, C ;If the Carry bit is clear, button < 300mS goto stone ;if the bit is set, button > 300mS rlf inp,f goto wt5s stone rlf inp,f ;Store a 1 wt5s movlw .5 ;wait 5 seconds for inactivity movwf r wt3 movlw .250 ;4mS delay is called 250 times to = 1S movwf tmr wait4 call dly4 btfsc PORTA,0 goto wait3 clrf mkcnt goto gcode wait3 decfsz tmr,1 goto wait4 decfsz r,1 goto wt3 movfw inp ;After 5 seconds of no button presses, ;we can assume the user is done ;storing the master-key movwf key clrf inp bcf PORTB,0 ;Turn off LED and exit programming mode. goto tstb ;======================= ;====Debounce Routine=== dbnc btfsc PORTA, 0 ;Test PORTA, bit 0, is it logic low? goto tstb ;No, line noise, return to testing. call dly20 ;Yes, delay for 20mS btfsc PORTA, 0 goto tstb ;Nope, false press..crazy button goto tmit ;Button held for > 20mS - it's valid ;======================= ;==Pulse-length timer==== ;Determines length of button press. ;=== tmit call dly20 ;Time the button press length btfsc PORTA, 0 goto test ;Time button release pulse-length incf count,f ;Increment counter, again, 20mS goto tmit ;======== tstb clrf count ;Just waiting for a button press here btfsc PORTA, 0 goto tsts goto dbnc tsts btfsc PORTA,1 ;Here, we're testing to see if the ;password program button is pressed goto tstb goto prgm main movlw .26 ;Not gonna happen, default to security movwf key movlw .15 ;This is the value that determines how ;long the pulse-length is. movwf x movlw 0 TRIS PORTB ;PORTB=Output clrf PORTB movlw 3 ;Make PORTA inputs, where the switches are tris PORTA goto tstb ;Same thing as up there ^^^, determine the button press ;pulse-length. I probably could've made this a "function" ;and just do a "call" instead of goto. test movf x,w subwf count,w btfsc STATUS, C goto isone rlf inp,f goto wait isone rlf inp,f wait movlw .250 ;Wait 1S after the last button press, ;if no presses, assume user is done movwf tmr wait2 call dly4 btfsc PORTA,0 goto wait1 goto tstb wait1 decfsz tmr,1 goto wait2 goto cmp cmp movf inp, w ;The "Master" algorithm! All we do is ;compare the input to the key, if they're ;equal, we turn on the LED (relay) xorwf key, w btfsc STATUS, Z goto bon ;If they're equal, clear the input ;register and turn on the LED. clrf inp ;If not, clear the input and start over... clrf count goto tstb ;The rest just turns on the LED (or relay) ;for 1 sec. Then we go back to square one bon clrf inp bsf PORTB,0 movlw .50 movwf z bon1 call dly20 decfsz z,1 goto bon1 bcf PORTB,0 goto tstb end