View previous topic :: View next topic |
Author |
Message |
freedom
Joined: 10 Jul 2011 Posts: 54
|
keypad button issue |
Posted: Wed Dec 21, 2011 1:36 pm |
|
|
hi all
I'm using Flex_KBD driver for keypad.
This driver returns character when any key is pressed and released . but I want to return character when button is pressed , not to wait until the button released.
Code: | ///////////////////////////////////////////////////////////////////////////
//// Flex_KBD.C ////
//// Generic keypad scan driver ////
//// ////
//// kbd_init() Must be called before any other function. ////
//// ////
//// c = kbd_getc(c) Will return a key value if pressed or /0 if not ////
//// This function should be called frequently so as ////
//// not to miss a key press. ////
//// ////
///////////////////////////////////////////////////////////////////////////
//Keypad connection:
#define col0 PIN_E0
#define col1 PIN_E1
#define col2 PIN_E2
#define row0 PIN_A0
#define row1 PIN_A1
#define row2 PIN_A2
#define row3 PIN_A3
// Keypad layout:
char const KEYS[4][3] = {{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}};
#define KBD_DEBOUNCE_FACTOR 33 // Set this number to apx n/333 where
// n is the number of times you expect
// to call kbd_getc each second
void kbd_init() {
}
short int ALL_ROWS (void)
{
if (input (row0) & input (row1) & input (row2) & input (row3))
return (0);
else
return (1);
}
char kbd_getc( ) {
static byte kbd_call_count;
static short int kbd_down;
static char last_key;
static byte col;
byte kchar;
byte row;
kchar='\0';
if(++kbd_call_count>KBD_DEBOUNCE_FACTOR) {
switch (col) {
case 0 : output_low(col0);
output_high(col1);
output_high(col2);
break;
case 1 : output_high(col0);
output_low(col1);
output_high(col2);
break;
case 2 : output_high(col0);
output_high(col1);
output_low(col2);
break;
}
if(kbd_down) {
if(!ALL_ROWS()) {
kbd_down=false;
kchar=last_key;
last_key='\0';
}
} else {
if(ALL_ROWS()) {
if(!input (row0))
row=0;
else if(!input (row1))
row=1;
else if(!input (row2))
row=2;
else if(!input (row3))
row=3;
last_key =KEYS[row][col];
kbd_down = true;
} else {
++col;
if(col==3)
col=0;
}
}
kbd_call_count=0;
}
return(kchar);
} |
Any tips ? Please |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Dec 21, 2011 5:27 pm |
|
|
Quote: |
I want to return character when button is pressed, not to wait until the
button is released.
|
I think these two changes below (in bold) will probably do it:
Quote: |
if(kbd_down) { // This block detects if a key was released.
if(!ALL_ROWS()) {
kbd_down=false;
// kchar=last_key; // Comment out this line
last_key='\0';
}
} else { // This block detects if a key was pressed.
if(ALL_ROWS()) {
if(!input (row0))
row=0;
else if(!input (row1))
row=1;
else if(!input (row2))
row=2;
else if(!input (row3))
row=3;
last_key =KEYS[row][col];
kchar=last_key; // Move it to here
kbd_down = true;
} else {
++col;
if(col==3)
col=0;
} |
|
|
![](templates/subSilver/images/spacer.gif) |
freedom
Joined: 10 Jul 2011 Posts: 54
|
|
Posted: Thu Dec 22, 2011 6:29 am |
|
|
Thanks PCM
Now its working.
Would you like to explain about KBD_DEBOUNCE_FACTOR 33
Code: |
#define KBD_DEBOUNCE_FACTOR 33
// Set this number to apx n/333 where
// n is the number of times you expect
// to call kbd_getc each second |
|
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Dec 22, 2011 6:16 pm |
|
|
That number controls the rate at which the keypad is polled. For a PIC
running at 20 MHz, the keypad is polled at about a 7.2 KHz rate, which
is really much faster than it needs to be.
I found the rate by adding two lines of code at the start of the keypad
polling code, as shown below. This gives a short pulse on the scope
at a 7.2 KHz rate. I also enabled fast_io for PortC and set the TRIS for
pin C0 to be an output pin. This reduces the ASM code for those two
lines to the minimum.
Code: |
if(++kbd_call_count>KBD_DEBOUNCE_FACTOR)
{
output_high(PIN_C0); // *** TESTING
output_low(PIN_C0);
|
If I change KBD_DEBOUNCE_FACTOR to 254, then the polling rate goes
down to 1 KHz (with a 20 MHz crystal on the PIC), and so it's being polled
every 1 ms. Of course it still works, and it's still faster than what you
really need. |
|
![](templates/subSilver/images/spacer.gif) |
|