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: keypad-license.txt ************************************************************************ FILE DESCRIPTIONS ================= 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 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 hits. 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: 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 question. BUGS ==== 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! tundra@tundraware.com