#include <12F675.h>
#device adc=10
#FUSES NOWDT, INTRC_IO, NOCPD, NOPROTECT, NOMCLR, NOPUT, NOBROWNOUT, BANDGAP_HIGH, RESERVED
#use delay(clock=4000000) 
#bit t1_overflow=0x0C.0
#bit Led=0x85.1
int RPM=false;
short Sleep_Mode;
const int  FMax=60;     //frecuencia maxima de corte en Hz
const int  FTyp=50;     //frecuencia tipica de operacion en Hz
const int  FMin=46;     //frecuencia minima de corte  en Hz
const int  T_Retry=10;  //tiempo de espera para reintentar activar campo en Segundos
const long Vmax=535;    //Voltaje maximo de operacion en escala de 0 a 1024
const long VMin=489;    //Voltaje minimo de operacion en escala de 0 a 1024
const long T_Auto=2000; //Tiempo de activacion del campo en automatico.
int32 Freqcount(void){
 int cycles8, cycles;
 long freqc_high;
 long freqc_low;
 int32 freq;
   
 cycles8=0x00;
 cycles=0x00;
 freqc_high=0x00;
 t1_overflow=0;
 set_timer1(0);
 setup_timer_1(T1_External|T1_Div_By_1);
 while (cycles!=0xFF)
 {cycles8=0x00; 
  while (cycles8!=0xFF)
  {if (t1_overflow)             
   {t1_overflow=0;freqc_high++;} 
   else                                     
   {delay_cycles(0x05);}                       
   delay_cycles(0x1); 
   cycles8++;}
   delay_cycles(0x55);      
   cycles++;}
  delay_cycles(0x8D);   
  setup_timer_1(T1_Disabled);  
  if (t1_overflow) freqc_high++;
  freqc_low=get_timer1();     
  freq=make32(freqc_high,freqc_low);  
  return(freq);
}
void Turn_On(long Time)
{int32 Frq;
 long VW=0;
 long To=0;  
 output_low(pin_a1);
 output_high(pin_a4);
 while (VW<=VMin&&To<=Time) 
 {VW=Read_Adc();
  delay_ms(1);
  To++;
  if (time==0xFFFF&&To>=999) {to=0;if (led==0) output_float(pin_a1); else output_low(pin_a1);}}
 if (To>=Time&&VW<=VMin)
 {output_low(pin_a4);
  output_high(pin_a1);}
 else   
 {output_low(pin_a2);
  output_low(pin_a4);
  frq= freqcount(); 
  if (frq>=FTyp-1&&frq<=FTyp+1) RPM=true;
  else {RPM=false;output_high(pin_a2);output_high(pin_a1);}}}
void Turn_off(void)
{output_high(pin_a1);
 output_high(pin_a2);
 RPM=false;}
#int_RA
void RA_isr(void) 
{if (input(pin_a3)&&sleep_mode==true) sleep_mode=true;}
 
void main()
  {delay_ms(500);
   long VD;  
   long msec,sec;
   long timer=0xFFFF;
     
   setup_adc_ports(sAN0|VSS_VDD);
   setup_adc(ADC_Clock_Div_2);
   setup_timer_0(RTCC_Internal|RTCC_Div_1);
   setup_comparator(NC_NC);
   setup_vref(false);
   set_tris_a(0b101001);
   set_adc_channel(0);
   enable_interrupts(INT_RA3);     
   enable_interrupts(GLOBAL);     
   output_low(pin_a4);
   output_high(pin_a2);
   output_high(pin_a1);
   sleep_mode=false;  
   sec=t_retry;
  while (true) 
   {if (sleep_mode==true) sleep(); 
    if (RPM==true)
    {VD=Read_Adc();
     if (VD>=VMin&&VD<=VMax) output_low(pin_a1); else output_high(pin_a1);
     VD=freqcount();
     if (VD<=FMin||VD>=Fmax) {turn_off();sec=0;timer=T_Auto;}} 
    else if (sleep_mode==false)
    {delay_ms(1);
     msec++;
     if (msec>=0x03E7)
     {msec=0;sec++;if (led==0) output_float(pin_a1); else output_high(pin_a1);} 
     if (sec>=T_Retry) {Turn_On(timer);sec=0;}}   
    if (!input(pin_a3))
    {while(!input(pin_a3)) true;
     if (RPM==true) {turn_off();output_float(pin_a1);sleep_mode=true;}
     else
     if (sleep_mode==true) {sleep_mode=false;sec=T_Retry;timer=0xFFFF;} else {sleep_mode=true;output_float(pin_a1);}
    }	
   }
  }