+ Reply to Thread
Results 1 to 3 of 3

Thread: pic keypad

  1. #1
    nevada Newbie
    Join Date
    Nov 2003
    Location
    canada
    Posts
    10

    Default pic keypad

    hello
    great forum.I need help interfaceing the 4x4 matrix keypad to pic 16f84.
    can someone give me some ideas.
    thank you.


  2. #2
    Super Moderator Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent
    Join Date
    Nov 2003
    Location
    Derbyshire, UK
    Posts
    29,759

    Default Re: pic keypad

    Quote Originally Posted by nevada
    hello
    great forum.I need help interfaceing the 4x4 matrix keypad to pic 16f84.
    can someone give me some ideas.
    thank you.
    Funnily enough I'm currently writing a new tutorial on just that subject, so far I have the hardware page in place at http://www.winpicprog.co.uk/pic_tuto...ypad_board.htm, the main page is still being written, but I have some working preliminary code that uses the keypad board above and my LCD board using a 16F628.

    You could easily modify it for the 16F84, here's the current (24/11/03) version of the code for a 4 digit keypad lock, it may well change before I actually post the tutorial:

    Code:
    ;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
    

  3. #3
    nevada Newbie
    Join Date
    Nov 2003
    Location
    canada
    Posts
    10

    Default Nigel Goodwin

    thanks a lot. I will study the code you give me.
    once again thanks

+ Reply to Thread

Tags for this Thread