Sie sind auf Seite 1von 3

Keypad Usage

by
Bruce Misner

In one of my recent projects I used a keypad as an input device to my 16f877


microcontroller. The keypad I purchased was one by Grayhill 88bb2-072, which is a 4x4 matrix
output. Initially, I had never used a matrix output and needed to learn. The following tells how I
achieved the operation of the keypad.

As stated previously, the output of the keypad is a matrix output. You have eight outputs
for sixteen keys, how does that work? Well, the connections you have are the row and column
connections. Hence, each button push actually closes two contacts, one row and one column.
Every intersection has both a row and column switch (see diagram below). The row connections
have pull down resistors to ground and the top of each resistor will connect to the upper bits of
Port B to utilize the Port B change interrupt that is available on the PIC 16f877 microcontrollers.
The column connection are taken to the lower bits of Port B.

Now that we have covered the hardware the software needs to be dealt with. What needs
to be down is each column needs to be pulsed individually and as a key is pressed an interrupt
will be generated from the row connections. The following is the code for this support.

TRISB = 0xf0;
INTCON = 0x08;

These line are in the init() subroutine. TRISB defines the intput output staus of Port B,
upper four bits inputs the lower four bits output. The INTCON register enables the Port B change
interrupt. In other code I have written INTCON has a different value because other interrupts are
enabled. The next section of code generates the pulses that continually pulse the column
connections.
void scankey()
{
int i;

nokey = 0;
while (nokey == 0)
{
RB0 = 1;
for ( i=0;i<9;i++);
RB0 = 0;
RB1 = 1;
for ( i=0;i<9;i++);
RB1 = 0;
RB2 = 1;
for ( i=0;i<9;i++);
RB2 = 0;
RB3 = 1;
for ( i=0;i<9;i++);
RB3 = 0;
}
}

This code by itself won't get the job done. nokey is a global variable used as a flag to
signify that a key has been pressed. This variable gets set in the interrupt subroutine. Hence, this
is a continual loop that runs until the interrupt is generated and the nokey variable is set to 1. The
following is the interrupt code.

static void interrupt


isr()
{
int i;

//
// interrupt routine assign the
// character that corresponds to
// the key that has been pressed
//

if (RBIF)
{
for (i=0;i<15000;i++);
nokey = 1;
if (RB7)
{
if (RB3) key = '3';
if (RB2) key = '2';
if (RB1) key = '1';
if (RB0) key = '0';
}
if (RB6)
{
if (RB3) key = '7';
if (RB2) key = '6';
if (RB1) key = '5';
if (RB0) key = '4';
}
if (RB5)
{
if (RB3) key = 'b';
if (RB2) key = 'a';
if (RB1) key = '9';
if (RB0) key = '8';
}
if (RB4)
{
if (RB3) key = 'f';
if (RB2) key = 'e';
if (RB1) key = 'd';
if (RB0) key = 'c';
}
RBIF = 0;

}
The interrupt service routine starts by indentifying that it was the Port B change interrupt
that occurred followed by a delay loop used to debounce the contact (needed). Then proceeds to
determine which column bit changed and then determining which row had been pulsed. The Port
B change interrupt flag is cleared and then the interrupt service routine is terminated.

So there you have it. All you need to know to implement a Grayhill series 88 keypad to
your PIC 16f877 microcontroller. The only issue you may have is setting the debounce time delay
to suit your controllers frequency or your slow fat fingers.

Das könnte Ihnen auch gefallen