La verdad me da flojera revisar la librería del teclado de CCS. Mejor te pongo una que me elaboré para no tener problemas a la hora de modificar.
Código:
/***************** teclado.h ******************/
#byte PORTA = getenv("sfr:PORTA")
#byte TRISA = getenv("sfr:TRISA")
#byte PORTB = getenv("sfr:PORTB")
#byte TRISB = getenv("sfr:TRISB")
#byte PORTC = getenv("sfr:PORTC")
#byte TRISC = getenv("sfr:TRISC")
#byte PORTD = getenv("sfr:PORTD")
#byte TRISD = getenv("sfr:TRISD")
#byte PORTE = getenv("sfr:PORTE")
#byte TRISE = getenv("sfr:TRISE")
/***************************************/
#define PORT_fila0 PORTC
#define TRIS_fila0 TRISC
#define fila0 0
#define PORT_fila1 PORTC
#define TRIS_fila1 TRISC
#define fila1 1
#define PORT_fila2 PORTC
#define TRIS_fila2 TRISC
#define fila2 2
#define PORT_fila3 PORTC
#define TRIS_fila3 TRISC
#define fila3 3
#define PORT_columna0 PORTC
#define TRIS_columna0 TRISC
#define columna0 4
#define PORT_columna1 PORTC
#define TRIS_columna1 TRISC
#define columna1 5
#define PORT_columna2 PORTC
#define TRIS_columna2 TRISC
#define columna2 6
#define PORT_columna3 PORTC
#define TRIS_columna3 TRISC
#define columna3 7
/*************************************************/
#ifdef teclado_activoalto
#define es_activo(r,b) bit_test(r,b)
#define activar(r,b) bit_set(r,b)
#define desactivar(r,b) bit_clear(r,b)
#else
#ifdef teclado_activobajo
#define es_activo(r,b) !bit_test(r,b)
#define activar(r,b) bit_clear(r,b)
#define desactivar(r,b) bit_set(r,b)
#else
#error "Debe declarar la lógica del teclado: activo alto o activo bajo"
#endif
#endif
/***************************************************/
void teclado_inicializa(void)
{
// Inicializa los latches de salida para las filas.
activar(PORT_fila0,fila0);
activar(PORT_fila1,fila1);
activar(PORT_fila2,fila2);
activar(PORT_fila3,fila3);
// Configura las filas como salidas.
bit_clear(TRIS_fila0,fila0);
bit_clear(TRIS_fila1,fila1);
bit_clear(TRIS_fila2,fila2);
bit_clear(TRIS_fila3,fila3);
// Configura las columnas como entradas
bit_set(TRIS_columna0,columna0);
bit_set(TRIS_columna1,columna1);
bit_set(TRIS_columna2,columna2);
bit_set(TRIS_columna3,columna3);
}
void teclado_activafilas(void)
{
activar(PORT_fila0,fila0);
activar(PORT_fila1,fila1);
activar(PORT_fila2,fila2);
activar(PORT_fila3,fila3);
}
int8 teclado_examinacolumnas(void)
{
if(es_activo(PORT_columna0,columna0)) return 0;
if(es_activo(PORT_columna1,columna1)) return 1;
if(es_activo(PORT_columna2,columna2)) return 2;
if(es_activo(PORT_columna3,columna3)) return 3;
return 4;
}
char teclado_lee(void)
{
const char teclas[16]={'0', '1', '2', '3',
'4', '5', '6', '7',
'8', '9', 'A', 'B',
'C', 'D', 'E', 'F'};
int8 i;
teclado_activafilas();
for(i=0; i<20; i++)
{
if(teclado_examinacolumnas()>3) return 0;
delay_ms(1);
}
desactivar(PORT_fila3,fila3);
desactivar(PORT_fila2,fila2);
desactivar(PORT_fila1,fila1);
if((i=teclado_examinacolumnas())<4) return(teclas[i]);
desactivar(PORT_fila0,fila0);
activar(PORT_fila1,fila1);
if((i=teclado_examinacolumnas())<4) return(teclas[i+4]);
desactivar(PORT_fila1,fila1);
activar(PORT_fila2,fila2);
if((i=teclado_examinacolumnas())<4) return(teclas[i+8]);
desactivar(PORT_fila2,fila2);
activar(PORT_fila3,fila3);
if((i=teclado_examinacolumnas())<4) return(teclas[i+12]);
desactivar(PORT_fila3,fila3);
return 0;
}
void teclado_esperalibere(void)
{
teclado_activafilas();
while(teclado_examinacolumnas()<4);
}
#byte PORTA = getenv("sfr:PORTA")
#byte TRISA = getenv("sfr:TRISA")
#byte PORTB = getenv("sfr:PORTB")
#byte TRISB = getenv("sfr:TRISB")
#byte PORTC = getenv("sfr:PORTC")
#byte TRISC = getenv("sfr:TRISC")
#byte PORTD = getenv("sfr:PORTD")
#byte TRISD = getenv("sfr:TRISD")
#byte PORTE = getenv("sfr:PORTE")
#byte TRISE = getenv("sfr:TRISE")
/***************************************/
#define PORT_fila0 PORTC
#define TRIS_fila0 TRISC
#define fila0 0
#define PORT_fila1 PORTC
#define TRIS_fila1 TRISC
#define fila1 1
#define PORT_fila2 PORTC
#define TRIS_fila2 TRISC
#define fila2 2
#define PORT_fila3 PORTC
#define TRIS_fila3 TRISC
#define fila3 3
#define PORT_columna0 PORTC
#define TRIS_columna0 TRISC
#define columna0 4
#define PORT_columna1 PORTC
#define TRIS_columna1 TRISC
#define columna1 5
#define PORT_columna2 PORTC
#define TRIS_columna2 TRISC
#define columna2 6
#define PORT_columna3 PORTC
#define TRIS_columna3 TRISC
#define columna3 7
/*************************************************/
#ifdef teclado_activoalto
#define es_activo(r,b) bit_test(r,b)
#define activar(r,b) bit_set(r,b)
#define desactivar(r,b) bit_clear(r,b)
#else
#ifdef teclado_activobajo
#define es_activo(r,b) !bit_test(r,b)
#define activar(r,b) bit_clear(r,b)
#define desactivar(r,b) bit_set(r,b)
#else
#error "Debe declarar la lógica del teclado: activo alto o activo bajo"
#endif
#endif
/***************************************************/
void teclado_inicializa(void)
{
// Inicializa los latches de salida para las filas.
activar(PORT_fila0,fila0);
activar(PORT_fila1,fila1);
activar(PORT_fila2,fila2);
activar(PORT_fila3,fila3);
// Configura las filas como salidas.
bit_clear(TRIS_fila0,fila0);
bit_clear(TRIS_fila1,fila1);
bit_clear(TRIS_fila2,fila2);
bit_clear(TRIS_fila3,fila3);
// Configura las columnas como entradas
bit_set(TRIS_columna0,columna0);
bit_set(TRIS_columna1,columna1);
bit_set(TRIS_columna2,columna2);
bit_set(TRIS_columna3,columna3);
}
void teclado_activafilas(void)
{
activar(PORT_fila0,fila0);
activar(PORT_fila1,fila1);
activar(PORT_fila2,fila2);
activar(PORT_fila3,fila3);
}
int8 teclado_examinacolumnas(void)
{
if(es_activo(PORT_columna0,columna0)) return 0;
if(es_activo(PORT_columna1,columna1)) return 1;
if(es_activo(PORT_columna2,columna2)) return 2;
if(es_activo(PORT_columna3,columna3)) return 3;
return 4;
}
char teclado_lee(void)
{
const char teclas[16]={'0', '1', '2', '3',
'4', '5', '6', '7',
'8', '9', 'A', 'B',
'C', 'D', 'E', 'F'};
int8 i;
teclado_activafilas();
for(i=0; i<20; i++)
{
if(teclado_examinacolumnas()>3) return 0;
delay_ms(1);
}
desactivar(PORT_fila3,fila3);
desactivar(PORT_fila2,fila2);
desactivar(PORT_fila1,fila1);
if((i=teclado_examinacolumnas())<4) return(teclas[i]);
desactivar(PORT_fila0,fila0);
activar(PORT_fila1,fila1);
if((i=teclado_examinacolumnas())<4) return(teclas[i+4]);
desactivar(PORT_fila1,fila1);
activar(PORT_fila2,fila2);
if((i=teclado_examinacolumnas())<4) return(teclas[i+8]);
desactivar(PORT_fila2,fila2);
activar(PORT_fila3,fila3);
if((i=teclado_examinacolumnas())<4) return(teclas[i+12]);
desactivar(PORT_fila3,fila3);
return 0;
}
void teclado_esperalibere(void)
{
teclado_activafilas();
while(teclado_examinacolumnas()<4);
}
Antes de incluir la librería debes declarar:
Código:
#use delay(clock=xxxx)
También debes declarar previamente la lógica del teclado, por ejemplo:
Código:
#define teclado_activoalto
o el otro caso:
Código:
#define teclado_activobajo
Si en las columnas colocas resistencias de pullup (hacia Vcc) la lógica debe ser activo bajo. Si en las columnas colocas resistencias de pulldown (hacia GND) la lógica debe ser activo alto.
Todas y cada una de las filas y columnas son colocables en cualquier terminal de cualquier puerto.
Así, si colocas la fila 0 del teclado en la terminal RA5, la declaración debe quedar así:
Código:
#define PORT_fila0 PORTA
#define TRIS_fila0 TRISA
#define fila0 5
#define TRIS_fila0 TRISA
#define fila0 5
Para leer una tecla debes invocar a la función teclado_lee(). Esta función retornará un 0 binario (caracter nulo) si no hay tecla pulsada. En caso contrario retornará el código ASCII de la tecla pulsada.
Debes invocar la función teclado_esperalibere() para esperar que se libere la tecla y evitar leer varias veces la misma tecla.
Te dejo el siguiente programa de ejemplo:
Código:
#include "16f877a.h"
#use delay(clock=20M)
#define teclado_activobajo
#include "teclado.h"
#define use_portb_lcd
#include "lcd.c"
int main(void)
{
char tecla;
teclado_inicializa();
lcd_init();
while(1)
{
if(tecla=teclado_lee())
{
lcd_putc(tecla);
teclado_esperalibere();
}
}
}
Nos vemos...#use delay(clock=20M)
#define teclado_activobajo
#include "teclado.h"
#define use_portb_lcd
#include "lcd.c"
int main(void)
{
char tecla;
teclado_inicializa();
lcd_init();
while(1)
{
if(tecla=teclado_lee())
{
lcd_putc(tecla);
teclado_esperalibere();
}
}
}