#include <16F876.h>
#fuses XT,NOWDT,NOPUT,NOPROTECT
#use delay(clock=4000000)
#use standard_io(b)
#include <lcd_portb.c>
/******************************************************************************/
//Definicion de variables.
int1 cambio,start,dato_recibido;
int tiempo,longitud,i,j,command,address;
int16 word;
/*****************************************************************************/
#INT_EXT
void ext_isr(){
if(cambio){
set_timer0(0);
tiempo=0;
EXT_INT_EDGE(L_TO_H);
cambio=1;
}else{
tiempo=get_timer0();
EXT_INT_EDGE(H_TO_L);
cambio=0;
}
if((tiempo>140) && (tiempo<160)){ //"Start", si está entre 2240 y 2560 us.
start=1; //Flag start activado.
i=0; //contador de bits a 0.
}
if(start){
if((tiempo>27) && (tiempo<55)){ //Entre 432 y 880 us, es cero.
bit_clear(word,i);
i++;
}
if((tiempo>65) && (tiempo<90)){ //Entre 1040 y 1440 us es uno.
bit_set(word,i);
i++;
}
}
if(i==longitud){
dato_recibido=1;
EXT_INT_EDGE(H_TO_L);
start=0; //para reiniciar lectura.
}
}
/******************************************************************************/
//Rutinas de separacion de comando y direccion.
void take_address(void){
i=longitud-1;
address=0;
for(j=0;j<longitud-7;j++){
address= address<<1;
address=address+bit_test(word,i);
i--;
}
}
void take_command(void){
i=6;
command=0;
for(j=0;j<7;j++){
command=command<<1;
command=command+bit_test(word,i);
i--;
}
}
/******************************************************************************/
void main(){
port_b_pullups(TRUE); //Pull-up para RB0
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_16); //configuracion del timer0.
lcd_init();
ext_int_edge(H_TO_L); //En canto de bajada se activa int.
cambio=0; //control de cambio, para que comience a contar.
longitud=0x0B; //para los 12 bits de la palabra
enable_interrupts(int_ext); //habilita la interrupcion externa (Rb0).
if(start){
while(dato_recibido){ //en el prgrma original aparecia "while(!dato_recibido)" pero no le encontre sentido, ya que al recibir data, se pone a 1
dato_recibido=0;
DISABLE_INTERRUPTS(INT_EXT);
take_address();
take_command();
lcd_gotoxy(0,0);
switch(command){
case 0: printf(lcd_putc,"\fCanal 1");break;
case 1: printf(lcd_putc,"\fCanal 2");break;
case 2: printf(lcd_putc,"\fCanal 3");break;
case 3: printf(lcd_putc,"\fCanal 4");break;
case 4: printf(lcd_putc,"\fCanal 5");break;
case 5: printf(lcd_putc,"\fCanal 6");break;
case 6: printf(lcd_putc,"\fCanal 7");break;
case 7: printf(lcd_putc,"\fCanal 8");break;
case 8: printf(lcd_putc,"\fCanal 9");break;
case 9: printf(lcd_putc,"\fCanal 0");break;
case 16: printf(lcd_putc,"\fCanal +");break;
case 17: printf(lcd_putc,"\fCanal -");break;
case 18: printf(lcd_putc,"\fVolumen +");break;
case 19: printf(lcd_putc,"\fVolumen -");break;
case 20: printf(lcd_putc,"\fSilencio");break;
case 47: printf(lcd_putc,"\fStandBy");break;
default: printf(lcd_putc,"\fCom:%3U Adr:%2U",command,address);
}
ENABLE_INTERRUPTS(INT_EXT);
}
}
}