I2C QWERTY 36-Keypad
(Turnkey
project)

Introduction
This turnkey project demonstrates an I2C 'QWERTY' keypad
using the 'QWERTY
36-Keypad' sub-circuit. LED's and a 'new key' output
show the status of the keypad.
The target device is a PIC16F872 running at 10MHz
The keypad is based on the Storm 700 series rugged
36-keypad (RS Stock no. 198-292)
Operation
The keypad is scanned at regular intervals by calls
made from the timer tick routine RTCC_ISR. When a key
is pressed its ASCII value is stored in the shared I2CSLRAM
slave ram sub-circuit at address location 0x00. In addition,
the NEWKEY_PORT is set high and the NEWKEY_LED is switched
on indicating the presence of a new key press.
The master I2C device can determine the presence of
a new key press by either polling location 0x00 of the
I2CSLRAM for a non- zero ASCII character, or, by monitoring
the NEWKEY_PORT output for a high state. The master
reads the new-key press ASCII value from location 0x00,
this also clears location 0x00, clears NEWKEY_PORT to
low and switches off NEWKEY_LED. Subsequent reads from
0x00 result in zero until a new key is pressed. The
master can get the currently pressed key by reading
from I2CSLRAM location 0x01, similarly, capitals lock
status is determined by reading location 0x02.
The following summarise the functions of the I2CSLRAM
data:
I2CSLRAM Address 0x00
New ASCII key.
Reading this location returns the ASCII value of the
new key. A value of zero means no new key pressed. In
addition a read also clears this location to zero and
resets NEWKEY_PORT output to low.
I2CSLRAM Address 0x01
Current pressed ASCII key.
Reading this location returns the current pressed ASCII
key value. A value of zero means no key pressed.
I2CSLRAM Address 0x02
Capitals lock status.
Reading the location returns the capitals lock status.
A value of zero means caps lock is off, a value of one
means caps lock is on.
I2CSLRAM Address 0x03
This location is not used but may be read and written
for test purposes.
Application code
Below is the application code for this project. To use
it, select and copy (ctr-insert) the code below and
past it into a text editor and save as a 'C' file in
your working directory. You may also need to change
the build output path using 'Project | Options'
///////////////////////////////////////////////////////////////////////
//// AI2CKP1.C ////
//// ////
//// This project demostrates the 'QWERTY 36-keypad' sub-circuit ////
//// with I2C interface. ////
//// ////
//// This program is an example of how your application code is ////
//// is organised. Note the #include "i2ckp1.c", this include ////
//// file was generated by QuickBuilder and contains all ////
//// driver code. ////
//// ////
//// This demo is intended for a PIC16F872 ////
//// Compile using CCS 'C' visit www.quickbuilder.co.uk/qb/ccs ////
///////////////////////////////////////////////////////////////////////
#include <16f872.H>
#fuses hs,wdt,noprotect,put,nowrt,nolvp
#case
#define PORTA 5
#define PORTB 6
#define PORTC 7
#define TRISA 0x85
#define TRISB 0x86
#define TRISC 0x87
#include "i2ckp1.c"
#int_rtcc
void RTCC_ISR()
{
QWERTY_1DO(); // scans keypad
}
main() {
BYTE key;
// initialise
//------------
INIT_SUB_CIRCUITS();
// watch dog, subcircuits and timer tick
restart_wdt();
setup_counters(RTCC_INTERNAL,RTCC_DIV_4);
enable_interrupts(INT_TIMER0);
setup_adc_ports(NO_ANALOGS);
// set i2c device address
I2CSLRAM_1SETDADD( ADD_READ() );
enable_interrupts(GLOBAL);
// set up keypad status
NEWKEY_PORT_WRITE(0); // no newkey
NEWKEY_LED_OFF(); // newkey led oFF
// main loop
//----------
while(1) {
// upadte I2CSLRAM with key press data
//------------------------------------
key = QWERTY_1NEWKEY(); // I2C REG0: new key press
if ( key ) {
I2CSLRAM_1DATA[0] = key;
NEWKEY_PORT_WRITE(1); // set newkey line
NEWKEY_LED_ON(); // newkey led on
}
I2CSLRAM_1DATA[1] = QWERTY_1KEY(); // I2C REG1: current key press
if ( QWERTY_1CAPS() ) { // I2C REG2: caps lock status
I2CSLRAM_1DATA[2] == 1;
CAPS_LED_ON();
} else {
I2CSLRAM_1DATA[2] == 0;
CAPS_LED_OFF();
}
// service i2c
//------------
I2CSLRAM_1DO();
// monitor i2c for reads
if ( I2CSLRAM_1UPDATE == 1) { // i2c has been read
I2CSLRAM_1UPDATE = 0; // clear update flag
if ( I2CSLRAM_1ADDR == 0 ) { // reg0 has been read
I2CSLRAM_1DATA[0] = 0; // I2C REG0: clear new key press
NEWKEY_PORT_WRITE(0); // clear new key line
NEWKEY_LED_OFF(); // new key led off
}
}
// service watchdog
//------------------
restart_wdt(); // reset watch dog
}
}
|