Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
nevada said:hello
great forum.I need help interfaceing the 4x4 matrix keypad to pic 16f84.
can someone give me some ideas.
thank you.
;4 digit keypad code entry with LCD display
;Nigel Goodwin 2003
LIST p=16F628 ;tell assembler what chip we are using
include "P16F628.inc" ;include the defaults for the chip
ERRORLEVEL 0, -302 ;suppress bank selection messages
__config 0x3D18 ;sets the configuration settings (oscillator type etc.)
cblock 0x20 ;start of general purpose registers
count ;used in looping routines
count1 ;used in delay routine
counta ;used in delay routine
countb ;used in delay routine
tmp1 ;temporary storage
tmp2
templcd ;temp store for 4 bit mode
templcd2
key ;which key was pressed
rows ;counter for number of rows
code1 ;registers for secret code
code2
code3
code4
key1 ;registers for keyed attempts
key2
key3
key4
endc
LCD_PORT Equ PORTA
LCD_TRIS Equ TRISA
LCD_RS Equ 0x04 ;LCD handshake lines
LCD_RW Equ 0x06
LCD_E Equ 0x07
KEY_PORT Equ PORTB ;keypad port
KEY_TRIS Equ TRISB
Col1 Equ 0 ;pins used for keypad inputs
Col2 Equ 1
Col3 Equ 2
Col4 Equ 3
org 0x0000
goto Start
Key_Table ADDWF PCL , f ;translation table for keypad
RETLW 0x43
RETLW 0x42
RETLW 0x30
RETLW 0x41
RETLW 0x44
RETLW 0x39
RETLW 0x38
RETLW 0x37
RETLW 0x45
RETLW 0x36
RETLW 0x35
RETLW 0x34
RETLW 0x46
RETLW 0x33
RETLW 0x32
RETLW 0x31
HEX_Table ADDWF PCL , f ;hex table for LCD routines
RETLW 0x30
RETLW 0x31
RETLW 0x32
RETLW 0x33
RETLW 0x34
RETLW 0x35
RETLW 0x36
RETLW 0x37
RETLW 0x38
RETLW 0x39
RETLW 0x41
RETLW 0x42
RETLW 0x43
RETLW 0x44
RETLW 0x45
RETLW 0x46
Text addwf PCL, f
retlw 'E'
retlw 'n'
retlw 't'
retlw 'e'
retlw 'r'
retlw ' '
retlw 'C'
retlw 'o'
retlw 'd'
retlw 'e'
retlw '!'
retlw '.'
retlw 0x00
Wrong_Text addwf PCL, f
retlw 'W'
retlw 'r'
retlw 'o'
retlw 'n'
retlw 'g'
retlw ' '
retlw 'C'
retlw 'o'
retlw 'd'
retlw 'e'
retlw '.'
retlw 0x00
Correct_Text addwf PCL, f
retlw 'C'
retlw 'o'
retlw 'r'
retlw 'r'
retlw 'e'
retlw 'c'
retlw 't'
retlw ' '
retlw 'C'
retlw 'o'
retlw 'd'
retlw 'e'
retlw '.'
retlw 0x00
Start movlw 0x07
movwf CMCON ;turn comparators off (make it like a 16F84)
Initialise movlw '2' ;set 4 digit secret code
movwf code1
movlw '5'
movwf code2
movlw '8'
movwf code3
movlw '0'
movwf code4
SetPorts bsf STATUS, RP0 ;select bank 1
movlw 0x00 ;make all pins outputs
movwf LCD_TRIS
movlw 0x0F ;set keypad pins
movwf KEY_TRIS ;half in, half out
movwf TRISB
bcf STATUS, RP0 ;select bank 0
Init call LCD_Init ;setup LCD
clrf count ;set counter register to zero
Message movf count, w ;put counter value in W
call Text ;get a character from the text table
xorlw 0x00 ;is it a zero?
btfsc STATUS, Z
goto Main
call LCD_Char
incf count, f
goto Message
Wrong call LCD_Clr
clrf count ;set counter register to zero
Message1 movf count, w ;put counter value in W
call Wrong_Text ;get a character from the text table
xorlw 0x00 ;is it a zero?
btfsc STATUS, Z
goto Wrong_Wait
call LCD_Char
incf count, f
goto Message1
Wrong_Wait call Delay255
call Delay255
call Delay255
call Delay255
goto Init
Correct call LCD_Clr
clrf count ;set counter register to zero
Message2 movf count, w ;put counter value in W
call Correct_Text ;get a character from the text table
xorlw 0x00 ;is it a zero?
btfsc STATUS, Z
goto Correct_Wait
call LCD_Char
incf count, f
goto Message2
Correct_Wait call Delay255
call Delay255
call Delay255
call Delay255
goto Init
Main movlw d'1'
call LCD_Line2W ;move to 2nd row, 2nd column
call LCD_CurOn
call Chk_Keys ;wait for key
movwf key1 ;store first digit
call LCD_Char
call Chk_Keys ;wait for key
movwf key2 ;store second digit
call LCD_Char
call Chk_Keys ;wait for key
movwf key3 ;store third digit
call LCD_Char
call Chk_Keys ;wait for key
movwf key4 ;store fourth digit
call LCD_Char
call LCD_CurOff
Chk_Code movf code1, w ;test first digit
subwf key1, w
btfss STATUS, Z
goto Wrong
movf code2, w ;test second digit
subwf key2, w
btfss STATUS, Z
goto Wrong
movf code3, w ;test third digit
subwf key3, w
btfss STATUS, Z
goto Wrong
movf code4, w ;test fourth digit
subwf key4, w
btfss STATUS, Z
goto Wrong
goto Correct
;Keypad subroutine
Chk_Keys movlw 0x00 ;wait until no key pressed
movwf KEY_PORT ;set all output pins low
movf KEY_PORT, W
andlw 0x0F ;mask off high byte
sublw 0x0F
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 0xF0 ;set all output lines high
movwf KEY_PORT
movlw 0x04
movwf rows ;set number of rows
bcf STATUS, C ;put a 0 into carry
Scan rrf KEY_PORT, f
bsf STATUS, C ;follow the zero with ones
;comment out next two lines for 4x3 numeric keypad.
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
;LCD routines
;Initialise LCD
LCD_Init call LCD_Busy ;wait for LCD to settle
movlw 0x20 ;Set 4 bit mode
call LCD_Cmd
movlw 0x28 ;Set display shift
call LCD_Cmd
movlw 0x06 ;Set display character mode
call LCD_Cmd
movlw 0x0c ;Set display on/off and cursor command
call LCD_Cmd ;Set cursor off
call LCD_Clr ;clear display
retlw 0x00
; command set routine
LCD_Cmd movwf templcd
swapf templcd, w ;send upper nibble
andlw 0x0f ;clear upper 4 bits of W
movwf LCD_PORT
bcf LCD_PORT, LCD_RS ;RS line to 1
call Pulse_e ;Pulse the E line high
movf templcd, w ;send lower nibble
andlw 0x0f ;clear upper 4 bits of W
movwf LCD_PORT
bcf LCD_PORT, LCD_RS ;RS line to 1
call Pulse_e ;Pulse the E line high
call LCD_Busy
retlw 0x00
LCD_CharD addlw 0x30 ;add 0x30 to convert to ASCII
LCD_Char movwf templcd
swapf templcd, w ;send upper nibble
andlw 0x0f ;clear upper 4 bits of W
movwf LCD_PORT
bsf LCD_PORT, LCD_RS ;RS line to 1
call Pulse_e ;Pulse the E line high
movf templcd, w ;send lower nibble
andlw 0x0f ;clear upper 4 bits of W
movwf LCD_PORT
bsf LCD_PORT, LCD_RS ;RS line to 1
call Pulse_e ;Pulse the E line high
call LCD_Busy
retlw 0x00
LCD_Line1 movlw 0x80 ;move to 1st row, first column
call LCD_Cmd
retlw 0x00
LCD_Line2 movlw 0xc0 ;move to 2nd row, first column
call LCD_Cmd
retlw 0x00
LCD_Line1W addlw 0x80 ;move to 1st row, column W
call LCD_Cmd
retlw 0x00
LCD_Line2W addlw 0xc0 ;move to 2nd row, column W
call LCD_Cmd
retlw 0x00
LCD_CurOn movlw 0x0d ;Set display on/off and cursor command
call LCD_Cmd
retlw 0x00
LCD_CurOff movlw 0x0c ;Set display on/off and cursor command
call LCD_Cmd
retlw 0x00
LCD_Clr movlw 0x01 ;Clear display
call LCD_Cmd
retlw 0x00
LCD_HEX movwf tmp1
swapf tmp1, w
andlw 0x0f
call HEX_Table
call LCD_Char
movf tmp1, w
andlw 0x0f
call HEX_Table
call LCD_Char
retlw 0x00
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
Pulse_e bsf LCD_PORT, LCD_E
nop
bcf LCD_PORT, LCD_E
retlw 0x00
LCD_Busy
bsf STATUS, RP0 ;set bank 1
movlw 0x0f ;set Port for input
movwf LCD_TRIS
bcf STATUS, RP0 ;set bank 0
bcf LCD_PORT, LCD_RS ;set LCD for command mode
bsf LCD_PORT, LCD_RW ;setup to read busy flag
bsf LCD_PORT, LCD_E
swapf LCD_PORT, w ;read upper nibble (busy flag)
bcf LCD_PORT, LCD_E
movwf templcd2
bsf LCD_PORT, LCD_E ;dummy read of lower nibble
bcf LCD_PORT, LCD_E
btfsc templcd2, 7 ;check busy flag, high = busy
goto LCD_Busy ;if busy check again
bcf LCD_PORT, LCD_RW
bsf STATUS, RP0 ;set bank 1
movlw 0x00 ;set Port for output
movwf LCD_TRIS
bcf STATUS, RP0 ;set bank 0
return
;end of LCD routines
end