// Las funciones que contiene la librería son las siguientes:
//
// void Kbd_init(void); // Inicializa el teclado matricial, esta función hay que llamarla antes de poder usar el teclado.
// Función que usaremos solo si usamos el puerto B.
// char kbd_getc(void); // Función que retorna el caracter de la tecla pulsada.
// CONDICIONES: Es posible usar cualquier puerto del PIC ya sea el B,C,D..etc, teniendo en cuenta
// como trabaja la librería. Para que funcione correctamente el teclado tiene que tener conectado las resistencias pull - up
// en las columnas y filas...si usamos el puerto B, esto no es necesario debido a que tiene pull-up internas.
#define use_portb_kbd TRUE // Declaramos el uso del puerto B del PIC para conectar nuestro teclado.
#define PUERTO_PIC18 0xF83 // Puerto D. (PODEMOS PONER CUALQUIERA QUE CUMPLA CON LAS CONDICIONES).
#if defined(__PCH__) // Si trabajamos con PIC18...
#if defined use_portb_kbd // Si hemos definido el puerto B para trabajar...
#byte kbd = 0xF81 // Dirección PORTB = 0xF81.
#else // Caso contrario...
#byte kbd = PUERTO_PIC18 // Trabajamos con el puerto elejido...
#endif
#endif
#if defined use_portb_kbd // Si hemos definido el puerto B para trabajar...
#define set_tris_kbd(x) set_tris_b(x) // La configuración del teclado se hará según el registro "TRIS" del puerto B.
#else // si no...
#define set_tris_kbd(x) set_tris_d(x) // La configuración del teclado se hará según el registro "TRIS" del puerto elejido.
#endif
// Definimos columnas y filas usadas.
// Nota: Cuando dice (1 << 1) , quiere decir PUERTO << PIN DEL PUERTO
// Ejemplo: Si puerto B.... COL0 (PORTB << PIN_B1).
#define COL0 (1 << 1) // Columna 1, puerto B1.
#define COL1 (1 << 2) // Columna 2, puerto B2.
#define COL2 (1 << 3) // Columna 3, puerto B3.
#define ROW0 (1 << 4) // Fila 1, puerto B4.
#define ROW1 (1 << 5) // Fila 1, puerto B5.
#define ROW2 (1 << 6) // Fila 1, puerto B6.
#define ROW3 (1 << 7) // Fila 1, puerto B7.
#define ALL_ROWS (ROW0|ROW1|ROW2|ROW3)
#define ALL_PINS (ALL_ROWS|COL0|COL1|COL2)
// Distribución de las teclas.
char const KEYS[4][3] = {{'1','2','3'}, // Es posible poner cualquier caracter disponible...para HID
{'4','5','6'}, // hay que traducir el valor del caracter para ser enviado por USB...
{'7','8','9'}, // Los caracteres "*" y "#" no tenían traducción directa viable...por lo que se implementó
{'a','0','b'}}; // los caraceres a y b.
#define KBD_DEBOUNCE_FACTOR 5 // Cantidad de iteraciones que se hacen para leer la matriz, está directamente relacionado con la
// velocidad y la estabilidad de datos mostrados. Para la mejor estabilidad/velocidad del teclado
// se ha configurado el valor en 5..(recomendado no cambiarlo).
void kbd_init(void){ // Función implementada solo si se usa el puerto B.
port_b_pullups(TRUE); // Activamos las resistencias pull - up del puerto B.
}
// Función que entrega el caracter de la tecla pulsada.
char kbd_getc(void) {
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);
}