LIST p=16F628A ;tell assembler what chip we are using
include "P16F628A.inc" ;include the defaults for the chip
ERRORLEVEL 0, -302 ;suppress bank selection messages
__config 0x3D18 ;sets the configuration settings (oscillator)
cblock 0x20 ;start of general purpose registers
count
count1 ;used in delay routine
counta ;used in delay routine
countb ;used in delay routine
key
rows
endc
KEY_PORT Equ PORTA ;keypad port
KEY_TRIS Equ TRISA
Col1 Equ 4 ;pins used for keypad inputs
Col2 Equ 5
Col3 Equ 6
Col4 Equ 7
MA_PORT Equ PORTB ;set constant Message Alert = 'PORTB'
IR_PORT Equ PORTB ;set constant InfraRed = 'PORTB'
DOOR_PORT Equ PORTB
RESET_PORT Equ PORTB
KM_PORT Equ PORTB
KEYPAD_PORT Equ PORTB
OUT_PORT Equ PORTB
BARCODE_PORT Equ PORTB
IR_TRIS Equ TRISB ;set constant for TRIS register
KM Equ 0
DOOR Equ 3
IR Equ 4
MA Equ 5
RESET Equ 6
OUT Equ 7
;end of defines
org 0x0000
movlw 0x07
movwf CMCON ;turn comparators off
goto Initialise
Key_Table ADDWF PCL , f
RETLW 0x41 ;A
RETLW 0x33 ;3
RETLW 0x32 ;2
RETLW 0x31 ;1
RETLW 0x42 ;B
RETLW 0x36 ;6
RETLW 0x35 ;5
RETLW 0x34 ;4
RETLW 0x43 ;C
RETLW 0x39 ;9
RETLW 0x38 ;8
RETLW 0x37 ;7
RETLW 0x44 ;D
RETLW 0x23 ;#
RETLW 0x30 ;0
RETLW 0x2A ;*
Initialise clrf count
clrf PORTA
clrf PORTB
SetPorts bsf STATUS, RP0 ;select bank 1
movlw 0xF0 ;set keypad pins
movwf KEY_TRIS ;half (RA4 - RA7) in, half (RA0 - RA3) out
MOVLW B'11011110'
MOVWF TRISB ;RB1/RX, RB2/TX, RB3, RB4, RB6 and RB7 as input, RB0 and RB5 as output
bcf STATUS, RP0 ;select bank 0
call SER_INIT
;####################### START ####################################
CHECK_BARCODE call Rcv_RS232 ;check receive data
xorlw 'B'
btfss STATUS, Z ;is data 'B'?
goto CHECK_BARCODE ;if not, goto CHECK_BARCODE
goto KM_ON ;if yes. goto KM_ON
;######################## NORMAL PROCEDURE #########################
KM_ON bsf KM_PORT, KM ;ON Keypad Message
;Check keypad scanning
Main movlw 0xF0
movwf KEY_PORT ;set all (RB0 - RB3) output pins low
movlw 4
movwf count ;4 digits are allowed to press
Loop call Chk_Keys ;check keys
movf key, w ;restore key pressed
call XMIT_RS232 ;display as ASCII
decfsz count, f
goto Loop
goto REPLY_KEYPAD
REPLY_KEYPAD call Rcv_RS232 ;check receive data
xorlw 'A'
btfss STATUS, Z ;is data 'A'?
goto Main ;if not, goto Main
goto KM_OFF ;if yes. goto KM_OFF
KM_OFF bcf KM_PORT, KM ;OFF Keypad Message
CHECK_DOOR btfss DOOR_PORT, DOOR ;is door open?
goto CHECK_DOOR ;if no, goto CHECK_DOOR
goto INFRARED ;if yes, goto INFRARED
INFRARED btfsc IR_PORT, IR ;is infrared block?
goto INFRARED ;if no, goto INFRARED
goto MA_OFF ;if yes, goto MA_OFF
MA_OFF call Delay255 ;delay for 3sec
call Delay255
call Delay255
call Delay255
call Delay255
call Delay255
call Delay255
call Delay255
call Delay255
call Delay255
call Delay100
call Delay100
call Delay50
goto INFRARED2 ;after 3sec goto INFRARED2
INFRARED2 btfsc IR_PORT, IR ;is infrared still block after 3min?
goto CHECK_DOOR1 ;if no, goto CHECK_DOOR1
goto MA_ON ;if yes, goto MA_ON
CHECK_DOOR1 btfsc DOOR_PORT, DOOR ;is door close?
goto INFRARED2 ;if no, goto INFRARED2
goto CHECK_BARCODE ;if yes, goto CHECK_BARCODE, start over again
MA_ON bsf IR_PORT, MA ;ON Message Alert
goto CLOSE_MA ;goto CLOSE_MA
CLOSE_MA btfss RESET_PORT, RESET ;is the reset button press?
goto MA_ON ;if no, go to MA_ON
call MA_OFF1 ;if yes, go to MA_OFF1
goto CHECK_DOOR1 ;then go to CHECK_DOOR1 to check the door
MA_OFF1 bcf IR_PORT, MA ;close Message Alert
return
;########################## Keypad subroutine ##############################
Chk_Keys movlw 0x00 ;wait until no key pressed
movwf KEY_PORT ;set all output pins low
movf KEY_PORT, W
andlw 0xF0 ;mask off high byte
sublw 0xF0
btfsc STATUS, Z ;test if any key pressed
goto Keys ;if none, read keys
call Delay20
goto Chk_Keys ;else try again
Keys call Scan_Keys
movlw 0x10 ;check for no key pressed
subwf key, w
btfss STATUS, Z
goto Key_Found
call Delay20
goto Keys
Key_Found movf key, w
andlw 0x0f
call Key_Table ;lookup key in table
movwf key ;save back in key
return ;key pressed now in W
Scan_Keys clrf key
movlw 0x0F ;set all (RB0 - RB3) output lines high
movwf KEY_PORT
movlw 0x04
movwf rows ;set number of rows
bcf STATUS, C ;put a 0 into carry
Scan rlf KEY_PORT, f
bsf STATUS, C ;follow the zero with ones
btfss KEY_PORT, Col4
goto Press
incf key, f
btfss KEY_PORT, Col3
goto Press
incf key, f
btfss KEY_PORT, Col2
goto Press
incf key, f
btfss KEY_PORT, Col1
goto Press
incf key, f
decfsz rows, f
goto Scan
Press return
;end of keypad subroutines.
;######################## Hardware USART Serial routines #######################
SER_INIT
BSF STATUS, RP0 ;select bank 1
MOVLW d'25' ;9600 baud @ 4 Mhz Fosc +0.16% err
MOVWF SPBRG
MOVLW b'00100100' ;BRGH = 1
MOVWF TXSTA ;enable Async Transmission, set brgh
BCF STATUS, RP0 ;select bank 0
MOVLW b'10010000'
MOVWF RCSTA ;enable Async Reception
RETURN
XMIT_RS232 btfss PIR1, TXIF ;xmit buffer empty?
GOTO XMIT_RS232 ;no, wait
MOVWF TXREG ;now send
RETURN
Rcv_RS232 BTFSS PIR1, RCIF ;check for received data
GOTO Rcv_RS232
MOVF RCREG, W
RETURN
;End of serial routines
;############################### Delay ###################################
Delay255 movlw 0xff ;delay 255 mS
goto d0
Delay100 movlw d'100' ;delay 100mS
goto d0
Delay50 movlw d'50' ;delay 50mS
goto d0
Delay20 movlw d'20' ;delay 20mS
goto d0
Delay5 movlw 0x05 ;delay 5.000 ms (4 MHz clock)
d0 movwf count1
d1 movlw 0xC7 ;delay 1mS
movwf counta
movlw 0x01
movwf countb
Delay_0
decfsz counta, f
goto $+2
decfsz countb, f
goto Delay_0
decfsz count1 ,f
goto d1
retlw 0x00
end