CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

flexible 4x4 keypad driver

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
krantz
Guest







flexible 4x4 keypad driver
PostPosted: Thu Feb 08, 2007 8:01 am     Reply with quote

Hi to all!
Anyone used this driver within isr ( in my case INT_RB).
I can input only keys on first column (col0).
Any help?
Thanks

Krantz
treitmey



Joined: 23 Jan 2004
Posts: 1094
Location: Appleton,WI USA

View user's profile Send private message Visit poster's website

PostPosted: Thu Feb 08, 2007 9:25 am     Reply with quote

Does it display results, but the wrong letter. OR nothing at all?
krantz
Guest







PostPosted: Thu Feb 08, 2007 11:16 pm     Reply with quote

Hi!
here the code in which during main, I to focus on keyboard input, it do a simple task.
The driver see only key press on first column of the matrix (col0) inputting however the right charachters ( I have '1' , '4' , '7' , 'A').

If I insert the call to kbd_getc(); directly in main ( as in the original example) without use of interrupt (int_rb) the driver work fine inputting all chars.

Many thanks!





#include "C:\Temp\TurboC\Mplab\16f877.h"




//Keypad connection:
#define row0 PIN_B4
#define row1 PIN_B5
#define row2 PIN_B6
#define row3 PIN_B7
#define col0 PIN_B0
#define col1 PIN_B1
#define col2 PIN_B2
#define col3 PIN_B3



char const KEYS[4][4] =
{{'1','2','3','F'},
{'4','5','6','E'},
{'7','8','9','D'},
{'A','0','B','C'}};


#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()
{
//set_tris_b(0xF0);
//output_b(0xF0);
port_b_pullups(true);
}


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);
output_high(col3);
break;

case 1:
output_high(col0);
output_low(col1);
output_high(col2);
output_high(col3);
break;

case 2:
output_high(col0);
output_high(col1);
output_low(col2);
output_high(col3);
break;

case 3:
output_high(col0);
output_high(col1);
output_high(col2);
output_low(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()
{
enable_interrupts(GLOBAL);

enable_interrupts(INT_RB);



kbd_init();

printf("\r\Starting ...");

while(TRUE)
{



output_high(PIN_d0);
delay_ms(300);
output_low(PIN_d0);
delay_ms(300);
}

}




#int_rb

int_rb_isr()


{

char k;

k=kbd_getc();
if(k!=0)
{
if(k=='*')
printf("%c", '*');
else
printf("%c", k);
}

}
treitmey



Joined: 23 Jan 2004
Posts: 1094
Location: Appleton,WI USA

View user's profile Send private message Visit poster's website

PostPosted: Fri Feb 09, 2007 8:35 am     Reply with quote

If it works by itself but not with the IRQ, then that would seem to be the problem.

Your int_Rb works by seeing a change on the upper nibble of port b. B4-B7...the rows
so in normal operation:
1. upper bits of port b are pulled up. These are the rows.
2. column are outputted as 0.
3. you press a key that will connect a row to column. That pulls a single row line to ground(0). That row(B4-B7) is seen by the IRQ. Then you can read/decode it.

I see you have two lines commented out in kpd_init.

Are you seeing any place in the code that doesn't look correct.
krantz
Guest







PostPosted: Sun Feb 11, 2007 11:57 pm     Reply with quote

Hi treitmey,
sorry for delay, but week end....!

The lines in keyb_init are commented in the original version of the driver and I got it as was, but after some tests it seems they shall be set in that mode to do work the driver .

To check for irq involvement on the problem, I've removed the int_rb and inserted the call to kbd_getc directly in main as shown.

In this test the driver doesn't capture any key press not even the keys on col0.

The only way I found to do work the driver is to remove also the on-off delay on
pin D0 as shown, and then the driver capture properly all the key presses .

I don't understand well how the driver works but it seems that it needs several passes to reach the condition (kbd_call_count>KBD_DEBOUNCE_FACTOR) and then decode the key.

Pheraps during the irq it doesn't has this chance, but I don't understand in the case of the on-off on pin D0 what could be the bug (perhaps the key press time width is less than 300+300 ms delay inserted !) .

Thanks again for support,

Krantz




#include "C:\Temp\TurboC\Mplab\16f877.h"




//Keypad connection:
#define row0 PIN_B4
#define row1 PIN_B5
#define row2 PIN_B6
#define row3 PIN_B7
#define col0 PIN_B0
#define col1 PIN_B1
#define col2 PIN_B2
#define col3 PIN_B3



char const KEYS[4][4] =
{{'1','2','3','F'},
{'4','5','6','E'},
{'7','8','9','D'},
{'A','0','B','C'}};


#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()
{
//set_tris_b(0xF0);
//output_b(0xF0);
port_b_pullups(true);
}


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);
output_high(col3);
break;

case 1:
output_high(col0);
output_low(col1);
output_high(col2);
output_high(col3);
break;

case 2:
output_high(col0);
output_high(col1);
output_low(col2);
output_high(col3);
break;

case 3:
output_high(col0);
output_high(col1);
output_high(col2);
output_low(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()
{



kbd_init();

printf("\r\Starting ...");

while(TRUE)
{

char k;

k=kbd_getc();
if(k!=0)
{
if(k=='*')
printf("%c", '*');
else
printf("%c", k);


//output_high(PIN_d0);
//delay_ms(300);
//output_low(PIN_d0);
//delay_ms(300);
}

}

}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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