hello, quick question about keypad matrices.
I aquired a 4x4 matrix keypad for free and was trying to understand its operation in PBP. I started by using Bruce Reynolds code at: http://www.rentron.com/serkey16.htm.
All i am doing is waiting for a key to be pressed, then output the pressed key using HSEROUT on a PIC16F877@20Mhz.
I am using the schematic from rentron.
** The only change on my breadboard are resistors R1-R4 are 1k, not 270. **
The program kinda of works....sometimes when a button is pressed, the number sent via HSEROUT is actually the number below it.
i.e. Say the number "3" is pressed...most of the time the number "3" is displayed...but sometimes the number displayed will be "6", which is the button just below the "3" on the keypad.
Here is my slightly modified code...
Code:
'************************************************************
'* Name : serkey16.bas *
'* Author : Reynolds Electronics *
'* Date : 07/12/2001 *
'* Version : 1.0 *
'* Notes : PicBasic Pro program for 16-key serial keypad *
'************************************************************
DEFINE OSC 20 '// Define Oscillator @ (X)mHz
include "ansi.inc"
Include "modedefs.bas"
'---------------------------------------------------------------------
'---------- Define LCD Options ---------------------------------------
'---------------------------------------------------------------------
Define LCD_DREG PORTD '// Define the data port
define LCD_DBIT 0 '// Select port bit [0-lower or 4-upper]
define LCD_RSREG PORTC '// Select RS port
DEFINE LCD_RSBIT 4 '// Set RS bit (port number)
define LCD_EREG PORTC '// Set E port
define LCD_EBIT 5 '// Set E bit
define LCD_BITS 4 '// 4 or 8 bit LCD
'---------------------------------------------------------------------
'----------[Define HSEROUT Options]-----------------------------------
'---------------------------------------------------------------------
DEFINE HSER_TXSTA 20h
DEFINE HSER_RCSTA 90h
DEFINE HSER_BAUD 9600
'DEFINE HSER_SPBRG 25 '// commented out to get 9600baud working
col VAR BYTE '// Keypad column
row VAR BYTE '// Keypad row
key VAR BYTE '// Key value
'baud VAR PORTA.0 '// Baud select pin
baud VAR bit '// let baud be compiler controlled
trx_pin VAR PORTA.0 '// serial output pin
mode var word
'CMCON = 7 '// PortA = digital I/O
'VRCON = 0 '// Voltage reference disabled
'TRISA = %00000001 '// PortA.0 = baud select pin
OPTION_REG.7 = 0 '// Enable PORTB pull-ups
mode = 16780
baud = 1 '// set initial baud rate. for testing
pause 300 '// let LCD initialize
@ ClearScr '// clear screen
@ CurHome '// return cursor to home
startup:
lcdout $FE,1
lcdout "-Serial Keypad-"
hserout ["------------------------------",10,13]
hserout ["-----[Serial Keypad Demo]-----",10,13]
hserout ["------------------------------",10,13,13,13,13]
loop:
GOSUB getkey 'Get key from keypad
send:
IF baud = 1 THEN fast'If baud = 1 then N9600,else N2400
hserout [10,13,dec key,10,13]
'SEROUT2 trx_pin,N2400,[key]'Send key value out PortA.1
GOTO loop
fast:
hserout [dec key,10,13]
'SEROUT serpin,N9600,[key]
GOTO loop 'Do it forever
getkey:
PAUSE 100 'Debounce key-input
getkeyu:' Wait for all keys up
PORTB = 0 ' All output-pins low
TRISB = $f0 ' Bottom 4-pins out, top 4-pins in
IF ((PORTB >> 4) != $f) THEN getkeyu'If keys down, loop
PAUSE 50 ' Debounce key-input
getkeyp:' Wait for keypress
FOR row = 0 TO 3 ' 4 rows in keypad
PORTB = 0 ' All output-pins low
TRISB = (DCD row) ^ $ff ' Set one row pin to output
col = PORTB >> 4 ' Read columns
IF col != $f THEN gotkey' If any keydown, exit
NEXT row
GOTO getkeyp ' No keys down, go look again
gotkey: ' Change row and column to key number 1 - 16
key = (row * 4) + (NCD (col ^ $f))
'NOTE: for 12-key keypad, change to key = (row * 3)
RETURN ' Subroutine over
END
Any help would be greatly appreciated. I have a strong feeling it is something simple. Thanks in advance.
Sean
Bookmarks