#include <16F1823.h>
#device adc=8
#FUSES NOFCMEN //NO fail safe clock monitor
#FUSES NOIESO //NO internal external switchover
#FUSES NOBROWNOUT //NO brownout reset
#FUSES CPD //NO eeprom protegido de lecturas
#FUSES PROTECT //NO codigo protegido de lecturas
#FUSES NOMCLR //NO mclr
#FUSES PUT //power up timer
#FUSES NOWDT //NO watch dog timer
#FUSES INTRC_IO //oscilador interno, pines CLK como I/O
#use delay(clock=8000000) //clock de 8Mhz
#use fast_io(a) //se accede al puerto a como memoria
#use fast_io(c) //se accede al puerto c como memoria
//Direcciones de registros
#byte PORTA = 0x0C
#byte PORTC = 0x0E
#byte OPT_REG = 0x95
#bit INTEDG = OPT_REG.6 //direccion de int edge selection bit. 1=RISING, 0=FALLING
//--- Puertos ---
//0b11111110
//#define TX PIN_A0
//#define RX PIN_A1
#bit RF_IN = PORTA.2
#bit A3 = PORTA.3
#bit A4 = PORTA.4
#bit A5 = PORTA.5
//0b11111011
#bit C0 = PORTC.0
#bit C1 = PORTC.1
#bit LED = PORTC.2
#bit C3 = PORTC.3
#bit C4 = PORTC.4
#bit C5 = PORTC.5
//---------------
//--- Constantes ---
#define LOW 0 //pulso low
#define HIGH 1 //pulso high
#define FALLING 0 //falling edge
#define RISING 1 //rising edge
//------------------
//---Porcentajes del pulso HIGH sobre el pulso completo
#define MIN_CERO 15
#define CERO 25
#define MAX_CERO 35
#define MIN_UNO 65
#define UNO 75
#define MAX_UNO 85
#define MIN_SYNC 1
#define SYNC 3.125
#define MAX_SYNC 5
//--------------------------
short flagPulso = FALSE; //indica cuando se produjo un flanco
short Direccion[24]; //variable que almacena la direccion recibida (24 bits)
int Bits_Contados = 0; //numero de bits contados
int Duty = 0; //porcentaje de pulso alto sobre la duracion del pulso
long TiempoHigh = 0; //tiempo medido de la parte HIGH del pulso
long TiempoTot = 0; //tiempo total del pulso (high y low)
//-----------------
// --- INT EXT ---
#int_EXT
void EXT_isr(void) {
if(INTEDG == RISING){ //flanco ascendente, empieza el pulso
TiempoTot = get_timer1(); //obtiene la duracion total del pulso anterior
set_timer1(0); //resetea el timer
flagPulso = TRUE; //indica que leyo un pulso completo
}
else{ //flanco descendente, termina la parte HIGH del pulso
TiempoHigh = get_timer1(); //lee cuanto duro el pulso HIGH
}
INTEDG = !INTEDG; //invierte el flanco
}
// ---------------
void main(void) {
setup_wdt(WDT_OFF); //configuracion wdt
setup_timer_0(T0_INTERNAL|RTCC_DIV_1); //configuracion timer0
setup_timer_1(T1_INTERNAL|T1_DIV_BY_2); //configuracion timer1
setup_timer_2(T2_DISABLED,0,1); //configuracion timer2
setup_dac(DAC_OFF); //configura DAC
setup_adc(ADC_OFF); //configura ADC
setup_ccp1(CCP_OFF); //configura CCP
setup_spi(FALSE); //configura SPI
setup_comparator(NC_NC_NC_NC); //comparador apagado
setup_vref(FALSE); //no se usa voltaje de referencia
ext_int_edge(L_TO_H); //configura int ext ASCENDENTE
enable_interrupts(INT_EXT); //interrupcion externa
enable_interrupts(GLOBAL); //habilita las interrupciones
setup_oscillator(OSC_8MHZ|OSC_INTRC); //configura oscilador interno
set_tris_a(0b11011111); //
set_tris_c(0b11111011); //
do{
if(flagPulso == TRUE){
flagPulso = FALSE;
Duty = ((int32)TiempoHigh * 100) / TiempoTot;
if((MIN_CERO <= Duty) && (Duty <= MAX_CERO)){
shift_right(&Direccion,3,CERO); //coloca el bit recibido en la ultima posicion
if(Bits_Contados < 24) //no suma mas de 24
++Bits_Contados; //suma uno
}
else if((MIN_UNO <= Duty) && (Duty <= MAX_UNO)){
shift_right(&Direccion,3,UNO); //coloca el bit recibido en la ultima posicion
if(Bits_Contados < 24) //no suma mas de 24
++Bits_Contados; //suma uno
}
else if((MIN_SYNC <= Duty) && (Duty <= MAX_SYNC)){
if(Bits_Contados == 24){ //direccion completa?
//direccion correcta
disable_interrupts(GLOBAL);
LED = 1;
delay_ms(300);
LED = 0;
enable_interrupts(GLOBAL);
}
else{ //no se contaron 24 bits
Bits_Contados = 0; //reinicia la recepcion de datos
}
}
else{ //el pulso recibido no es nada esperado
Bits_Contados = 0; //reinicia la recepcion de datos
}
}
}while(true);
}