PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun May 30, 2010 5:27 pm |
|
|
Quote: |
You will notice that some members recommend not using the Port B
change interrupt but instead use a Timer interrupt to poll the keypad. |
Here is some sample code to do that. The program below calls the
Flex keypad driver (I didn't write that one) in the Code Library:
http://www.ccsinfo.com/forum/viewtopic.php?t=26333
I have connected my keypad with the Row pins on B1-B4 and the
column pins on pins E0-E2 on the 16F877. That's because I can
then easily turn on PortB pull-ups for the Row pins.
The program polls the keypad every 10ms in the #int_rtcc routine
and uses code from the CCS example file Ex_Sisr.c to create a
circular buffer to store the key presses. The user then calls bkbhit()
to see if there are any keys in the buffer, and if so, he can get them
by calling bgetc().
In the program below, you just press keys on the keypad and
they will appear on the terminal window on your PC. I'm using
TeraTerm as the terminal window program.
http://www.ccsinfo.com/forum/viewtopic.php?t=39388&start=18
Code: |
#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
// Use the Flex keypad driver from the CCS Code Library forum.
#include "flex_kbd.c"
#define BUFFER_SIZE 32
BYTE buffer[BUFFER_SIZE];
BYTE next_in = 0;
BYTE next_out = 0;
// This preload value will give an RTCC interrupt
// rate of 100 Hz (every 10 ms) with a pre-scaler
// of 256, and if the PIC is running at 4 MHz.
#define RTCC_PRELOAD (256 - 39)
//------------------------------
// The keypad is polled every 10ms in this interrupt
// routine.
#int_rtcc
void rtcc_isr(void)
{
int t;
int k;
set_rtcc(RTCC_PRELOAD); // Reload Timer0 for 10ms rate
k = kbd_getc(); // Check the keypad for a keypress
// If we got a keypress, put it in the circular
// buffer.
if(k != 0)
{
buffer[next_in] = k;
t=next_in;
next_in=(next_in+1) % BUFFER_SIZE;
if(next_in==next_out)
next_in=t;
}
}
#define bkbhit (next_in!=next_out)
//------------------------------
int8 bgetc(void)
{
int8 c;
while(!bkbhit);
c=buffer[next_out];
next_out=(next_out+1) % BUFFER_SIZE;
return(c);
}
//==================================
void main()
{
int8 key;
kbd_init(); // Enable PortB pull-ups on keypad Row pins
// Setup the RTCC (also called Timer0).
setup_counters(RTCC_INTERNAL, RTCC_DIV_256);
set_rtcc(RTCC_PRELOAD);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
while(1)
{
// Check if a key is available in the buffer.
if(bkbhit)
{
key = bgetc(); // If so, get the key
putc(key); // 'key' is an ASCII char, so display it
}
}
} |
|
|