#include <htc.h>
__CONFIG (LVPDIS & WDTDIS & MCLRDIS & INTIO);
#include "Def16f62xa.h" // algunas definiciones propias para esta familia de PICs
#define PIC_CLK 4000000 // defino la velocidad de trabajo
#include "delayhd.h" // rutinas de retardo
#define set_tris_b(x) TRISB=x
#define output_b(x) PORTB=x
#define set_tris_a(x) TRISA=x
#define output_a(x) PORTA=x
/************************************************************************************************
Todos esos include y define son para poder trabajar con el pic, estoy usando el compilador HiTech
pero tratando de dejar el código lo más parecido posible a CCS
Hay que adaptar la cabecera y parte del programa para que trabaje correctamente con CCS
También la línea __CONFIG (xxxx) hay que cambiarla por el tipo soportado por CCS
**************************************************************************************************/
unsigned char flag_teclado = 0; // variable para saber si se presionó una tecla
unsigned char tecla_pulsada;
/*****************************************
Rutina de delay de aproximadamente 10mS
para usar como anti-rebote
******************************************/
void AntiRebote (void)
{
unsigned char tiempo;
for (tiempo = 40; tiempo > 0; tiempo--)
{
DelayUs (250);
}
}
/************************************************
Esta es la rutina que devuelve la tecla pulsada
Los valores devueltos van de 1 a 16
*************************************************/
unsigned char captura(void)
{
unsigned char teclado[4][4] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
int tecla,lectura,i;
unsigned char fila, columna;
for(i=0;i<4;i++)
{
output_b(0);
// bit_set(port_b,i);
PORTB = (1 << i); // utilizo esto en lugar de bit_set, porque Hitech no tiene dicha funcion
lectura = PORTB & 0xf0;
switch(lectura)
{
case 0b00010000: columna=0;
fila = i;
break;
case 0b00100000: columna=1;
fila = i;
break;
case 0b01000000: columna=2;
fila = i;
break;
case 0b10000000: columna=3;
fila = i;
break;
}
}
tecla = teclado[fila][columna];
return(tecla);
}
/****************************************************************
Esta es la rutina de atención de interrupción que permite Hitech
hay que cambiarla y adaptarla al formato de CCS
******************************************************************/
void interrupt isr (void)
{
unsigned char temporal;
temporal = PORTB & 0xF0;
if (temporal != 0)
{
AntiRebote();
temporal = PORTB & 0xF0;
if (temporal != 0)
{
flag_teclado = 1; // si hay tecla pulsada activo el flag
tecla_pulsada = captura();
}
}
PORTB = 0x0F; // todo el nibble bajo del puerto B en "1"
temporal = PORTB; // leo el puerto B para que ya no exista condición de cambio
RBIF = 0; // borro el flag de cambio de RB. (Adaptar a CCS)
/*
No deshabilito ni vuelvo a habilitar las interrupciones por que
de ello ya se encarga el compilador. Adaptar a CCS si es necesario
*/
}
void main (void)
{
//setup_adc (ADC_OFF);
setup_comparator (NC_NC_NC_NC);
set_tris_a (0); // Puerto A como salida
output_a (0); // todo en 0
set_tris_b (0b11110000); // Nibble alto como entrada, nibble bajo como salida
output_b (0x0F); // Todas las salidas en 1
RBIF = 0; // borro el flag que indica cambio en RB4..RB7
/*
Creo que en CCS se usa clear_interrupt (INT_RB)
*/
enable_interrupt (INT_RB); // habilito interrupción por cambio
enable_interrupt (GLOBAL); // habilito todas las interrupciones
while (1)
{
if (flag_teclado == 1) // si se presionó alguna tecla...
{
output_a (tecla_pulsada); // la muestro en formato binario por el puerto A
flag_teclado = 0;
}
}
}