Hola a todos,
Tengo problemas de estabilidad en un montaje con un teclado 4x4, aparentemente debidos a ruido y/o a errores de control en el codigo. El circuito consiste en un 18F452, un teclado 4x4 y un lcd 2x16. Esta montado sobre una placa perforada y las conexiones con wire-wrapping. La alimentación ésta regulada por un 7805 con un condensador de 470 nF a la entrada y uno de 47 uF junto a otro de 100nF a la salida del regulador. El programa que corre sobre el pic esta escrito en C para CSS y basado en los drivers kbd.c, modificado para teclado 4x4, y lcd.c sin modificar . El “main” esta basado en el exlcdkb.c que incorpora el CSS y simplemente debe mostrar la tecla pulsada en el LCD (adjunto el codigo al final).
Pues bien, resulta que el sistema funciona correctamente a veces y otras no. Al alimentar el circuito el LCD muestra el mensaje “Ready ...” y queda a la espera de que se pulse una tecla. A veces funciona a la perfección pero otras simplemente con acercar la mano a la parte inferior del teclado el sistema se inestabiliza y empieza a sacar una cadena de símbolos como si efectivamente se estuviese pulsando una tecla aunque no se haya pulsado ninguna. Si reseteo queda otra vez en espera y a veces tras el reset ya arranca con la inestabilidad descrita hasta que quito la alimentación y la vuelvo a conectar.
He probado posteriormente con apantallar la parte inferior del teclado con una lamina metalica unida a tierra y asi tocando la parte inferior del teclado no se inicia la inestabilidad, pero a cambio empiezan a fallar algunas teclas y otras a escribir caracteres que no le corresponden. Como datos adicionales decir que las columnas del teclado tienen conectadas resistencias de pull-up, que el teclado esta en el puerto B del pic y el lcd en el D, con un cristal de 20 Mhz. Tambien he probado a filtar la alimentación a las resistencias de pull-up con un condensador lo mas cerca posible de ellas y a nivel de codigo probar diferentes valores de KBD_DEBOUNCE_FACTOR en kbd.c entre 33 y 100 para ver la influencia de la frecuencia de escaneo del teclado, mejorando con el valor superior, pero siguiendo la estabilidad descrita.
Les agradeceria me pudiesen dar alguna indicació para la solución de este problema.
Saludos cordiales,
======================================================
KBD.C
////////////////// The following defines the keypad layout on port D
// 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

#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:
#define COL0 (1 << 4)
#define COL1 (1 << 5)
#define COL2 (1 << 6)
#define COL3 (1 << 7)
#define ROW0 (1 << 0)
#define ROW1 (1 << 1)
#define ROW2 (1 << 2)
#define ROW3 (1 << 3)
#define ALL_ROWS (ROW0|ROW1|ROW2|ROW3)
#define ALL_PINS (ALL_ROWS|COL0|COL1|COL2|COL3)
// Keypad layout:
char const KEYS[4][4] = {{"1","2","3","C"},
{"4","5","6","D"},
{"7","8","9","E"},
{"A","0","B","F"}};
#define KBD_DEBOUNCE_FACTOR 1 // 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=" ";
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;
case 3 : set_tris_kbd(ALL_PINS&~COL3);
kbd=~COL3&ALL_PINS;
break;
}
if(kbd_down) {
if((kbd & (ALL_ROWS))==(ALL_ROWS)) {
kbd_down=FALSE;
kchar=last_key;
last_key=" ";
}
} 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==4)
col=0;
}
}
kbd_call_count=0;
}
set_tris_kbd(ALL_PINS);
return(kchar);
}
==============================================================
“MAIN”
#include <18F452.h>
#fuses HS,NOPROTECT, NOBROWNOUT,NOWDT,PUT,NODEBUG,NOLVP
#use delay(clock=20000000)
#include "kbd.c"
#include "lcd.c"
main()
{
char k;
kbd_init();
lcd_init();
lcd_putc("fReady...
"

;
while(true) {
k=kbd_getc();
if(k!=0)
if(k=="F")
lcd_putc("f");
else
lcd_putc(k);
}
return 0;
}