;ALARM415.ASM 12DEC02 - COPYRIGHT JOHN BECKER - EPE INTRUDER ALARM ;PIC16F877-4, 3.2768MHz, WDT OFF, POR ON, XTAL XS ;Config register bits ; CP1 CP0 DBG NIL WRT CPD LVP BOR CP1 CP0 POR WDT OS1 OS0 ; 1 1 1 1 1 1 0 0 1 1 0 0 0 1 ;N.B. Logic 1/0 do NOT necessarily mean that the function is On/Off ;respectively - refer to PIC '87 data sheet. ;#include #DEFINE PAGE0 BCF 0x03,5 #DEFINE PAGE1 BSF 0x03,5 List P = PIC16F877, R=DEC; __CONFIG 3F31h INDF: EQU 0x00 ;page 0, 1, 2, 3 OPTIONR: EQU 0x01 ;page 1, 3 PCL: EQU 0x02 ;page 0, 1, 2, 3 STATUS: EQU 0x03 ;page 0, 1, 2, 3 FSR: EQU 0x04 ;page 0, 1, 2, 3 PORTA: EQU 0x05 ;page 0 TRISA: EQU 0x05 ;page 1 PORTB: EQU 0x06 ;page 0, 2 TRISB: EQU 0x06 ;page 1, 3 PORTC: EQU 0x07 ;page 0 TRISC: EQU 0x07 ;page 1 PORTD: EQU 0x08 ;page 0 TRISD: EQU 0x08 ;page 1 PORTE: EQU 0x09 ;page 0 TRISE: EQU 0x09 ;page 1 PCLATH: EQU 0x0A ;page 0, 1, 2, 3 INTCON: EQU 0x0B ;page 0, 1, 2, 3 EEDATA: EQU 0x0C ;page 2 EECON1: EQU 0x0C ;page 3 PIR2: EQU 0x0D ;page 0 EEADR: EQU 0x0D ;page 2 EECON2: EQU 0x0D ;page 3 ADCON1: EQU 0x1F ;page 1 SLOWIT: EQU 0x20 ; pause counter CLKCNT: EQU 0x21 CLKSEC: EQU 0x22 CLKMIN: EQU 0x23 CLKHRS: EQU 0x24 LOOP: EQU 0x25 LOOPA: EQU 0x26 RSLINE: EQU 0x27 STORE: EQU 0x28 STORE1: EQU 0x29 STORE2: EQU 0x2A STORE3: EQU 0x2B ZONESVAL: EQU 0x2C ; current val of zones status ALARMSTATUS: EQU 0x2D ; controls the following: ; bit 0 buzzer ; bit 1 strobe ; bit 2 bell ; bit 3 - ; bit 4 Panic flag ; bit 5 passive entry zone (just turns on buzzer when entered) ; bit 6 power interrupt flag ; bit 7 alarm on flag SWITCH1: EQU 0x2E ; multiplex val for rows SWVAL: EQU 0x2F ; input val from RB0-RB3 COL: EQU 0x30 ; column counter (inc in decimal) ROW: EQU 0x31 ; row counter (inc as matrix val) ROWNUM: EQU 0x32 ; row counter (inc in decimal) ALARMZONE: EQU 0x33 ; holds status of which zone triggered KEYPRESS: EQU 0x34 ; value of key pressed keypad1 PIN0: EQU 0x35 ; 1st pin number val FIRST KEYPAD PIN1: EQU 0x36 ; 2nd pin number val PIN2: EQU 0x37 ; 3rd pin number val PIN3: EQU 0x38 ; 4th pin number val EXITTIME: EQU 0x39 ; entry/exit delay EXITZONE: EQU 0x3A ; entry/exit zone INCLZONE: EQU 0x3B ; zones to be included in monitoring BELLTIME EQU 0x3C ; bell on time value in BCD mins FLASH: EQU 0x3D ; flag for flashing buzzer LED when zone incorrectly open during alarm setting ZONENORMAL: EQU 0x3E ; normal zone logic ENGINEERSET: EQU 0x3F ; flag to indicate if ENGINEER has been called PREVALARMZONE EQU 0x40 ; previous alarm condition register ENTRYDELAY: EQU 0x41 ; counter for entry/exit delay PIN4: EQU 0x42 ; 1st pin number val FOR 2ND KEYPAD PIN5: EQU 0x43 ; 2nd pin number val PIN6: EQU 0x44 ; 3rd pin number val PIN7: EQU 0x45 ; 4th pin number val KEYPRESS2: EQU 0x46 ; value of key pressed keypad2 ENTRYTIME2: EQU 0x47 ; entry time for keypad2 ENTRYDELAY2: EQU 0x48 ; counter for keypad2 entry delay CLKCNT2: EQU 0x49 STORED EQU 0x4A ; temp store for keypad2 COUNT0 EQU 0x50 ;lsb COUNT1 EQU 0x51 COUNT2 EQU 0x52 ;msb DIGIT1 EQU 0x53 ;lsd DIGIT2 EQU 0x54 BITCNT EQU 0x5B DIGCNT EQU 0x5C STOREX: EQU 0x60 STOREY: EQU 0x61 ; locations up to $7F are available ;************************************************************ ; Bit Definitions ;************************************************************ W: EQU 0 F: EQU 1 C: EQU 0 DC: EQU 1 Z: EQU 2 RP0: EQU 5 ;STATUS reg RP1: EQU 6 ;STATUS reg GIE: EQU 7 ;INTCON reg RD: EQU 0 ;EECON1 reg eeprom read enable flag WR: EQU 1 ;EECON1 reg eeprom write initiate flag WREN: EQU 2 ;EECON1 reg eeprom write enable flag EEPGD: EQU 7 ;EECON1 reg EEIF: EQU 4 ;PIR2 reg BUZZER: EQU 0 STROBE: EQU 1 BELL: EQU 2 PANIC: EQU 4 RBIF: EQU 0 ;............. DATA EEPROM USE ; 0-3 PIN CODE ; 4 ZONES EXCLUDED ; 5 ENTRY/EXIT ZONE ; 6 ENTRY/EXIT DELAY ; 7 ZONES INTRUDED (AlarmZone) ; 8 ALARM ON/OFF & BELL, BUZZER, STROBE STATUS (AlarmStatus) ; 9 BELL ON TIME (MAX 15 MINS) ; 10 NORMAL ZONE STATUS ; 11-14 2ND PIN CODE ; 15 ENTRY DELAY VIA KEYPAD2 ORG 0x0004 ;Interrupt vector address GOTO GIEOFF ;Jump to interrupt routine on interrupt ORG 0x0005 ;Start of program memory GIEOFF: BCF INTCON,GIE ;turn off global interrupts BTFSC INTCON,GIE goto GIEOFF goto START TABLCD: addwf PCL,F ;LCD initialisation table retlw b'00110011' ;initialise lcd - first byte retlw b'00110011' ;2nd byte (repeat of first) retlw b'00110010' ;set for 4-bit operation retlw b'00101100' ;set for 2 lines retlw b'00000110' ;set entry mode to increment each address retlw b'00001100' ;set display on, cursor off, blink off retlw b'00000001' ;clear display retlw b'00000010' ;return home, cursor & RAM to zero ;end inititalisation table ALLOFF: addwf PCL,F retlw 'A' retlw 'L' retlw 'L' retlw ' ' retlw 'O' retlw 'F' retlw 'F' retlw ' ' MESSAGON: addwf PCL,F retlw 'A' retlw 'L' retlw 'A' retlw 'R' retlw 'M' retlw ' ' retlw 'O' retlw 'N' retlw ' ' MESSAG2: addwf PCL,F retlw ' ' retlw ' ' retlw 'E' retlw 'N' retlw 'T' retlw 'R' retlw 'Y' retlw ' ' CHKVAL: addwf PCL,F retlw b'01011001' ;59 secs max retlw b'01011001' ;59 mins max retlw b'00100011' ;23 hours max VALUE: ADDWF PCL,F ;lookup table for key allocation retlw '1' retlw '2' retlw '3' retlw 'A' retlw '4' retlw '5' retlw '6' retlw 'B' retlw '7' retlw '8' retlw '9' retlw 'C' retlw '-' retlw '0' retlw 'E' retlw 'D' BITVALUE: ADDWF PCL,F ;lookup table for decimal to bit conversion retlw 0 retlw 1 retlw 2 retlw 4 retlw 8 retlw 16 retlw 32 retlw 64 retlw 128 PINCODE: ADDWF PCL,F ; change pin code message retlw 'C' retlw 'H' retlw 'A' retlw 'N' retlw 'G' retlw 'E' retlw ' ' retlw 'P' retlw 'I' retlw 'N' retlw ' ' retlw 'C' retlw 'O' retlw 'D' retlw 'E' retlw ' ' PIN2MSG: ADDWF PCL,F ; change 2ND pin code message retlw 'S' retlw 'E' retlw 'T' retlw ' ' retlw '2' retlw 'N' retlw 'D' retlw ' ' retlw 'P' retlw 'I' retlw 'N' retlw ' ' retlw 'C' retlw 'O' retlw 'D' retlw 'E' ENTRYTIME: ADDWF PCL,F ; change ENTRY/EXIT time message retlw 'S' retlw 'E' retlw 'T' retlw ' ' retlw 'I' retlw 'N' retlw '/' retlw 'O' retlw 'U' retlw 'T' retlw ' ' retlw 'T' retlw 'I' retlw 'M' retlw 'E' retlw ' ' BELLTIMEMSG: ADDWF PCL,F ; change ENTRY/EXIT time message retlw 'S' retlw 'E' retlw 'T' retlw ' ' retlw 'B' retlw 'E' retlw 'L' retlw 'L' retlw ' ' retlw 'O' retlw 'N' retlw ' ' retlw 'T' retlw 'I' retlw 'M' retlw 'E' ENTRYZONE: ADDWF PCL,F ; set ENTRY/EXIT zone message retlw 'S' retlw 'E' retlw 'T' retlw ' ' retlw 'I' retlw 'N' retlw '/' retlw 'O' retlw 'U' retlw 'T' retlw ' ' retlw 'Z' retlw 'O' retlw 'N' retlw 'E' retlw ' ' MODEMSG: ADDWF PCL,F ; mode message retlw 'S' retlw 'E' retlw 'L' retlw 'E' retlw 'C' retlw 'T' retlw ' ' retlw 'M' retlw 'O' retlw 'D' retlw 'E' retlw ' ' retlw ' ' retlw ' ' retlw ' ' retlw ' ' WATCHMSG: ADDWF PCL,F ; zones to be watched message retlw 'S' retlw 'E' retlw 'T' retlw ' ' retlw 'W' retlw 'A' retlw 'T' retlw 'C' retlw 'H' retlw ' ' retlw 'Z' retlw 'O' retlw 'N' retlw 'E' retlw 'S' retlw ' ' OPENZONE: ADDWF PCL,F ; zones incorrectly open when alarm is being set retlw 'C' retlw 'H' retlw 'E' retlw 'C' retlw 'K' retlw ' ' retlw 'O' retlw 'P' retlw 'E' retlw 'N' retlw ' ' retlw 'Z' retlw 'O' retlw 'N' retlw 'E' retlw 'S' ZONELOGIC: ADDWF PCL,F ; assess zone logic message (i.e normally open or normally closed) retlw 'A' retlw 'U' retlw 'T' retlw 'O' retlw ' ' retlw 'Z' retlw 'O' retlw 'N' retlw 'E' retlw ' ' retlw 'A' retlw 'S' retlw 'S' retlw 'E' retlw 'S' retlw 'S' SHOWLOGIC: ADDWF PCL,F ; assess zone logic message (i.e normally open or normally closed) retlw 'N' retlw 'O' retlw 'R' retlw 'M' retlw ' ' retlw 'Z' retlw 'O' retlw 'N' retlw 'E' retlw ' ' retlw 'L' retlw 'O' retlw 'G' retlw 'I' retlw 'C' retlw ' ' PASSIVEMSG: ADDWF PCL,F ; passive alarm message retlw 'M' retlw 'O' retlw 'N' retlw 'I' retlw 'T' retlw 'O' retlw 'R' retlw ' ' START: bcf STATUS,RP0 bcf STATUS,RP1 clrf PORTA clrf PORTB clrf PORTC clrf PORTD clrf PORTE PAGE1 movlw b'11011111' ;RB0-RB4, RB6-RB7 as input, RB5 as output movwf TRISB movlw b'00001111' ;RC0-RC3 as input, RC4-RC7 as output movwf TRISC movlw 255 movwf TRISD ;PORTD as input clrf TRISE ;PORTE as output movlw b'00000111' ;PORT A/E as digital movwf ADCON1 ; movlw b'11000000' ;RA0-RA5 as outputs movwf TRISA movlw b'00000110' ;timer 1:128 (1/25th sec) movwf OPTIONR PAGE0 clrf INTCON call PAUSIT ;1/5 sec delay LCDSET: clrf LOOP ;clr LCD set-up loop clrf RSLINE ;clear RS line for instruction send LCDST2: movf LOOP,W ;get table address call TABLCD ;get set-up instruction call LCDOUT ;perform it incf LOOP,F ;inc loop btfss LOOP,3 ;has last LCD set-up instruction now been done? goto LCDST2 ;no call PAUSIT ;1/5 sec delay clrf ENGINEERSET bsf ALARMSTATUS,6 ; set Power interruption flag call KEYPAD1 ; is ENGINEER code to be entered following power-up movf KEYPRESS,W ; with key 'D' pressed? xorlw 'D' btfss STATUS,Z goto SETCLK ; no clrf ALARMZONE clrf ALARMSTATUS bsf ENGINEERSET,0 bcf ALARMSTATUS,6 ; clear Power interruption flag movlw b'10000001' ; default set INCLZONE for zones 1 & 8 movwf STORE1 movlw 4 call SETPRM movlw b'00000001' ; default set entry/exit zone movwf STORE1 movlw 5 call SETPRM movlw 30 ; default set EXITTIME to 30 secs in binary movwf STORE1 movlw 6 call SETPRM clrf STORE1 ; default clear INTRUDED status movlw 7 call SETPRM clrf PORTE clrf STORE1 ; default clear ALARMSTATUS (bell etc) bcf STORE1,BELL movlw 8 call SETPRM movlw b'00010101'; default set bell switch-off time to 15 mins in BCD movwf STORE1 movlw 9 call SETPRM movlw b'00000000' ; default set for "normal" zone status - all open movwf STORE1 movlw 10 call SETPRM movlw 30 ; default set ENTRYTIME to 30 secs in binary for keypad2 movwf STORE1 movlw 15 call SETPRM call ENGINEER ; yes, set ENGINEER entry code and reset all defaults SETCLK: clrf CLKSEC ;clear seconds counter clrf CLKMIN ;clear minutes counter clrf CLKHRS ;clear hours counter clrf PREVALARMZONE clrf ENTRYDELAY clrf ENTRYDELAY2 movlw 25 ;initial basic CLKCNT val for secs timing movwf CLKCNT movlw 0 ; RECALL PIN CODE call PRMGET movwf PIN0 movlw 1 call PRMGET movwf PIN1 movlw 2 call PRMGET movwf PIN2 movlw 3 call PRMGET movwf PIN3 movlw 4 ; RECALL INCLUDED/EXCLUDED ZONES call PRMGET movwf INCLZONE bsf INCLZONE,7 ; ensure bit 7 (1st PANIC zone) is always on movlw 5 ; RECALL ENTRY/EXIT ZONE call PRMGET movwf EXITZONE movlw 6 ; RECALL ENTRY/EXIT TIME call PRMGET movwf EXITTIME movlw 7 ; RECALL ALARMZONE STATUS call PRMGET movwf ALARMZONE movlw 8 ; RECALL ALARMSTATUS STATUS call PRMGET movwf ALARMSTATUS ; and activate buzzer/strobe if needed (but not bell) andlw b'00000011' movwf PORTE movlw 9 ; RECALL BELL ON TIME call PRMGET movwf BELLTIME movlw 10 ; RECALL "NORMAL ZONE STATUS call PRMGET movwf ZONENORMAL movlw 11 ; RECALL PIN CODE 2 call PRMGET movwf PIN4 movlw 12 call PRMGET movwf PIN5 movlw 13 call PRMGET movwf PIN6 movlw 14 call PRMGET movwf PIN7 movlw 15 ; RECALL ENTRY TIME FOR KEYPAD2 call PRMGET movwf ENTRYTIME2 btfss ALARMSTATUS,7 ; is alarm on? goto ITSOFF call CHECKZONE2 bsf ALARMSTATUS,6 ; set Power interruption flag goto MAIN ITSOFF: call ALARMOFF ; show ALARM OFF message btfsc ENGINEERSET,0 ; has ENGINEER been called? goto MAIN ;yes call LCD21 ;set address for line 1 cell 1 bsf RSLINE,4 ;set RS for data send movlw 'P' call LCDOUT movlw 'O' call LCDOUT movlw 'W' call LCDOUT movlw 'E' call LCDOUT movlw 'R' call LCDOUT movlw ' ' call LCDOUT movlw 'E' call LCDOUT movlw 'R' call LCDOUT movlw 'R' call LCDOUT movlw 'O' call LCDOUT movlw 'R' call LCDOUT clrf ENGINEERSET ; clear ENGINEER flag ;............................ END OF SETUP MAIN: call CHECKMODE call PINENTRY2 movf ENTRYDELAY2,W ; has entry2 delay timed out? btfss STATUS,Z call CONTINUEENTRY2 ; no, continue countdown of entry2 goto MAIN ALARMISON: btfss ALARMSTATUS,7 ; is alarm on ? return ; no call MONITOR ; get current status of zones 1-8 call CHECKZONE ; compare current and preset zones status call SETBELLS call CLKIN return PASSIVEALARM: call MONITOR ; get current status of zones 1-8 call CHECKZONE ; compare current and preset zones status movf ZONESVAL,W btfss STATUS,Z goto PAS1 bcf PORTE,BUZZER goto PAS2 PAS1: bsf PORTE,BUZZER PAS2: call LCD21 ;set address for line 1 cell 1 bsf RSLINE,4 ;set RS for data send movf ZONESVAL,W movwf STORE1 ; store INTRUDED status call SHOWZONE return ;******* CHECK MODE CHECKMODE: call KEYPAD1 ; is key pressed? movf KEYPRESS,W btfsc STATUS,Z return ; no, so return CHECKM2: call WAITKEYPRESS movf KEYPRESS,W ; is keypress = pin number? xorwf PIN0,W btfss STATUS,Z return call WAITKEYRELEASE call WAITKEYPRESS movf KEYPRESS,W ; is keypress = pin number? xorwf PIN1,W btfss STATUS,Z return call WAITKEYRELEASE call WAITKEYPRESS movf KEYPRESS,W ; is keypress = pin number? xorwf PIN2,W btfss STATUS,Z return call WAITKEYRELEASE call WAITKEYPRESS movf KEYPRESS,W ; is keypress = pin number? xorwf PIN3,W btfss STATUS,Z return goto AMENDMODE ; yes ;*********** AMEND MODE ********** AMENDMODE: clrf PORTE ; turn off bell, buzzer, strobe btfss ALARMSTATUS,7 ; is alarm already in alarm mode? goto AMEND0 ; no goto AMEND2 AMEND0: call LCD1 ;set address for line 1 cell 1 bsf RSLINE,4 ;set RS for data send clrf LOOP ;clear loop bsf RSLINE,4 ;set RS for data send AMEND1: movf LOOP,W ;get table address call MODEMSG ;get message letter call LCDOUT ;show it incf LOOP,F ;inc loop btfss LOOP,4 ;has last LCD letter been sent? goto AMEND1 ;no call CLRLINE2 AMEND2: clrf ALARMSTATUS clrf ALARMZONE clrf PREVALARMZONE call WAITKEYRELEASE call WAITKEYPRESS movf KEYPRESS,W ; is keypress = '0' - alarm on? xorlw '0' btfsc STATUS,Z goto ALARMON ; yes, so set alarm on and exit CHECK12: movf KEYPRESS,W ; is keypress = '-' - cancel? xorlw '-' btfsc STATUS,Z goto ALARMOFF ; general return to normal off status CHECK0: movf KEYPRESS,W ; is keypress = '1' - change PIN code? xorlw '1' btfss STATUS,Z goto CHECK1 call ENGINEER goto AMEND0 CHECK1: movf KEYPRESS,W ; is keypress = '2' - change ENTRY/EXIT time? xorlw '2' btfss STATUS,Z goto CHECK2 call CHANGEENTRY goto AMEND0 CHECK2: movf KEYPRESS,W ; is keypress = '3' - change ENTRY/EXIT ZONE? xorlw '3' btfss STATUS,Z goto CHECK3 call SETENTRY goto AMEND0 CHECK3: movf KEYPRESS,W ; is keypress = '4' - select zones to monitored? xorlw '4' btfss STATUS,Z goto CHECK4 call SETMONITOR goto AMEND0 CHECK4: movf KEYPRESS,W ; is keypress = '5' - select bell on time (max 15 mins) xorlw '5' btfss STATUS,Z goto CHECK5 call SETBELLTIME goto AMEND0 CHECK5: movf KEYPRESS,W ; is keypress = '6' - assess normal zone logic xorlw '6' btfss STATUS,Z goto CHECK6 call ASSESSLOGIC goto AMEND0 CHECK6: movf KEYPRESS,W ; is keypress = '7' - preset normal zone logic xorlw '7' btfss STATUS,Z goto CHECK7 call PRESETLOGIC goto AMEND0 CHECK7: movf KEYPRESS,W ; is keypress = '8' - set 2nd pin code xorlw '8' btfss STATUS,Z goto CHECK8 call PINCODE2 goto AMEND0 CHECK8: movf KEYPRESS,W ; is keypress = '9' - change ENTRY time for keypad2 ? xorlw '9' btfss STATUS,Z goto CHECK14 call CHANGEENTRY2 goto AMEND0 CHECK14: movf KEYPRESS,W ; is keypress = '.' (coded 'E') - buzzer only monitor of entries xorlw 'E' btfss STATUS,Z goto CHECK15 goto SETPASSIVE CHECK15: goto AMEND2 ; ******** PASSIVE MODE SETPASSIVE: call LCD1 ;set LCD for line 1, cell 1 bsf RSLINE,4 ;set LCD RS line high clrf LOOP ;clear loop SETP2: movf LOOP,W ;get table address call PASSIVEMSG ;get message letter call LCDOUT ;show it incf LOOP,F ;inc loop btfss LOOP,3 ;has last LCD letter been sent? goto SETP2 ;no movlw 'M' call LCDOUT movlw '0' call LCDOUT movlw 'D' call LCDOUT movlw 'E' call LCDOUT bsf ALARMSTATUS,5 return ;********* CHANGE ENTRY/EXIT TIME CHANGEENTRY: call LCD1 ;set LCD for line 1, cell 1 bsf RSLINE,4 ;set LCD RS line high clrf LOOP ;clear loop ENT2: movf LOOP,W ;get table address call ENTRYTIME ;get message letter call LCDOUT ;show it incf LOOP,F ;inc loop btfss LOOP,4 ;has last LCD letter been sent? goto ENT2 ;no call CLRLINE2 call LCD23 ;set LCD for line 2, cell 3 bsf RSLINE,4 ;set LCD RS line high movlw ' ' call LCDOUT movlw 'P' call LCDOUT movlw 'R' call LCDOUT movlw 'E' call LCDOUT movlw 'V' call LCDOUT movlw ' ' call LCDOUT movf EXITTIME,W movwf COUNT0 call BIN2DEC movf DIGIT2,W addlw 48 call LCDOUT movf DIGIT1,W addlw 48 call LCDOUT call LCD21 ;set LCD for line 2, cell 1 bsf RSLINE,4 ;set LCD RS line high call WAITKEYRELEASE ENT3: call WAITKEYPRESS ; get first value (tens) movf KEYPRESS,W ; is keypress = 12 - cancel? xorlw '-' btfsc STATUS,Z return ; yes btfsc KEYPRESS,6 ; is it >= 'A'? goto ENT3 ; yes, so try again movf KEYPRESS,W andlw b'00001111' movwf COUNT1 movwf COUNT2 movf KEYPRESS,W call LCDOUT call WAITKEYRELEASE ENT4: call WAITKEYPRESS ; get 2nd val (units) movf KEYPRESS,W ; is keypress = 12 - cancel? xorlw '-' btfsc STATUS,Z return ; yes btfsc KEYPRESS,6 ; is it >= 'A'? goto ENT4 ; yes, so try again movf KEYPRESS,W andlw b'00001111' movwf COUNT0 addwf COUNT1,W ; is total = 0? btfsc STATUS,Z goto ENT4 ; yes, so try again movf KEYPRESS,W call LCDOUT ENT5: call WAITKEYRELEASE call WAITKEYPRESS movf KEYPRESS,W xorlw 'D' ; is key = 15? - completion code number btfsc STATUS,Z goto ENT6 ; yes movf KEYPRESS,W xorlw '-' ; is key = 12? - error in number so start again btfss STATUS,Z goto ENT5 ; no goto CHANGEENTRY ; yes ENT6: call WAITKEYRELEASE bcf STATUS,C rlf COUNT1,F ; convert decimal to binary rlf COUNT1,F rlf COUNT1,W addwf COUNT2,W addwf COUNT2,W addwf COUNT0,W movwf EXITTIME movf EXITTIME,W movwf STORE1 movlw 6 call SETPRM call STORIT return ;********* MONITOR ZONES ********* MONITOR: swapf PORTC,W ; get RC0-RC3, store it as MS nibble andlw b'11110000' movwf ZONESVAL movf PORTD,W ; get RD0-RD3, store it as LS nibble andlw b'00001111' iorwf ZONESVAL,F return ; ********* compare current and preset zones status CHECKZONE: movf ENTRYDELAY2,W ; has entry2 delay timed out? btfss STATUS,Z call CONTINUEENTRY2 ; no, continue countdown movf ZONESVAL,W ; get current zones val xorwf ZONENORMAL,W ; XOR with normal zones status btfss STATUS,Z ; has a zone status been changed? goto ZCH2 ; yes movf ALARMZONE,W ; have any zones been triggered? btfsc STATUS,Z ; return ; no ZCH2: movwf ZONESVAL ; yes andwf INCLZONE,W ; is it a required zone? btfsc STATUS,Z return ; no movwf ZONESVAL btfsc ALARMSTATUS,5 ; yes, is alarm in passive status (just sets buzzer)? return ; yes iorwf ALARMZONE,W ; no, OR answer with previous zones triggered value movwf ALARMZONE btfsc ALARMSTATUS,STROBE ; has alarm already been triggered? goto ZONEB ; yes movf ALARMZONE,W andwf EXITZONE,W ; has entry zone been triggered? btfsc STATUS,Z goto ZONEB ; no movf ENTRYDELAY,W ; yes, has entry delay timed out? btfsc STATUS,Z goto ZONEB ; yes bsf ALARMSTATUS,BUZZER ; no so continue countdown call CONTINUEENTRY ; call LCD21 ;set address for line 1 cell 1 bsf RSLINE,4 ;set RS for data send movlw 'E' call LCDOUT movlw 'N' call LCDOUT movlw 'T' call LCDOUT movlw 'R' call LCDOUT movlw 'Y' call LCDOUT return ZONEB: movf ALARMZONE,W xorwf PREVALARMZONE,W ; is it same as previous alarm zone setting? btfsc STATUS,Z return ; yes movf ALARMZONE,W movwf PREVALARMZONE movwf STORE1 ; store INTRUDED status movlw 7 call SETPRM CHECKZONE2: ; called also from power up entry call LCD1 ;set address for line 1 cell 1 bsf RSLINE,4 ;set RS for data send movf ALARMZONE,W movwf STORE1 ; store INTRUDED status call SHOWZONE clrf LOOP ;clear loop bsf RSLINE,4 ;set RS for data send btfss ALARMSTATUS,PANIC goto LCDMS3 ; ...... TRIG movlw 'P' call LCDOUT LCDMS3: movf LOOP,W ;get table address call MESSAG2 ;get ENTERED message letter call LCDOUT ;show it incf LOOP,F ;inc loop btfss LOOP,3 ;has last LCD letter been sent? goto LCDMS3 ;no TRIG: btfss ALARMSTATUS,STROBE ; has alarm already been triggered? bsf ALARMSTATUS,BELL ; no, so trigger bell bsf ALARMSTATUS,BUZZER bsf ALARMSTATUS,STROBE movf ALARMSTATUS,W ; store ALARMSTATUS (but with bell off) to eeprom movwf STORE1 bcf STORE1,BELL movlw 8 call SETPRM return ; ****** SETS BELL BUZZER STROBE with ALARMSTATUS value SETBELLS: movf ALARMSTATUS,W andlw b'00000111' movwf PORTE return ;********* CLOCK UPDATING CLKIN: btfss ALARMSTATUS,STROBE ; clock only used if strobe active return ; allowing elapsed time since first zone triggered to be shown btfss INTCON,2 ; has timer rollover occurred? return ; no BCF INTCON,2 ; yes, clear timer flag decfsz CLKCNT,F ; increment clock routine. Is it = 0? return ; no CLKADD: movlw 25 ; reset start value of CLKCNT movwf CLKCNT SECCLK: movlw CLKSEC movwf FSR movlw 3 movwf LOOPA ADDCLK: incf INDF,F ;inc units movlw 6 addwf INDF,W ;if 6 is added is there a digit carry? btfss STATUS,DC goto CHK15 ;no movwf INDF ;yes movlw 160 addwf INDF,W ;if 160 is added is there a carry btfss STATUS,C ;(adding 160 checks if tens of units = 6) goto CHK15 ;no clrf INDF ;yes incf FSR,F decfsz LOOPA,F goto ADDCLK CHK15: movf CLKMIN,W ; has bell been on for set number of mins? xorwf BELLTIME,W ; mins in BCD (max 20) btfsc STATUS,Z bcf ALARMSTATUS,BELL CLKSHW: call LCD21 ;set address for line 1 cell 9 bsf RSLINE,4 ;set RS for data send movf CLKHRS,W ;get hrs call LCDFRM ;format and send it movlw ':' ;insert colon call LCDOUT movf CLKMIN,W ;get mins call LCDFRM movlw '.' ;insert colon call LCDOUT movf CLKSEC,W ;get secs call LCDFRM btfss ALARMSTATUS,6 ; has there been a power interruption? return ;no movlw ' ' ; yes call LCDOUT movlw 'P' call LCDOUT movlw 'S' call LCDOUT movlw 'U' call LCDOUT movlw ' ' call LCDOUT movlw 'E' call LCDOUT movlw 'R' call LCDOUT movlw 'R' call LCDOUT return ;..........GET KEYPAD 1 VAL ROUTINE........ KEYPAD1: clrf KEYPRESS btfss INTCON,RBIF ; has Panic been pushed goto KP2 ; no call PANICSET KP2: btfsc ALARMSTATUS,7 ; is alarm on? call ALARMISON ; yes btfsc ALARMSTATUS,5 ; is alarm on? call PASSIVEALARM ; yes ; goto KEYPAD2 movlw b'00001111' movwf PORTC movwf STORE nop ;pause to allow PORTC to stabilise comf PORTB,W ;get & invert PORTB andlw b'00001111' ;isolate bits 0-3 btfsc STATUS,Z ;is result NOT zero (keys pressed)? return ;no, so return to main prog movlw b'10000000' ;yes, a key is pressed so get it movwf SWITCH1 ;initial val for RC4-7 movlw 3 ;initial val for COL movwf COL clrf ROW ;initial val for ROW GETIT: comf SWITCH1,W ;get and invert val for PORTC iorwf STORE,W movwf PORTC ;output to PORTC nop ;pause to allow PORTC to stabilise comf PORTB,W ;get and invert val from PORTB andlw 15 ;isolate bits 0-3 btfss STATUS,Z ;is it zero? goto GET2 ;no, so goto analysis routine decf COL,F ;dec col val bcf STATUS,C ;clear carry flag rrf SWITCH1,F ;divide RC7-4 val by 2 movf SWITCH1,W ; andlw b'11110000' btfss STATUS,C ;is it zero? goto GETIT ;no, so continue loop return ;yes, so return to main program GET2: movwf SWVAL ;store PORTB val clrf ROW ;clear row count clrf ROWNUM ;clear row number count GET3: rrf SWVAL,F ;rotate right PORTB store val btfsc STATUS,C ;is carry flag set? goto SUMIT ;yes so key pressed, go & finish answer movlw 4 addwf ROW,F ;add matrix val to ROW count incf ROWNUM,F ;inc row number count btfss ROWNUM,2 goto GET3 SUMIT: movf ROW,W ;sum up results to single answer addwf COL,W ;add ROW to COL (total of 0-15) call VALUE movwf KEYPRESS ; store result into KEYPRESS call DEBOUNCE return ;return to main program ;********* SET ENGINEER'S PIN CODE ENGINEER: call LCD1 ;set LCD for line 1, cell 1 bsf RSLINE,4 ;set LCD RS line high clrf LOOP ;clear loop ENG2: movf LOOP,W ;get table address call PINCODE ;get message letter call LCDOUT ;show it incf LOOP,F ;inc loop btfss LOOP,4 ;has last LCD letter been sent? goto ENG2 ;no call CLRLINE2 call LCD21 ;set LCD for line 2, cell 1 bsf RSLINE,4 ;set LCD RS line high movlw PIN0 movwf FSR clrf LOOP ENG3: call WAITKEYRELEASE call WAITKEYPRESS movf KEYPRESS,W xorlw '-' ; is key = 12? - error in number so start again btfss STATUS,Z ; ... c goto ENG4 ; ... ENGINEER movf LOOP,W ; is LOOP = 0? btfss STATUS,Z goto ENGINEER ; no, so clear and continue return ; yes, so exit ENG4: movf KEYPRESS,W ; is val greater than 11? xorlw 'E' ; is it = 14? btfsc STATUS,Z goto ENG3 ; yes, so try again movf KEYPRESS,W ; is val greater than 11? xorlw 'D' ; is it = 15? btfsc STATUS,Z goto ENG3 ; yes, so try again movf KEYPRESS,W movwf INDF ; no, store it into PINx and eeprom movwf STORE1 ; and send to LCD movf LOOP,W call SETPRM movf KEYPRESS,W call LCDOUT incf FSR,F incf LOOP,F btfss LOOP,2 goto ENG3 ENG7: call WAITKEYRELEASE call WAITKEYPRESS movf KEYPRESS,W xorlw 'D' ; is key = 16? - completion code number btfsc STATUS,Z goto ENG8 ; yes movf KEYPRESS,W xorlw '-' ; is key = 12? - error in number so start again btfss STATUS,Z goto ENG7 ; no goto ENGINEER ENG8: call STORIT call WAITKEYRELEASE return ; ******* WRITE DATA TO EEPROM ROUTINE modified for PIC16F87x devices ******** ;according to data sheet DS30292A page 43 ;This routine is entered with W holding ;the eeprom byte address at which data ;is to be stored. The data to be stored ;is held in STORE1. SETPRM: bsf STATUS,RP1 ;set for Page 2 bcf STATUS,RP0 movwf EEADR ;copy W into EEADR to set eeprom address bcf STATUS,RP1 ;set for Page 0 movf STORE1,W ;get data value from STORE1 and hold in W bsf STATUS,RP1 ;set for Page 2 movwf EEDATA ;copy W into eeprom data byte register bsf STATUS,RP0 ;set for page 3 bcf EECON1,EEPGD ;point to Data memory bsf EECON1,WREN ;enable write flag MANUAL: movlw 0x55 ;these lines cause the action required by movwf EECON2 ;by the eeprom to store the data in EEDATA movlw 0xAA ;at the address held by EEADR. movwf EECON2 bsf EECON1,WR ;set the ``perform write'' flag bcf STATUS,RP1 ;set for Page 0 bcf STATUS,RP0 CHKWRT: btfss PIR2,EEIF ;wait until bit 4 of PIR2 is set goto CHKWRT bcf PIR2,EEIF ;clear bit 4 of PIR2 return ;******** READ DATA FROM EEPROM ROUTINE modified for PIC16F87x devices **** ; according to data sheet DS30292A page 43 ;This routine is entered with W holding ;the eeprom byte address to be read. PRMGET: bsf STATUS,RP1 ;set for Page 2 bcf STATUS,RP0 movwf EEADR ;copy W into EEADR to set eeprom address bsf STATUS,RP0 ;set for Page 3 bcf EECON1,EEPGD ;point to data memory bsf EECON1,RD ;enable read flag bcf STATUS,RP0 ;set for Page 2 movf EEDATA,W ;read eeprom data now in EEDATA into W bcf STATUS,RP1 ;set for Page 0 return ;******** LCD ROUTINES ********** LCD1: movlw b'10000000' goto LCDLIN LCD5: movlw b'10000100' goto LCDLIN LCD21: movlw b'11000000' goto LCDLIN LCD23: movlw b'11000011' LCDLIN: BCF RSLINE,4 LCDOUT: movwf STORE movlw 50 movwf LOOPA DELAY: decfsz LOOPA,F goto DELAY call SENDIT SENDIT: swapf STORE,F movf STORE,W andlw 15 iorwf RSLINE,W movwf PORTA BSF PORTA,5 BCF PORTA,5 RETURN LCDFRM: movwf STORE2 ;split & format decimal byte for LCD swapf STORE2,W ;get tens nibble andlw 15 iorlw 48 ;ASCII convert it call LCDOUT ;send it movf STORE2,W ;get units andlw 15 iorlw 48 ;ASCII convert it call LCDOUT return ;............. PAUSIT: movlw 10 movwf SLOWIT BCF INTCON,2 PAUSE: btfss INTCON,2 goto PAUSE BCF INTCON,2 decfsz SLOWIT,F goto PAUSE return DEBOUNCE: bsf PORTE,0 ; briefly sound buzzer clrf SLOWIT DBX: decfsz SLOWIT,F goto DBX DBA: decfsz SLOWIT,F goto DBA DBB: decfsz SLOWIT,F goto DBB DBC: decfsz SLOWIT,F goto DBC DBD: decfsz SLOWIT,F goto DBD btfss PORTE,1 ; has alarm been triggered? bcf PORTE,0 ; no, so turn off buzzer return ;............. ALARMOFF: clrf PORTE call CLRLINE1 call LCD1 ;set address for line 1 cell 1 bsf RSLINE,4 ;set RS for data send clrf LOOP ;clear loop bsf RSLINE,4 ;set RS for data send ALOFF2: movf LOOP,W ;get table address call ALLOFF ;get message letter call LCDOUT ;show it incf LOOP,F ;inc loop btfss LOOP,3 ;has last LCD letter been sent? goto ALOFF2 ;no call CLRLINE2 call PAUSIT clrf ALARMZONE clrf ALARMSTATUS clrf PREVALARMZONE clrf ENTRYDELAY clrf ZONESVAL clrf CLKSEC clrf CLKMIN clrf CLKHRS clrf STORE1 ; reset ALARMZONE status to eeprom movlw 7 call SETPRM clrf STORE1 ; reset ALARMSTATUS status to eeprom movlw 8 call SETPRM return ;******** SET ALARM INTO ACTIVE MODE ******** ALARMON: bsf PORTE,BUZZER ; turn on buzzer call MONITOR ; get zones status comf EXITZONE,W ; invert exit zone andwf ZONESVAL,W ; AND inverted exit zone with zones status to exclude exit zone setting movwf STOREX ; store it into STOREX (new variable that needs equating at start) comf EXITZONE,W ; invert exit zone andwf ZONENORMAL,W ; AND it with ZONENORMAL to exclude its setting xorwf STOREX,W ; compare current zones value with normal zones status, but ignoring entry zone btfsc STATUS,Z ; is a zone incorrectly open? goto ALON1 ; no movwf STORE3 ; yes, set value for show zones at SETAL call KEYPAD1 ; check if abort being called movf KEYPRESS,W ; is there a keypress? btfsc STATUS,Z goto SETAL ; no movf KEYPRESS,W ; yes xorlw '-' ; is key = 12 - abort? btfsc STATUS,Z goto ALARMOFF ; yes SETAL: call LCD1 ;set address for line 1 cell 1 bsf RSLINE,4 ;set RS for data send clrf LOOP ;clear loop bsf RSLINE,4 ;set RS for data send ALON0: movf LOOP,W ;get table address call OPENZONE ;get message letter call LCDOUT ;show it incf LOOP,F ;inc loop btfss LOOP,4 ;has last LCD letter been sent? goto ALON0 ;no call LCD21 ; set LCD for line 2, cell 1 bsf RSLINE,4 ; set LCD RS line high movf STORE3,W ; yes, so show zones movwf STORE1 call SHOWZONE incf FLASH,F ; beep buzzer and flash its LED bcf PORTE,0 btfss FLASH,0 bsf PORTE,0 call PAUSIT goto ALARMON ALON1: call CLRLINE1 call LCD1 ;set address for line 1 cell 1 bsf RSLINE,4 ;set RS for data send clrf LOOP ;clear loop bsf RSLINE,4 ;set RS for data send ALON2: movf LOOP,W ;get table address call MESSAGON ;get message letter call LCDOUT ;show it incf LOOP,F ;inc loop btfss LOOP,3 ;has last LCD letter been sent? goto ALON2 ;no clrf ALARMZONE clrf PREVALARMZONE call CLRLINE2 goto DELAYEXIT ;............ DELAYEXIT: movf EXITTIME,W movwf CLKSEC bsf PORTE,BUZZER ; set buzzer on movf CLKSEC,W movwf COUNT0 call BIN2DEC call LCD21 ;set address for line 2 cell 1 bsf RSLINE,4 ;set RS for data send movlw 'I' call LCDOUT movlw 'N' call LCDOUT movlw ' ' call LCDOUT movf digit2,W addlw 48 call LCDOUT movf digit1,W addlw 48 call LCDOUT movlw ' ' call LCDOUT movlw 'S' call LCDOUT movlw 'E' call LCDOUT movlw 'C' call LCDOUT movlw 'S' call LCDOUT movlw 25 ; reset start value of CLKCNT movwf CLKCNT ; 23 used because of DEBOUNCE call in KEYPAD1 routine bcf INTCON,2 ; yes, clear timer flag EXIT2: btfss INTCON,2 ; has timer rollover occurred? goto EXIT2 ; no bcf INTCON,2 ; yes, clear timer flag call KEYPAD1 ; is abort being called? movf KEYPRESS,W xorlw '-' btfsc STATUS,Z goto ALARMOFF ; yes bsf PORTE,BUZZER ; keep buzzer on decfsz CLKCNT,F ; increment clock routine. Is it = 0? goto EXIT2 ; no movlw 25 ; reset start value of CLKCNT movwf CLKCNT ; 23 used because of DEBOUNCE call in KEYPAD1 routine decf CLKSEC,F ; inc secs count movf CLKSEC,W movwf count0 clrf COUNT1 clrf COUNT2 call BIN2DEC call LCD23 ;set address for line 2 cell 1 bsf RSLINE,4 ;set RS for data send movf CLKSEC,W movf digit2,W addlw 48 call LCDOUT movf digit1,W addlw 48 call LCDOUT movf CLKSEC,W ; is it equal to EXITTIME? btfss STATUS,Z goto EXIT2 ; no bcf PORTE,BUZZER call CLRLINE2 clrf CLKSEC clrf CLKMIN clrf CLKHRS clrf STORE1 ; reset ALARMZONE status to eeprom movlw 7 call SETPRM movlw b'10000000' ; bit 7 = alarm on flag movwf ALARMSTATUS movwf STORE1 ; reset ALARMSTATUS status to eeprom movlw 8 call SETPRM movf EXITTIME,W movwf ENTRYDELAY movlw 25 ; reset start value of CLKCNT movwf CLKCNT ; bcf PORTB,5 ; turn off keypad2 entry enable return ;*********** binary to decimal modified from Peter Hemsley's code bin2dec: clrf digit1 clrf digit2 movlw 8 ;8 bits to do movwf bitcnt bitlp rlf count0,F ;Shift msb into carry movlw digit1 movwf fsr ;Pointer to digits movlw 2 ;2 digits to do movwf digcnt adjlp rlf indf,F ;Shift digit 1 bit left movlw 10 subwf INDF, W skpnc movwf indf incf fsr,F ;Next digit decfsz digcnt,F goto adjlp decfsz bitcnt,F ;Next bit goto bitlp return ;********* SET ENTRY/EXIT ZONE SETENTRY: call LCD1 ;set LCD for line 1, cell 1 bsf RSLINE,4 ;set LCD RS line high clrf LOOP ;clear loop EXT2: movf LOOP,W ;get table address call ENTRYZONE ;get message letter call LCDOUT ;show it incf LOOP,F ;inc loop btfss LOOP,4 ;has last LCD letter been sent? goto EXT2 ;no movf EXITZONE,W movwf STORE3 call CLRLINE2 EXT2A: call LCD21 ;set LCD for line 2, cell 1 bsf RSLINE,4 ;set LCD RS line high movf STORE3,W movwf STORE1 call SHOWZONE movlw ' ' call LCDOUT movlw ' ' call LCDOUT movlw ' ' call LCDOUT movlw 'M' call LCDOUT movlw 'A' call LCDOUT movlw 'X' call LCDOUT movlw ' ' call LCDOUT movlw '6' call LCDOUT call WAITKEYRELEASE EXT3: call WAITKEYPRESS movf KEYPRESS,W ; is keypress = 12 - cancel? xorlw '-' btfsc STATUS,Z return ; yes movf KEYPRESS,W xorlw 'D' ; is key = 15? - completion code number btfsc STATUS,Z goto EXT5 ; yes btfsc KEYPRESS,6 ; is val >= 'A'? goto EXT3 movf KEYPRESS,W addlw 201 ; is val greater than 7? btfsc STATUS,C goto EXT3 ; yes, so try again movf KEYPRESS,W andlw b'00001111' btfsc STATUS,Z ; is val = 0? goto EXT3 ; yes, so try again call BITVALUE movwf STORE3 goto EXT2A EXT5: movf STORE3,W ; store entry/exit zone movwf EXITZONE movwf STORE1 movlw 5 call SETPRM movf EXITZONE,W iorwf INCLZONE,F ; set INCLZONE to include entry/exit zone movf INCLZONE,W ; store new val for INCLZONE movwf STORE1 movlw 4 call SETPRM call STORIT return ;********** SET ZONES TO BE MONITORED SETMONITOR: call LCD1 ;set LCD for line 1, cell 1 bsf RSLINE,4 ;set LCD RS line high clrf LOOP ;clear loop MON2: movf LOOP,W ;get table address call WATCHMSG ;get message letter call LCDOUT ;show it incf LOOP,F ;inc loop btfss LOOP,4 ;has last LCD letter been sent? goto MON2 ;no movf INCLZONE,W movwf STORE3 ; temp store INTRUDED status call CLRLINE2 WATCH2: call LCD21 ;set address for line 2 cell 1 bsf RSLINE,4 ;set RS for data send movf STORE3,W movwf STORE1 ; store INTRUDED status call SHOWZONE MON2A: call WAITKEYRELEASE MON3: call WAITKEYPRESS movf KEYPRESS,W ; is keypress = 12 - cancel? xorlw '-' btfsc STATUS,Z return ; yes movf KEYPRESS,W xorlw 'D' ; is key = 15? - completion code number btfsc STATUS,Z goto MON7 ; yes btfsc KEYPRESS,6 ; is val >= 'A'? goto MON3 movf KEYPRESS,W addlw 200 ; is val greater than 8? btfsc STATUS,C goto MON3 ; yes, so try again movf KEYPRESS,W andlw b'00001111' btfsc STATUS,Z goto MON2A call BITVALUE movwf STORE1 movwf STORE2 movf STORE3,W ; toggle existing bit into STORE addwf STORE1,W andwf STORE1,F comf STORE2,W ; invert value andwf STORE3,W ; AND to clear existing bit iorwf STORE1,W iorwf EXITZONE,W ; ensure that entry/exit zone is always set movwf STORE3 bsf STORE3,7 goto WATCH2 MON7: movf STORE3,W movwf INCLZONE movwf STORE1 movlw 4 call SETPRM call STORIT return ;.............. STORIT: movlw ' ' call LCDOUT movlw 'S' call LCDOUT movlw 'T' call LCDOUT movlw 'O' call LCDOUT movlw 'R' call LCDOUT movlw 'E' call LCDOUT movlw 'D' call LCDOUT movlw ' ' call LCDOUT movlw ' ' call LCDOUT call PAUSIT call PAUSIT call LCD1 ;set LCD for line 1, cell 1 bsf RSLINE,4 ;set LCD RS line high clrf LOOP ; STOR2: movf LOOP,W ; movlw ' ' ;clear cell call LCDOUT ;show it incf LOOP,F ;inc loop btfss LOOP,4 ;has last LCD letter been sent? goto STOR2 ;no call CLRLINE2 return ;........... WAITKEYRELEASE: WKR2: call KEYPAD1 ; wait till key released movf KEYPRESS,W btfss STATUS,Z goto WKR2 return WAITKEYPRESS: WKP2: call KEYPAD1 ; wait till key pressed movf KEYPRESS,W btfsc STATUS,Z goto WKP2 return SHOWZONE: movlw '1' movwf LOOP movlw b'00000001' movwf COUNT0 SHOW2: movf COUNT0,W andwf STORE1,W movlw '-' btfss STATUS,Z movf LOOP,W call LCDOUT incf LOOP,F bcf STATUS,C rlf COUNT0,F btfss STATUS,C goto SHOW2 return SHOWZONE2: movlw b'00000001' movwf COUNT0 SHOW3: movf COUNT0,W andwf STORE1,W movlw 'o' btfss STATUS,Z movlw 'C' call LCDOUT bcf STATUS,C rlf COUNT0,F btfss STATUS,C goto SHOW3 return ;********* CHANGE BELL ON TIME SETBELLTIME: call LCD1 ;set LCD for line 1, cell 1 bsf RSLINE,4 ;set LCD RS line high clrf LOOP ;clear loop BEL2: movf LOOP,W ;get table address call BELLTIMEMSG ;get message letter call LCDOUT ;show it incf LOOP,F ;inc loop btfss LOOP,4 ;has last LCD letter been sent? goto BEL2 ;no call CLRLINE2 call LCD21 ;set LCD for line 2, cell 1 bsf RSLINE,4 ;set LCD RS line high movlw '?' call LCDOUT movlw '?' call LCDOUT movlw ' ' call LCDOUT movlw 'P' call LCDOUT movlw 'R' call LCDOUT movlw 'E' call LCDOUT movlw 'V' call LCDOUT movlw ' ' call LCDOUT movf BELLTIME,W call LCDFRM movlw ' ' call LCDOUT movlw 'M' call LCDOUT movlw 'A' call LCDOUT movlw 'X' call LCDOUT movlw '2' call LCDOUT movlw '0' call LCDOUT call LCD21 ;set LCD for line 2, cell 1 bsf RSLINE,4 ;set LCD RS line high call WAITKEYRELEASE BEL3: call WAITKEYPRESS ; get first value (tens) movf KEYPRESS,W ; is keypress = 12 - cancel? xorlw '-' btfsc STATUS,Z return ; yes btfsc KEYPRESS,6 ; is val >= 'A'? goto BEL3 movf KEYPRESS,W addlw 205 ; is val greater than 2? btfsc STATUS,C goto BEL3 ; yes, so try again movf KEYPRESS,W andlw b'00001111' movwf COUNT1 iorlw 48 call LCDOUT call WAITKEYRELEASE BEL4: call WAITKEYPRESS ; get 2nd val (units) movf KEYPRESS,W ; is keypress = 12 - cancel? xorlw '-' btfsc STATUS,Z return ; yes btfsc KEYPRESS,6 ; is val >= 'A'? goto BEL4 movf KEYPRESS,W addlw 198 ; is val greater than 9? btfsc STATUS,C goto BEL4 ; yes, so try again movf KEYPRESS,W andlw b'00001111' movwf COUNT0 btfss COUNT1,1 ; is COUNT1 (tens) = 2? goto BEL4A ; no clrf COUNT0 ; yes, so clear units BEL4A: movf COUNT0,W ; is total value = 0? iorwf COUNT1,W btfsc STATUS,Z goto BEL4 ; yes movf COUNT0,W ; no iorlw 48 call LCDOUT BEL5: call WAITKEYRELEASE call WAITKEYPRESS movf KEYPRESS,W xorlw 'D' ; is key = 15? - completion code number btfsc STATUS,Z goto BEL6 ; yes movf KEYPRESS,W xorlw '-' ; is key = 12? - error in number so start again btfss STATUS,Z goto BEL5 ; no goto SETBELLTIME ; yes BEL6: swapf COUNT1,W iorwf COUNT0,W movwf BELLTIME movwf STORE1 movlw 9 call SETPRM call STORIT call WAITKEYRELEASE return ;............ CLRLINE1: call LCD1 ;set address for line 1 cell 1 bsf RSLINE,4 ;set RS for data send clrf LOOP ; CLRL1: movf LOOP,W ; movlw ' ' ;clear cell call LCDOUT ; incf LOOP,F ;inc loop btfss LOOP,4 ;has last LCD letter been sent? goto CLRL1 ;no return CLRLINE2: call LCD21 ;set address for line 2 cell 1 bsf RSLINE,4 ;set RS for data send clrf LOOP ; CLRL2: movf LOOP,W ; movlw ' ' ;clear cell call LCDOUT ; incf LOOP,F ;inc loop btfss LOOP,4 ;has last LCD letter been sent? goto CLRL2 ;no return ;.............. CONTINUEENTRY: bcf INTCON,2 ; yes, clear timer flag ENTRY2: btfss INTCON,2 ; has timer rollover occurred? goto ENTRY2 ; no bcf INTCON,2 ; yes, clear timer flag decfsz CLKCNT,F ; no, decrement clock routine. Is it = 0? return movlw 25 ; reset start value of CLKCNT movwf CLKCNT ; 23 used because of DEBOUNCE call in KEYPAD1 routine decf ENTRYDELAY,F ; dec secs count return ;............. ; **** ASSESS ZONE LOGIC ASSESSLOGIC: call LCD1 ;set LCD for line 1, cell 1 bsf RSLINE,4 ;set LCD RS line high clrf LOOP ;clear loop ASL1: movf LOOP,W ;get table address call ZONELOGIC ;get message letter call LCDOUT ;show it incf LOOP,F ;inc loop btfss LOOP,4 ;has last LCD letter been sent? goto ASL1 ;no call CLRLINE2 ASL2: ; movf PORTD,W call MONITOR movf ZONESVAL,W movwf STORE3 call LCD21 ;set LCD for line 2, cell 1 bsf RSLINE,4 ;set LCD RS line high movf STORE3,W movwf STORE1 call SHOWZONE2 call KEYPAD1 movf KEYPRESS,W ; is keypress = 12 - cancel? xorlw '-' btfsc STATUS,Z return ; yes movf KEYPRESS,W xorlw 'D' ; is key = 15? - completion code number btfss STATUS,Z goto ASL2 ; no movf STORE3,W ; store normal zone status movwf ZONENORMAL movwf STORE1 movlw 10 call SETPRM call STORIT return ; **** SHOW PRESET ZONE LOGIC PRESETLOGIC: call LCD1 ;set LCD for line 1, cell 1 bsf RSLINE,4 ;set LCD RS line high clrf LOOP ;clear loop SHL1: movf LOOP,W ;get table address call SHOWLOGIC ;get message letter call LCDOUT ;show it incf LOOP,F ;inc loop btfss LOOP,4 ;has last LCD letter been sent? goto SHL1 ;no call CLRLINE2 call LCD21 ;set LCD for line 2, cell 1 bsf RSLINE,4 ;set LCD RS line high movf ZONENORMAL,W movwf STORE1 call SHOWZONE2 call WAITKEYRELEASE SHL2: call KEYPAD1 movf KEYPRESS,W ; is keypress = 12 - cancel? xorlw '-' btfss STATUS,Z goto SHL2 return ; yes ;******** BEYOND THIS POINT ITS ALL FOR KEYPAD 2 ASSOCIATED ROUTINES ;********* SET 2ND PIN CODE - via keypad 1 PINCODE2: call LCD1 ;set LCD for line 1, cell 1 bsf RSLINE,4 ;set LCD RS line high clrf LOOP ;clear loop PINC2: movf LOOP,W ;get table address call PIN2MSG ;get message letter call LCDOUT ;show it incf LOOP,F ;inc loop btfss LOOP,4 ;has last LCD letter been sent? goto PINC2 ;no call CLRLINE2 call LCD21 ;set LCD for line 2, cell 1 bsf RSLINE,4 ;set LCD RS line high movlw PIN4 movwf FSR clrf LOOP PINC3: call WAITKEYRELEASE call WAITKEYPRESS movf KEYPRESS,W xorlw '-' ; is key = 12? - error in number so start again btfss STATUS,Z ; goto PINC3A ; movf LOOP,W ; is LOOP = 0? btfss STATUS,Z goto PINCODE2 ; no, so clear and continue return ; yes, so exit PINC3A: movf KEYPRESS,W ; is val greater than 11? xorlw 'D' ; is it = 14? btfsc STATUS,Z goto PINC3 ; yes, so try again movf KEYPRESS,W ; is val greater than 11? xorlw 'E' ; is it = 15? btfsc STATUS,Z goto PINC3 ; yes, so try again movf KEYPRESS,W movwf INDF ; no, store it into PINx and eeprom movwf STORE1 ; and send to LCD movf LOOP,W addlw 11 call SETPRM movf KEYPRESS,W call LCDOUT incf FSR,F incf LOOP,F btfss LOOP,2 goto PINC3 PINC4: call WAITKEYRELEASE call WAITKEYPRESS movf KEYPRESS,W xorlw 'D' ; is key = 16? - completion code number btfsc STATUS,Z goto PINC5 ; yes movf KEYPRESS,W xorlw '-' ; is key = 12? - error in number so start again btfss STATUS,Z goto PINC4 ; no goto PINCODE2 PINC5: call STORIT call WAITKEYRELEASE return ;******* CHECK PIN CODE2 ENTRY PINENTRY2: call KEYPAD2 ; is key pressed? movf KEYPRESS2,W btfsc STATUS,Z return ; no, so return movf KEYPRESS2,W ; is keypress = pin number? xorwf PIN4,W btfss STATUS,Z goto CLOSE2 call WAITKEYRELEASE2 call WAITKEYPRESS2 movf KEYPRESS2,W ; is keypress = pin number? xorwf PIN5,W btfss STATUS,Z goto CLOSE2 call WAITKEYRELEASE2 call WAITKEYPRESS2 movf KEYPRESS2,W ; is keypress = pin number? xorwf PIN6,W btfss STATUS,Z goto CLOSE2 call WAITKEYRELEASE2 call WAITKEYPRESS2 movf KEYPRESS2,W ; is keypress = pin number? xorwf PIN7,W btfss STATUS,Z goto CLOSE2 bsf PORTB,5 ; yes, so activate PORTB output RB5 call WAITKEYRELEASE2 movf ENTRYTIME2,W movwf ENTRYDELAY2 movlw 25 ; reset start value of CLKCNT2 movwf CLKCNT2 return CLOSE2: bcf PORTB,5 ; no, so clear PORTB output RB5 return ;..........GET KEYPAD 2 VAL ROUTINE........ KEYPAD2: clrf KEYPRESS2 movlw b'00001111' movwf PORTC movwf STORE nop ;pause to allow PORTC to stabilise ; comf PORTB,W ;get & invert PORTB comf PORTD,W ;get & invert PORTD movwf STORED swapf STORED,W ; take bits 4-7 andlw b'00001111' ;isolate bits 0-3 btfsc STATUS,Z ;is result NOT zero (keys pressed)? return ;no, so return to main prog movlw b'10000000' ;yes, a key is pressed so get it movwf SWITCH1 ;initial val for RC4-7 movlw 3 ;initial val for COL movwf COL clrf ROW ;initial val for ROW GETIT2: comf SWITCH1,W ;get and invert val for PORTC iorwf STORE,W movwf PORTC ;output to PORTC nop ;pause to allow PORTC to stabilise ; comf PORTB,W ;get and invert val from PORTB comf PORTD,W ;get and invert val from PORTD movwf STORED swapf STORED,W ; take bits 4-7 andlw 15 ;isolate bits 0-3 btfss STATUS,Z ;is it zero? goto GET22 ;no, so goto analysis routine decf COL,F ;dec col val bcf STATUS,C ;clear carry flag rrf SWITCH1,F ;divide RC7-4 val by 2 movf SWITCH1,W ; andlw b'11110000' btfss STATUS,C ;is it zero? goto GETIT2 ;no, so continue loop return ;yes, so return to main program GET22: movwf SWVAL ;store PORTB val clrf ROW ;clear row count clrf ROWNUM ;clear row number count GET23: rrf SWVAL,F ;rotate right PORTB store val btfsc STATUS,C ;is carry flag set? goto SUMIT2 ;yes so key pressed, go & finish answer movlw 4 addwf ROW,F ;add matrix val to ROW count incf ROWNUM,F ;inc row number count btfss ROWNUM,2 goto GET23 SUMIT2: movf ROW,W ;sum up results to single answer addwf COL,W ;add ROW to COL (total of 0-15) call VALUE movwf KEYPRESS2 ; store result into KEYPRESS ; movwf KEYPRESS ; store result into KEYPRESS call DEBOUNCE return ;return to main program WAITKEYRELEASE2: WKR22: call KEYPAD2 ; wait till key released movf KEYPRESS2,W btfss STATUS,Z goto WKR22 return WAITKEYPRESS2: WKP22: call KEYPAD2 ; wait till key pressed movf KEYPRESS2,W btfsc STATUS,Z goto WKP22 return ;********* CHANGE ENTRY/EXIT TIME FOR KEYPAD 2 CHANGEENTRY2: call LCD1 ;set LCD for line 1, cell 1 bsf RSLINE,4 ;set LCD RS line high clrf LOOP ;clear loop ENT22: movf LOOP,W ;get table address call ENTRYTIME ;get message letter call LCDOUT ;show it incf LOOP,F ;inc loop btfss LOOP,4 ;has last LCD letter been sent? goto ENT22 ;no call LCD5 ;set LCD for line 1, cell 5 bsf RSLINE,4 ;set LCD RS line high movlw 'E' call LCDOUT movlw 'N' call LCDOUT movlw 'T' call LCDOUT movlw 'R' call LCDOUT movlw 'Y' call LCDOUT movlw '2' call LCDOUT call CLRLINE2 call LCD23 ;set LCD for line 2, cell 3 bsf RSLINE,4 ;set LCD RS line high movlw ' ' call LCDOUT movlw 'P' call LCDOUT movlw 'R' call LCDOUT movlw 'E' call LCDOUT movlw 'V' call LCDOUT movlw ' ' call LCDOUT movf ENTRYTIME2,W movwf COUNT0 call BIN2DEC movf DIGIT2,W addlw 48 call LCDOUT movf DIGIT1,W addlw 48 call LCDOUT call LCD21 ;set LCD for line 2, cell 1 bsf RSLINE,4 ;set LCD RS line high call WAITKEYRELEASE ENT23: call WAITKEYPRESS ; get first value (tens) movf KEYPRESS,W ; is keypress = 12 - cancel? xorlw '-' btfsc STATUS,Z return ; yes btfsc KEYPRESS,6 ; is it >= 'A'? goto ENT23 ; yes, so try again movf KEYPRESS,W andlw b'00001111' movwf COUNT1 movwf COUNT2 movf KEYPRESS,W call LCDOUT call WAITKEYRELEASE ENT24: call WAITKEYPRESS ; get 2nd val (units) movf KEYPRESS,W ; is keypress = 12 - cancel? xorlw '-' btfsc STATUS,Z return ; yes btfsc KEYPRESS,6 ; is it >= 'A'? goto ENT24 ; yes, so try again movf KEYPRESS,W andlw b'00001111' movwf COUNT0 addwf COUNT1,W ; is total = 0? btfsc STATUS,Z goto ENT24 ; yes, so try again movf KEYPRESS,W call LCDOUT ENT25: call WAITKEYRELEASE call WAITKEYPRESS movf KEYPRESS,W xorlw 'D' ; is key = 15? - completion code number btfsc STATUS,Z goto ENT26 ; yes movf KEYPRESS,W xorlw '-' ; is key = 12? - error in number so start again btfss STATUS,Z goto ENT25 ; no goto CHANGEENTRY2 ; yes ENT26: call WAITKEYRELEASE bcf STATUS,C rlf COUNT1,F ; convert decimal to binary rlf COUNT1,F rlf COUNT1,W addwf COUNT2,W addwf COUNT2,W addwf COUNT0,W movwf ENTRYTIME2 movf ENTRYTIME2,W movwf STORE1 movlw 15 call SETPRM call STORIT return CONTINUEENTRY2: bcf INTCON,2 ; yes, clear timer flag ENTRY22: btfss INTCON,2 ; has timer rollover occurred? goto ENTRY22 ; no bcf INTCON,2 ; yes, clear timer flag decfsz CLKCNT2,F ; no, decrement clock routine. Is it = 0? return movlw 25 ; reset start value of CLKCNT movwf CLKCNT2 decfsz ENTRYDELAY2,F ; dec secs count return bcf PORTB,5 ; clear entry 2 enable return ;........... PANIC ZONE ......... PANICSET: btfsc PORTB,PANIC ; has RB4 called Panic interrupt ( = 0)? goto PSET2 ; no bsf ALARMSTATUS,PANIC ; yes bsf ALARMSTATUS,7 ; bsf ALARMSTATUS,BELL ; trigger bell etc bsf ALARMSTATUS,BUZZER bsf ALARMSTATUS,STROBE movlw b'00000111' movwf PORTE call LCD1 ;set address for line 1 cell 1 bsf RSLINE,4 ;set RS for data send movf ZONESVAL,W movwf STORE1 ; store INTRUDED status call SHOWZONE movlw 'P' call LCDOUT clrf LOOP ;clear loop bsf RSLINE,4 ;set RS for data send PSET3: movf LOOP,W ;get table address call MESSAG2 ;get ENTRY message letter call LCDOUT ;show it incf LOOP,F ;inc loop btfss LOOP,3 ;has last LCD letter been sent? goto PSET3 ;no call CLRLINE2 call CLKSHW clrf CLKSEC clrf CLKMIN clrf CLKHRS movf ALARMSTATUS,W ; store ALARMSTATUS (but with bell off) to eeprom movwf STORE1 bcf STORE1,BELL movlw 8 call SETPRM PSET2: bcf INTCON,RBIF ; clear RBIF flag return END