![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
Guest101 Guest
|
Problem with 4x4 Keypad Scan (Without Pull-up) |
Posted: Tue Feb 12, 2008 10:28 pm |
|
|
Hi all,
i did some modification to the codes which i found here but i cant seem to get it to work on hardware. I've successfully simulated it using proteus. Can someone help me out with this? Thanks in advance
Quote: |
#include <18F2680.h>
#fuses HS,NOPROTECT,NOLVP,NOWDT
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
// =============================
//Keypad connection:
#define row0 PIN_A0
#define row1 PIN_A1
#define row2 PIN_A2
#define row3 PIN_A3
#define col0 PIN_C0
#define col1 PIN_C1
#define col2 PIN_C2
#define col3 PIN_C3
// Keypad layout:
int const KEYS[4][4] =
{{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}};
#define KBD_DEBOUNCE_FACTOR 33
short int ALL_ROWS (void)
{
if(input (row0) || input (row1) || input (row2) || input (row3))
return (1);
else
return (0);
}
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_high(col0);
output_low(col1);
output_low(col2);
output_low(col3);
break;
case 1:
output_low(col0);
output_high(col1);
output_low(col2);
output_low(col3);
break;
case 2:
output_low(col0);
output_low(col1);
output_high(col2);
output_low(col3);
break;
case 3:
output_low(col0);
output_low(col1);
output_low(col2);
output_high(col3);
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==4)
col=0;
}
}
kbd_call_count=0;
}
return(kchar);
}
//===========================
void main()
{
char k;
printf("\r\Starting ...");
while(TRUE)
{
k=kbd_getc();
if(k!=0)
{
if(k=='*')
printf("%c", '*');
else
printf("%c", k);
}
}
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Feb 12, 2008 10:40 pm |
|
|
Add pull-up resistors on the row pins. You can use 10K resistors. |
|
![](templates/subSilver/images/spacer.gif) |
fms
Joined: 12 Feb 2008 Posts: 4
|
|
Posted: Wed Feb 13, 2008 2:14 am |
|
|
This would result changes in the hardware design. There are many design which uses this concept (without pullup). but why it wouldn't work using PIC C? |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Wed Feb 13, 2008 6:06 am |
|
|
Row scanning like this, should work fine with CCS. I do it on several keyboards OK.
So, there has to be something wrong in the code, or approach...
The code as written, does make it quite hard to follow the sequence being used.
Comments:
You seem to only change the column addressed, when the debounce factor is met. It is reset, whenever the routine exits, so will never go true...
Before testing all rows, you really want to initially set all columns, then this will say if any key is pressed. At present, because of the comment above, _no_ column will be set...
The code failing, is not because of CCS.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
fms
Joined: 12 Feb 2008 Posts: 4
|
|
Posted: Wed Feb 13, 2008 7:11 am |
|
|
Ttelmah wrote: | Row scanning like this, should work fine with CCS. I do it on several keyboards OK.
|
Dear Ttelmah,
Thanks for the explanation. mind if u share us your codes? This would help me alot. |
|
![](templates/subSilver/images/spacer.gif) |
fms
Joined: 12 Feb 2008 Posts: 4
|
4x4 Keypad Scan (Without Pull-up) (SOLVED) |
Posted: Thu Feb 14, 2008 12:12 pm |
|
|
Dear ALL,
I've retested and reconfirmed that my code is just fine and working perfectly. The problem is with the floating of my row input pins. Pull them low and everything works beautifully. Hope this will help many out there.
Code: |
//Code Edited by AdrianKhoo from CCS forum (www.ccsinfo.com).
//Keypad connection:
#define ROW0 PIN_A0
#define ROW1 PIN_A1
#define ROW2 PIN_A2
#define ROW3 PIN_A3
#define COL0 PIN_C0
#define COL1 PIN_C1
#define COL2 PIN_C2
#define COL3 PIN_C3
// Keypad layout:
int const KEYS[4][4] =
{{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}};
#define KBD_DEBOUNCE_FACTOR 33
short int ROW_HIGH()
{
if(input (ROW0) || input (ROW1) || input (ROW2) || input (ROW3))
return (1);
else
{
return (0);
}
}
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_high(col0);
output_low(col1);
output_low(col2);
output_low(col3);
break;
case 1:
output_low(col0);
output_high(col1);
output_low(col2);
output_low(col3);
break;
case 2:
output_low(col0);
output_low(col1);
output_high(col2);
output_low(col3);
break;
case 3:
output_low(col0);
output_low(col1);
output_low(col2);
output_high(col3);
break;
}
if(kbd_down)
{
if(!ROW_HIGH())
{
kbd_down=false;
kchar=last_key;
last_key='\0';
}
}
else
{
if(ROW_HIGH())
{
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==4)
col=0;
}
}
kbd_call_count=0;
}
return(kchar);
}
//===========================
void main()
{
char k;
printf("\r\Starting ...");
while(TRUE)
{
k=kbd_getc();
if(k!=0)
{
if(k=='*')
printf("%c", '*');
else
printf("%c", k);
}
}
} |
Last edited by fms on Wed Apr 02, 2008 11:12 am; edited 1 time in total |
|
![](templates/subSilver/images/spacer.gif) |
D-Kens
Joined: 09 May 2005 Posts: 35 Location: Toulouse (France)
|
|
Posted: Tue Mar 25, 2008 8:34 am |
|
|
Thanks a lot for your code : I just began working on a project where I have to use a 4x3 keypad, and couldn't lose much time on writing code to handle it with my PIC. You made me save lots of time... ![Wink](images/smiles/icon_wink.gif) |
|
![](templates/subSilver/images/spacer.gif) |
fms
Joined: 12 Feb 2008 Posts: 4
|
|
Posted: Wed Apr 02, 2008 11:11 am |
|
|
Really glad it did helped someone out. Worth all the debugging effort. Thanks CCS Forum and PCM programmer for the pull up version. |
|
![](templates/subSilver/images/spacer.gif) |
filjo
Joined: 29 Apr 2008 Posts: 9
|
|
Posted: Tue Apr 29, 2008 10:07 am |
|
|
Hi
I try make one program using keypad 3x4 and I like use ports D I used for example "c = kbd_getc(c)" I used driver KBDD.c
but where I connect my keypad to PIC ports?
for example, I have col0, col1, col2 and row0, row1 ,row2 ,row3 but I dont know connect this, D0,D1,D2,D3,D4,D5,D6,D7...
some one can help me?
regards |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
![](templates/subSilver/images/spacer.gif) |
filjo
Joined: 29 Apr 2008 Posts: 9
|
|
Posted: Tue Apr 29, 2008 12:41 pm |
|
|
Hi PCM programmer thanks for help me ...
I configure KBDD.c in my case stay iqual because I use PIC18F452 and need connect keypad to port D.
but I my problem continue... where I connect my keypad? what is the PIN's of th e PIC?
my key pad is:
C0 | C1 | C2
_________________
R0 | 1 | 2 | 3
R1 | 4 | 5 | 6
R2 | 7 | 8 | 9
R3 | * | 0 | #
Some one can help me comple this?
C0=RD..
C1=RD..
C2=RD..
R0=RD..
R1=RD..
R2=RD..
R3=RD..
regards |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Apr 29, 2008 2:50 pm |
|
|
#define COL0 (1 << 5) // Pin D5
#define COL1 (1 << 6) // Pin D6
#define COL2 (1 << 7) // Pin D7
#define ROW0 (1 << 1) // Pin D1
#define ROW1 (1 << 2) // Pin D2
#define ROW2 (1 << 3) // Pin D3
#define ROW3 (1 << 4) // Pin D4
There is no connection to Pin D0.
Pins D1, D2, D3, D4 must have a 10K pull-up resistor on each pin. |
|
![](templates/subSilver/images/spacer.gif) |
filjo
Joined: 29 Apr 2008 Posts: 9
|
|
Posted: Tue Apr 29, 2008 3:13 pm |
|
|
Hi
I dont know how I can thanks your help.... thanks
one question:
KBD.C for my case stay:
Quote: |
// Un-comment the following define to use port B
// #define use_portb_kbd TRUE
// Make sure the port used has pull-up resistors (or the LCD) on
// the column pins
#if defined(__PCH__)
#if defined use_portb_kbd
#byte kbd = 0xF81 // This puts the entire structure
#else
#byte kbd = 0xF83 // This puts the entire structure
#endif
#else
#if defined use_portb_kbd
#byte kbd = 6 // on to port B (at address 6)
#else
#byte kbd = 8 // on to port D (at address 8)
#endif
#endif
#if defined use_portb_kbd
#define set_tris_kbd(x) set_tris_b(x)
#else
#define set_tris_kbd(x) set_tris_d(x)
#endif
//Keypad connection: (for example column 0 is B2)
// Bx:
#ifdef blue_keypad ///////////////////////////////////// For the blue keypad
#define COL0 (1 << 2)
#define COL1 (1 << 3)
#define COL2 (1 << 6)
#define ROW0 (1 << 4)
#define ROW1 (1 << 7)
#define ROW2 (1 << 1)
#define ROW3 (1 << 5)
#else ////////////////////////////////////////////////// For the black keypad
#define COL0 (1 << 5) //PIN D5
#define COL1 (1 << 6) //PIN D6
#define COL2 (1 << 7) //PIN D7
#define ROW0 (1 << 1) //PIN D1
#define ROW1 (1 << 2) //PIN D2
#define ROW2 (1 << 3) //PIN D3
#define ROW3 (1 << 4) //PIN D4
#endif
#define ALL_ROWS (ROW0|ROW1|ROW2|ROW3)
#define ALL_PINS (ALL_ROWS|COL0|COL1|COL2)
// 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() {
}
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 : set_tris_kbd(ALL_PINS&~COL0);
kbd=~COL0&ALL_PINS;
break;
case 1 : set_tris_kbd(ALL_PINS&~COL1);
kbd=~COL1&ALL_PINS;
break;
case 2 : set_tris_kbd(ALL_PINS&~COL2);
kbd=~COL2&ALL_PINS;
break;
}
if(kbd_down) {
if((kbd & (ALL_ROWS))==(ALL_ROWS)) {
kbd_down=FALSE;
kchar=last_key;
last_key='\0';
}
} else {
if((kbd & (ALL_ROWS))!=(ALL_ROWS)) {
if((kbd & ROW0)==0)
row=0;
else if((kbd & ROW1)==0)
row=1;
else if((kbd & ROW2)==0)
row=2;
else if((kbd & ROW3)==0)
row=3;
last_key =KEYS[row][col];
kbd_down = TRUE;
} else {
++col;
if(col==3)
col=0;
}
}
kbd_call_count=0;
}
set_tris_kbd(ALL_PINS);
return(kchar);
|
I need delete firsts defines of COLs and ROWs?
but if you dont import you can explain me how you know this pinout? I like understand more about this driver.
this is for an car alarm whitch car locator... I stay make an prototype ;)
you can see more about my projects on http://filjoa.myvnc.com
regards |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Apr 29, 2008 4:12 pm |
|
|
Quote: | I need delete firsts defines of COLs and ROWs? |
No. The 'blue_keyboard' constant is not defined anywhere, so
the code for it will not be compiled. Instead, the code for the
"black keyboard" will be compiled.
Quote: | can explain me how you know this pinout? |
Look at these statements:
Code: |
#define COL0 (1 << 5) //PIN D5
#define COL1 (1 << 6) //PIN D6
#define COL2 (1 << 7) //PIN D7
#define ROW0 (1 << 1) //PIN D1
#define ROW1 (1 << 2) //PIN D2
#define ROW2 (1 << 3) //PIN D3
#define ROW3 (1 << 4) //PIN D4
|
The expression (1 << 5) defines a bitmask. It means 0b00000001
shifted left by 5 bit positions. It's the same as this:
Code: | #define COL0 0b00100000 |
Port D has 8 bits: D7 D6 D5 D4 D3 D2 D1 D0
Each bit corresponds to an i/o pin on Port D.
A bit in the following position corresponds to bit 5, which is pin D5 on Port D:
Code: | #define COL0 0b00100000 |
|
|
![](templates/subSilver/images/spacer.gif) |
filjo
Joined: 29 Apr 2008 Posts: 9
|
|
Posted: Tue Apr 29, 2008 6:54 pm |
|
|
Hi
now I understand... thanks
best regards PCM programmer, you are a crak ;) |
|
![](templates/subSilver/images/spacer.gif) |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|