#include <16f1827.h>
#use delay(clock = 16mhz)
#use rs232(baud=2400, xmit=pin_b2,rcv=pin_b1,stop=2,stream=rs232)
#use rs232(baud=4800, xmit=pin_b0,rcv=pin_b0,stop=2,stream=potencia,timeout=4)
#fuses intrc_io, wdt, put, brownout, nomclr
#byte porta = 0x0c //Definicion de variables del pic
#byte portb = 0x0d
#byte wpua = 0x20c
#byte wpub = 0x20d
#byte option_reg = 0x95
#define dip_sw porta
#define pin_rx bit_test(portb,1)
#define pin_cheq_rf pin_b7
int const dir_potencia = 0b10100010;
int dato_recibido[5];
int con_recibir;
int codigo_tecla;
int direccion;
int con_modo_env;
int con_recibir_rf;
int res_codigo_tecla;
int con_seguridad_rf;
short ban_enviar;
short ban_tmr1;
short ban_pin_rx;
void enviar_dato();
void tiempo_recibir();
void seguridad_rf();
///////////////////////////////////////////////////////////////////////////////
//******************INTERRUPCIONES*********************************************
//*****************************************************************************
//*****************************************************************************
//*****************************************************************************
//*****************************************************************************
//*****************************************************************************
//Vector de interrupcion de la recepcion de datos por el usart
#int_rda
void interrupcion_rx()
{
int respaldo;
output_toggle(pin_cheq_rf);
con_seguridad_rf = 0;
if(con_modo_env == 2)
{
if(respaldo == direccion) {con_recibir_rf = 0;}
return;
}
con_recibir_rf = 0;
if(con_modo_env == 1)
{
codigo_tecla = respaldo;
res_codigo_tecla = respaldo;
con_modo_env = 2;
return;
}
if(respaldo == direccion) {con_modo_env = 1;}
}
///////////////////////////////////////////////////////////////////////////////
//se recibe la comunicación del pic de potencia
#int_ext
void recibir_mando()
{
set_timer2(0);
clear_interrupt(int_timer2);
enable_interrupts(int_timer2);
dato_recibido
[con_recibir
] = getc(potencia
); con_recibir++;
if(con_recibir == 4)
{
con_recibir = 0;
if(dato_recibido[0] == dir_potencia)
{
ban_enviar = 1;
//enviar_dato_pc();
memset(dato_recibido
, 0, sizeof(dato_recibido
)); set_timer1(65536 - 2500);
}
}
}
///////////////////////////////////////////////////////////////////////////////
//vector de interrupcion por desbordamiento del timer 1
#int_timer1
void interrupcion_tmr1()
{
set_timer1(0);
ban_tmr1 = 1;
if(!ban_enviar) {return;}
ban_enviar = 0;
if(codigo_tecla != 0) {enviar_dato();} //si no han presionado tecla no envia
}
///////////////////////////////////////////////////////////////////////////////
//Vector de interrupcion por desbordamiento del timer 2
#int_timer2
void interrupcion_tmr2()
{
con_recibir = 0;
memset(dato_recibido
, 0, sizeof(dato_recibido
)); disable_interrupts(int_timer2);
}
///////////////////////////////////////////////////////////////////////////////
//******************PROGRAMA GENERAL*******************************************
//*****************************************************************************
//*****************************************************************************
//*****************************************************************************
//*****************************************************************************
#zero_ram //Borrado de la memoria ram
void main() //Rutina principal
{
set_tris_a(0b11111111); //Configuracion del puerto a
set_tris_b(0b00111011); //Configuracion del puerto b
porta = 0b11111111;
portb = 0b00111111;
setup_comparator(nc_nc_nc_nc);
setup_oscillator(osc_16mhz | osc_intrc | osc_pll_off);
delay_ms(10);
setup_timer_0(rtcc_div_1 | rtcc_ext_h_to_l);
setup_timer_1(t1_internal | t1_div_by_8);
setup_timer_2(t2_div_by_64,250,8);
port_b_pullups(true);
setup_wdt(wdt_512ms);
ext_int_edge(h_to_l);
clear_interrupt(int_ext);
enable_interrupts(int_ext);
enable_interrupts(int_rda);
enable_interrupts(int_timer1);
enable_interrupts(int_timer2);
enable_interrupts(global);
///////////////////////////////////////////////////////////////////////////////
//***********************RUTINAS GENERAL DE TECLADO****************************
//*****************************************************************************
while(true)
{
restart_wdt();
delay_ms(5);
tiempo_recibir();
seguridad_rf();
}
}
///////////////////////////////////////////////////////////////////////////////
//***********************RUTINAS***********************************************
//*****************************************************************************
//*****************************************************************************
//*****************************************************************************
//*****************************************************************************
//rutina que envia los datos al pic de potencia
void enviar_dato()
{
disable_interrupts(int_timer0);
fputc(0b10100001, potencia
); fputc(codigo_tecla
, potencia
);
set_timer2(0);
clear_interrupt(int_timer0);
enable_interrupts(int_timer0);
input(pin_b0);
codigo_tecla = 0;
}
///////////////////////////////////////////////////////////////////////////////
//sei se deja de recibir un dato durante 150 ms se envía la función de apagado
void tiempo_recibir()
{
direccion = dip_sw >> 1;
direccion &= 0b00001111;
direccion |= 0b10100000;
con_recibir_rf++;
if(con_recibir_rf == 30 && con_modo_env == 2)
{
codigo_tecla = res_codigo_tecla + 1;
res_codigo_tecla = 0;
con_modo_env = 0;
}
}
///////////////////////////////////////////////////////////////////////////////
//se chequea el pin de rx rf y se se bloquea la interrupción se resetea el pic
void seguridad_rf()
{
if(!pin_rx && !ban_pin_rx)
{
ban_pin_rx = 1;
con_seguridad_rf++;
if(con_seguridad_rf == 5)
{
con_seguridad_rf = 0;
reset_cpu();
}
}
if(pin_rx && ban_pin_rx) {ban_pin_rx = 0;}
}