|
|
View previous topic :: View next topic |
Author |
Message |
kd5uzz
Joined: 28 May 2006 Posts: 56
|
16F88 4x4 flex_keypad decoder lockup |
Posted: Mon Apr 16, 2007 6:52 pm |
|
|
I'm using the following code to decode a 4x4 keypad using flex_keypad4x4 driver found elsewhere on this forum. My PIC seems to lockup at a random interval, sometimes I can press buttons for as long as one minute or more, other times only two or three key presses. Every now and then the LED on B7 stays on for a little longer than 200ms, but then it goes out just like I expect. It seems to lockup more frequently if I have it connected to the SPI master. It seems I can't use my PICKIT2 as a debugger, so I have no idea where to start to find this problem. Any help would be welcome!
Note in the first picture there is actually an LED on 13, as shown in the 2nd picture.
Code: |
#include <16F88>
#fuses INTRC_IO
#fuses NOWDT, BROWNOUT, NOLVP
#use delay(clock=8000000)
#use rs232(baud=2400,xmit=PIN_B3,rcv=PIN_B3,ERRORS)
#include <flex_keypad_4x4.c>
//******************************
// Functions
//******************************
//******************************
// Global Defs
//******************************
//******************************
// Code
//******************************
void main(){
char k;
int BP = 0;
output_high(PIN_B7);
delay_ms(1000);
output_low(PIN_B7);
kbd_init();
delay_ms(5);
printf("\r\Starting ...");
while(TRUE){
k=kbd_getc();
if(k!=0){
output_high(PIN_B7);
printf("Key: %i = '%c'\n\r",k,k);
delay_ms(200);
output_low(PIN_B7);
}
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Apr 17, 2007 1:36 am |
|
|
1. You need a series resistor between the PIC pin and the LED, to limit
the current from the PIC's pin driver to a level that's within spec.
Use a resistor value in the range from 220 to 470 ohms.
2. You have question marks on the MCLR resistor. I don't know
anything about the PICkit. But for the ICD2, you should use a 10K
pullup on MCLR and for the CCS ICD-U40, you should use 47K.
What's your compiler version ? |
|
|
kd5uzz
Joined: 28 May 2006 Posts: 56
|
|
Posted: Tue Apr 17, 2007 3:01 pm |
|
|
Quote: | 1. You need a series resistor between the PIC pin and the LED, to limit
the current from the PIC's pin driver to a level that's within spec.
Use a resistor value in the range from 220 to 470 ohms.
|
Thanks for catching that error, its not in the schematic but it was on the breadboard. (330ohm)
Quote: |
2. You have question marks on the MCLR resistor. I don't know
anything about the PICkit. But for the ICD2, you should use a 10K
pullup on MCLR and for the CCS ICD-U40, you should use 47K.
|
I was using ~30k, switched to a 47k, seems to be more stable, but I still have the same problem. It's almost like a counter is overflowing, but I don't see it.
Quote: |
What's your compiler version ? |
3.222
Below is (your?) code for the 4x4 keypad. I don't think I've changed anything except the keymap.
Code: |
//=============================
//Keypad connection:
#define row0 PIN_A1
#define row1 PIN_A0
#define row2 PIN_A7
#define row3 PIN_A6
#define col0 PIN_A2
#define col1 PIN_A3
#define col2 PIN_A4
#define col3 PIN_B0
// Keypad layout:
char const KEYS[4][4] =
{{'1','2','3','U'},
{'4','5','6','D'},
{'7','8','9','N'},
{'C','0','H','E'}};
#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);
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);
}
//===========================
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Apr 17, 2007 3:47 pm |
|
|
You need pull-up resistors on the keypad's Row pins. Your schematic
shows series resistors. You need to remove those and change them
to pull-ups. You can use 4.7K or 10K. |
|
|
kd5uzz
Joined: 28 May 2006 Posts: 56
|
|
Posted: Tue Apr 17, 2007 4:57 pm |
|
|
I think I need to go over my project's schematic a little better, the resistors are in fact pullups, not series. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Apr 17, 2007 5:05 pm |
|
|
They look like series resistors to me.
This is a series resistor. This is what your schematic shows:
Code: |
PIC pin ------/\/\/\/-------- Keypad pin
|
This is a pull-up resistor:
Code: |
+5v ---/\/\/\/---
|
|
PIC pin ------------o---------- Keypad pin
|
|
|
|
kd5uzz
Joined: 28 May 2006 Posts: 56
|
|
Posted: Tue Apr 17, 2007 6:01 pm |
|
|
I understand. I have them wired on the bread board as pull-ups, but I was rushing when I created the schematic and drew it wrong. |
|
|
Guest
|
|
Posted: Tue Apr 17, 2007 10:02 pm |
|
|
Schematic updated |
|
|
|
|
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
|