Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

pic keypad

Status
Not open for further replies.

nevada

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

Nigel Goodwin

Super Moderator
Most Helpful Member
nevada said:
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 https://www.winpicprog.co.uk/pic_tutorial_keypad_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
 
Status
Not open for further replies.

Latest threads

EE World Online Articles

Loading
Top