@tundra tundra authored on 19 Jan 2019
CHANGELOG move stable code to git 5 years ago
Makefile move stable code to git 5 years ago
keypad-board.jpg move stable code to git 5 years ago
keypad-license.txt move stable code to git 5 years ago
keypad.asm move stable code to git 5 years ago
keypad.brd move stable code to git 5 years ago
keypad.gif move stable code to git 5 years ago
keypad.hex move stable code to git 5 years ago
keypad.lst move stable code to git 5 years ago
keypad.png move stable code to git 5 years ago
keypad.ps move stable code to git 5 years ago
keypad.sch move stable code to git 5 years ago
keypad.xrf move stable code to git 5 years ago
readme.txt move stable code to git 5 years ago
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.


'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.


NOTE: The 'keypad' code is pretty thoroughly commented and is a good
      place to go to understand the details of just how this stuff
      actually works.

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.


'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


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.


The numeric keys on the keypad are mapped to their equivalent
binary values.  The remaining keys are mapped as follows:

R1C4      0ah
R2C4      0bh
R3C4      0ch
R4C4      0dh
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.

Happy Hacking!