keypad - Copyright (c) 2002 Tundraware Inc., All Rights Reserved
$Id: readme.txt,v 1.4 2002/05/31 17:16:20 tundra Exp tundra $
PLEASE NOTE: Before using anything in this archive, you must read, and
agree to abide by, the licensing terms found in:
Makefile Unix-style makefile which runs under DJGPP and
should also work under MKS and Cygwin.
readme.txt This file.
keypad-license.txt Licensing terms for using this software.
keypad.gif keypad schematic in GIF format.
keypad.png keypad schematic in png format.
keypad.ps keypad schematic in PostScript format.
keypad.sch keypad schematic in Eagle format.
keypad.brd keypad printed circuit board layout in Eagle format.
keypad.asm keypad software written in PIC assembler.
keypad.hex The assembled keypad software.
keypad.lst keypad listing file generated by assembler.
keypad.xrf keypad cross-reference file generated by assmbler.
WHAT IS 'keypad'?
'keypad' is a PIC based system for decoding switch matrix type numeric
keypads with up to 4 rows and columns. The keypad switch matrix is
read, and if a key is pressed, it is converted into an equivalent
binary value (0-0fh) for output. Full debounce logic is included to
suppress mechanical switch bounce effects.
Output can either be a 4-bit parallel word or a serial clocked output.
Both serial and parallel outputs support a "latching" pulse to drive
external interface timing.
ABOUT THE HARDWARE
'keypad' is built around a very simple PIC 16F84 circuit. This
circuit uses an RC oscillator because timing is not particularly
critical in this application. The keypad hardware is connected to
PORTB and output is found on PORTA. MCLR is pulled up so that noise
does not reset the system. RA4 is pulled-up to allow for selection
of serial or parallel output as described below.
This release includes the schematic in a number of common formats.
***VERY IMPORTANT NOTE***: The schematic shows *both* a crystal
network and an RC network connected to OSC1/OSC2. This is intentional
so that the resulting printed circuit board has provision for either a
crystal or RC oscillator. However, you only use one *or* the other,
never both. This approach allows one printed circuit board to be used
in a variety of applications. In the case of 'keypad', the software
assumes an RC network formed by R2 and C2. You do *not* use Q1, C3,
or C4 at all. They should not be handwired into a circuit, nor should
they be populated on the printed circuit board.
ABOUT THE SOFTWARE
NOTE: The 'keypad' code is pretty thoroughly commented and is a good
place to go to understand the details of just how this stuff
The 'keypad' software has 4 major elements:
TMR0 Interrupt Routine - This creates a "heartbeat" clock with an
approximate period of 480us. This is used when
doing debounce waits and for timing the
output latching and serial clocking pulses.
Mainline Code - After some initialization, the main code continuously
loops through each keypad column looking to see if a
key has been pressed. If so, it reads a debounced
version of the key, translates it into and equivalent
binary value and outputs the result either serially or
as a parallel nibble.
Translation Tables - This code makes extensive use of translation
tables to pickup the various column selection bit
patterns and to translate key hit bit patterns
found on the keypad interface into equivalent
binary values for output.
Supporting Subroutines - These are the various subroutines called by
the Mainline Code to initially setup the
hardware, and thereafter scan and process key
The basic idea is that the column lines of the keypad are connected to
PORTB 4:7 and the row lines are connected to PORTB 0:3. The column
lines default to a logical high, and the row lines are pulled up to a
logical high using the PIC weak pullup capabilities.
'keypad' successively scans each keypad column by setting that
column's control bit to low. Then, if a key is pressed in that
column, it shorts the corresponding row/column lines together. Since
the row line is pulled high with an internal weak pullup and the
column line is low, this has the effect of pulling the row line low.
By examining which column line is currently enabled (low) and which
row line has been pulled low, 'keypad' can tell which key got pressed
and then translate it into an equivalent binary value.
It's not quite this simple, though, because mechanical switches
"bounce" when they are pressed or released. The software has to wait
until this bouncing is done before reading the keyboard interface or
you will get bogus key press values. the 'key_get' routine in this
software incorporates so-called "debounce" logic to avoid this
problem. A key hit is not considered valid until it has remained
unchanged DEBOUNCE_COUNT (5) times. The routine waits DEBOUNCE_TIME
(10 * TMR0 interval = 4.8ms) between read attempts.
During software intialization, the 'init' subroutine reads the
hardware configuration to determine whether you want serial or
parallel output. (See the next section on how to configure the
hardware to do this.) Thereafter, it uses that output method. In
other words, if you change the Serial/Parallel output selection while
'keypad' is running, it will be ignored - you have to do a device
reset to reread this configuration. The 'key_out' routine supports
both serial and parallel output modes and checks a flag set during
initialization to decide which one to use.
HOW TO SELECT SERIAL/PARALLEL OUTPUT
'keypad' is capable of delivering the binary value of the key
press as either a 4-bit parallel word *or* as a serial bit stream.
To select parallel output:
Pull RA4 high *through a 10K resistor*.
To select serial output:
Pull RA4 to ground (low).
Parallel Bit Assignments:
RA0 - Bit 0 out
RA1 - Bit 1 out
RA2 - Bit 2 out
RA3 - Bit 3 out
RA4 - Latch out - Normally low. Goes high for
approximately 480us (LATCH_TIME * TMR0 interval)
when the word on A0:3 is valid.
Serial Bit Assignments:
RA0 - Serial Data
RA1 - Serial Clock - Normally low. Goes high for
approximately 480us (CLK_TIME * TMR0 interval)
when bit on A0 is valid
RA2 - Latch out - Normally low. Goes high for
approximately 480us (LATCH_TIME * TMR0 interval)
when all bits in current value have been clocked out.
RA3 - Unused
RA4 - Unused
USING 3- and 4-COLUMN KEYPADS
The 'keypad' code assumes 4x4 keypad. However it is trivial to use a
3 column keypad (4x3). To use this smaller keypad, just don't connect
anything to bit B7. To avoid noise, you probably should pull this
pin high with a 10K resistor.
You can also change the MAX_COL value to 3 in the code which will
inhibit scanning for the 4th column. I prefer *not* to do this so
that one PIC can handle both keypad types.
MAPPING OF KEYPAD VALUES
The numeric keys on the keypad are mapped to their equivalent
binary values. The remaining keys are mapped as follows:
R4C1 (*) 0eh
R4C3 (#) 0fh
If you don't like these assignments you can change them by modifying
the 'colX_keys" translation tables, where 'X' is the column in
This is *experimental software* and has not been tested thorougly.
It probably has bugs. If you find one, please let me know and
I'll make the necessary changes.