Autor Tema: Interrupciones rs232 y Timer0  (Leído 5438 veces)

0 Usuarios y 3 Visitantes están viendo este tema.

Desconectado yeestrada

  • PIC10
  • *
  • Mensajes: 15
Interrupciones rs232 y Timer0
« en: 26 de Abril de 2011, 19:16:36 »
Hola a todos soy como que novato trabajando con pics, resulta que estoy implementando un programa para un 16f877a:

#int_TIMER0                         //directiva para it del timer0
void TIMER0_isr()
{
    actualiza_led(estado_leds);   
    set_timer0(81);
}


#int_rda
void rda_isr()
{
   printf("%d",getc());
}


Me pasa que cuando no pongo el metodo de la It de rda el timer0 hace lo que debe hacer, pero cuando lo pongo es por gusto, no lo ejecuta, alquien sabe el por que puede estarme pasando esto??

gracias
yordan

Desconectado korpaztk

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 202
Re: Interrupciones rs232 y Timer0
« Respuesta #1 en: 26 de Abril de 2011, 19:50:16 »
haber si entendi...

cuando solo ejecutas el programa sin la interrupcion por rs232, la interrupcion por timer, te funciona barabaro, pero cuando le agregas la interrupcion por rs232, el timer no funciona bien?
puedes declarar prioridades en las interrupciones si quieres
Korpaz.
Técnico Electronico.

El Papel Es Mi Mejor Psicologo

Desconectado yeestrada

  • PIC10
  • *
  • Mensajes: 15
Re: Interrupciones rs232 y Timer0
« Respuesta #2 en: 26 de Abril de 2011, 22:59:14 »
haber si entendi...

cuando solo ejecutas el programa sin la interrupcion por rs232, la interrupcion por timer, te funciona barabaro, pero cuando le agregas la interrupcion por rs232, el timer no funciona bien?
puedes declarar prioridades en las interrupciones si quieres

ya lo intenté, pero no hace nada... es esto no?  .

 #priority rda,ad,rtcc,timer1,timer0

Desconectado yeestrada

  • PIC10
  • *
  • Mensajes: 15
Re: Interrupciones rs232 y Timer0
« Respuesta #3 en: 26 de Abril de 2011, 23:06:56 »
a ver, este es el programa completo, donde no me corre:

#include <16F877A.h>                ///   libreria para el manejo del pic16f877a
#include <stdlib.h>
#priority rda,ad,rtcc,timer1,timer0
#use delay(clock=20000000)          ///   declara  la frecuencia del cristal 20mhz
#use RS232(BAUD=9600,BITS=8,PARITY=N,XMIT=PIN_C6,RCV=PIN_C7)

#use fast_io(A)
#use fast_io(B)
#use fast_io(C)                     ///   con esta instruccion evitamos que
#use fast_io(D)                     ///   se este configurando cada vez que usamos
#use fast_io(E)                     ///   alguna instruccion de entrada o salida

#byte porta = 5
#byte portb = 6
#byte portc = 7                     /// se definen direcciones de memoria
#byte portd = 8
#byte porte = 9

   int nums[7];
   int temporal;
   int cont_letras;                    //variable para contar los 8 numeros que se puede entrar por Tx serie
   int16 time;                           //hasta 300 segundos entre recuperaciones de muestras
   int16 cant_var;                       //hasta 2000 muestras que es necesario recojer
   int cont_seg;
   int cont;
   int estado_leds;

int Tabla(int a)        //tabla para visualizar numeros por el 7segmentos
{
  switch(a)
  {
      CASE 0:RETURN 0b00111111;
      CASE 1:RETURN 0B00000110;
      CASE 2:RETURN 0B01011011;
      CASE 3:RETURN 0B01001111;
      CASE 4:RETURN 0B01100110;
      CASE 5:RETURN 0B01101101;
      CASE 6:RETURN 0B01111101;
      CASE 7:RETURN 0B00000111;
      CASE 8:RETURN 0B01111111;
      CASE 9:RETURN 0B01100111;
  }
}

int Is_num(int a)
{
   if(a>=48 && a<=57)
    return 0;                          //si es 0 es un numero sino es otro
   return 1;
}

void actualiza_led(int i)
{
   switch(i)
   {
   case 0: portb= 0B11111110;         //PC
           portd= 0B01110011;
           delay_ms(50);
           portb= 0B11111101;
           portd= 0B00111001;
           break;
   case 1: portb= 0B11111110;         //Ad
           portd= 0B01110111;
           delay_ms(50);
           portb= 0B11111101;
           portd= 0B01011110;
           break;  
   case 2: portb= 0B11111110;         //Sd
           portd= 0B01101101;
           delay_ms(50);
           portb= 0B11111101;
           portd= 0B01011110;
           break;
   }
}


#int_TIMER0                         //directiva para it del timer0
void TIMER0_isr()
{
    actualiza_led(estado_leds);    
    set_timer0(81);
}

#int_rda
void rda_isr()
{
   printf("%d",getc());
}

void configurar(void)                  //configuraciones
{
   enable_interrupts(INT_TIMER0);         //habilitar el timer0
   enable_interrupts(INT_RDA);            //habilitar para comunicación serie
   enable_interrupts(GLOBAL);             //habilitar el bit de it global
  
   set_tris_d(0x00);
   set_tris_b(0x00);
}


void entrar_numeros()                  //validar la entrada de números
{
    temporal = 0;
    while(temporal==0)
    {
      cont_letras = 0;
      while(cont_letras < 7)
      {
         temporal=GETC();
         if(Is_num(temporal)==0)
         {
            temporal =temporal-48;
            nums[cont_letras] = temporal;
            printf ("%d",nums[cont_letras]);
            cont_letras++;
         }
         else
         {
            cont_letras = 0;
            printf ("Error");
         }
      }

      cant_var = _mul(nums[0],1000) + _mul(nums[1],100) + _mul(nums[2],10) + nums[3];
      time = _mul(nums[4],100) + _mul(nums[5],10) + nums[6];

      temporal = 1;

      if(time>300 || time<1)
      {
         printf (" Tiempo fuera de rango. ");
         temporal = 0;
      }
     
      if(cant_var>2000)
      {
         printf (" Cantidad de muestras fuera de rango. ");
         temporal = 0;
      }
   }
}

void main()
{
   cont_seg = 0;
   estado_leds = 2;
   configurar();
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
   set_timer0(81);  
   entrar_numeros();
}                                
« Última modificación: 26 de Abril de 2011, 23:15:59 por yeestrada »

Desconectado bmb

  • PIC18
  • ****
  • Mensajes: 423
Re: Interrupciones rs232 y Timer0
« Respuesta #4 en: 27 de Abril de 2011, 00:05:04 »
Hola yeestrada, creo que no le estás prestando atención a un mensaje de advertencia que te debe estar dando el compilador: Interrupts disabled during call to prevent re-entrancy.  En la función que corresponde a Timer0 veo una llamada a una función con delays incluidos.  Fíjate lo que dice CCS de eso por aquí.
Además, en la función que corresponde a la comunicación serial tienes esta instrucción: printf("%d",getc());  Igualmente fíjate lo que dice CCS sobre eso.

Saludos!

Desconectado yeestrada

  • PIC10
  • *
  • Mensajes: 15
Re: Interrupciones rs232 y Timer0
« Respuesta #5 en: 27 de Abril de 2011, 00:50:59 »
si, disculpame, ese no era el ultimo codigo que hice, no obstante, no se que otra solución darle al delay, pues lo que se me ocurre es que el timer0 se ocupe de actualizarme constantemente el estado de los led 7segmentos, por otra parte necesito mostrar el numero que entra el usuario cada vez que presiona una tecla,tampoco se otra forma de hacerlo, y por ultimo, cuando termino de entrar los 7 numeros, es como que se acaba el programa cuando solo deberia no hacer nada mas con el rda,y el timer debe seguir funcionabdo, pero se para....   :(


#include <16F877A.h>                ///   libreria para el manejo del pic16f877a
#include <stdlib.h>
#priority rda,timer1,timer0
#use delay(clock=20000000)          ///   declara  la frecuencia del cristal 20mhz
#use RS232(BAUD=9600,BITS=8,PARITY=N,XMIT=PIN_C6,RCV=PIN_C7)

#use fast_io(A)
#use fast_io(B)
#use fast_io(C)                     ///   con esta instruccion evitamos que
#use fast_io(D)                     ///   se este configurando cada vez que usamos
#use fast_io(E)                     ///   alguna instruccion de entrada o salida

#byte porta = 5
#byte portb = 6
#byte portc = 7                     /// se definen direcciones de memoria
#byte portd = 8
#byte porte = 9

   int nums[7];
   int temporal;
   int cont_letras;                    //variable para contar los 8 numeros que se puede entrar por Tx serie
   int16 time;                           //hasta 300 segundos entre recuperaciones de muestras
   int16 cant_var;                       //hasta 2000 muestras que es necesario recojer
   int cont_seg;
   int cont;
   int estado_leds;

int Tabla(int a)        //tabla para visualizar numeros por el 7segmentos
{
  switch(a)
  {
      CASE 0:RETURN 0b00111111;
      CASE 1:RETURN 0B00000110;
      CASE 2:RETURN 0B01011011;
      CASE 3:RETURN 0B01001111;
      CASE 4:RETURN 0B01100110;
      CASE 5:RETURN 0B01101101;
      CASE 6:RETURN 0B01111101;
      CASE 7:RETURN 0B00000111;
      CASE 8:RETURN 0B01111111;
      CASE 9:RETURN 0B01100111;
  }
}

int Is_num(int a)
{
   if(a>=48 && a<=57)
    return 0;                          //si es 0 es un numero sino es otro
   return 1;
}

void actualiza_led(int i)
{
   switch(i)
   {
   case 0: portb= 0B11111110;         //PC
           portd= 0B01110011;
           delay_ms(50);
           portb= 0B11111101;
           portd= 0B00111001;
           break;
   case 1: portb= 0B11111110;         //Ad
           portd= 0B01110111;
           delay_ms(50);
           portb= 0B11111101;
           portd= 0B01011110;
           break;  
   case 2: portb= 0B11111110;         //Sd
           portd= 0B01101101;
           delay_ms(50);
           portb= 0B11111101;
           portd= 0B01011110;
           break;
   }
}


#int_TIMER0                         //directiva para it del timer0
void TIMER0_isr()
{
    actualiza_led(estado_leds);    
    set_timer0(81);
}

#int_rda
void rda_isr()
{
   if(cont_letras < 7)
   {
      temporal = getc();
      if(Is_num(temporal)==0)
      {
         temporal =temporal-48;
         nums[cont_letras] = temporal;
         printf ("%d",nums[cont_letras]);
         cont_letras++;
      }
      else
      {
         cont_letras = 0;
         printf ("Error");
      }
   }
}

void configurar(void)                  //configuraciones
{
   enable_interrupts(INT_TIMER0);         //habilitar el timer0
   enable_interrupts(INT_RDA);            //habilitar para comunicación serie
   enable_interrupts(GLOBAL);             //habilitar el bit de it global
  
   set_tris_d(0x00);
   set_tris_b(0x00);
}


void main()
{
   cont_seg = 0;
   estado_leds = 0;
   cont_letras = 0;
   configurar();
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
   set_timer0(81);  
   while(1){}
}        
« Última modificación: 27 de Abril de 2011, 01:05:38 por yeestrada »

Desconectado korpaztk

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 202
Re: Interrupciones rs232 y Timer0
« Respuesta #6 en: 27 de Abril de 2011, 12:07:44 »
no es conveniente con una interrupcion del timer entrar en una subrutina, yo utilizaria un flag en el timer para activar la subrutina, yo compilo este programa y me da error en la interrupcion, me dice que no puede durar tanto tiempo.
consulta: para que has colocado prioridad al timer1 si en el codigo no se esta utilizando??

Saludos.-
Korpaz.
Técnico Electronico.

El Papel Es Mi Mejor Psicologo

Desconectado yeestrada

  • PIC10
  • *
  • Mensajes: 15
Re: Interrupciones rs232 y Timer0
« Respuesta #7 en: 27 de Abril de 2011, 23:38:50 »
no es conveniente con una interrupcion del timer entrar en una subrutina, yo utilizaria un flag en el timer para activar la subrutina, yo compilo este programa y me da error en la interrupcion, me dice que no puede durar tanto tiempo.
consulta: para que has colocado prioridad al timer1 si en el codigo no se esta utilizando??

Saludos.-

Bueno, de colocar una bandera tendria que estar en el programa principal constantemente preguntando por esa bandera para actualizar los leds 7segmentos, y la intención que tuve es dejar que el timer 0 se encarge el solo de los leds, de modo que siempre lo este actualizando, ya sea con un mensaje o con otro. El timer 1 lo tengo incluido pq lo pretendo utilizar tambien es el que va a encargarse de contar la cantidad de segundos entre las lecturas del conversor ad.


Desconectado yeestrada

  • PIC10
  • *
  • Mensajes: 15
Re: Interrupciones rs232 y Timer0
« Respuesta #8 en: 28 de Abril de 2011, 17:12:51 »
bmb, creo que ya he logrado hacer algo de lo que queria, solo que me parece que ahora no estoy leyendo bien a la hora de mostrar por serie los valores guardados en la eeprom, se que esos valores no son correctos, lo que no se es por que estoy leyendolos mal, si se que los esta guardando bien. Otra cosa, que compilador estas usando, pq en el que yo uso (PCWC compiler version 3.249) no me sale ningun warning.

diseño del hardware (MPLAB):

http://www.filefactory.com/file/cbf547d/n/Diseño_hardware.rar


el codigo como me quedo:

#include <16F877A.h>                ///   libreria para el manejo del pic16f877a
#device ADC=10 ICD=TRUE
#include <stdlib.h>

#define EEPROM_SDA PIN_c4
#define EEPROM_SCL PIN_c3

#include "24256.c"
#include "external_eeprom.c"
#priority rda,ad,timer1,timer0
#use delay(clock=20000000)          ///   declara  la frecuencia del cristal 20mhz
#use RS232(BAUD=9600,BITS=8,PARITY=N,XMIT=PIN_C6,RCV=PIN_C7)

#FUSES NOWDT                        //No Watch Dog Timer
#FUSES HS                           //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOBROWNOUT                   //No brownout reset
#FUSES NOLVP                        //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O

#use fast_io(A)
#use fast_io(B)
#use fast_io(C)                     ///   con esta instruccion evitamos que
#use fast_io(D)                     ///   se este configurando cada vez que usamos
#use fast_io(E)                     ///   alguna instruccion de entrada o salida

#byte porta = 5
#byte portb = 6
#byte portc = 7                     /// se definen direcciones de memoria
#byte portd = 8
#byte porte = 9

   int nums[7];
   int temporal;
   int cont_letras;                 //variable para contar los 8 numeros que se puede entrar por Tx serie
   int16 time;                      //hasta 300 segundos entre recuperaciones de muestras
   int16 cant_var;                  //hasta 2000 muestras que es necesario recojer
   int cont_seg;
   int16 cont_time;
   int16 cont_var;
   int estado_leds;
   int var_in_rand;
   int16 lectura_ad;
   int canal_ad;

int Tabla(int a)                    //tabla para visualizar numeros por el 7segmentos
{
  switch(a)
  {
      CASE 0:RETURN 0b00111111;
      CASE 1:RETURN 0B00000110;
      CASE 2:RETURN 0B01011011;
      CASE 3:RETURN 0B01001111;
      CASE 4:RETURN 0B01100110;
      CASE 5:RETURN 0B01101101;
      CASE 6:RETURN 0B01111101;
      CASE 7:RETURN 0B00000111;
      CASE 8:RETURN 0B01111111;
      CASE 9:RETURN 0B01100111;
  }
}

int Is_num(int a)
{
   if(a>=48 && a<=57)
    return 0;                        //si es 0 es un numero sino es otro
   return 1;
}

void actualiza_led(int i)
{
   switch(i)
   {
   case 0: portb= 0B11111110;         //PC
           portd= 0B01110011;
           delay_ms(50);
           portb= 0B11111101;
           portd= 0B00111001;
           break;
   case 1: portb= 0B11111110;         //Ad
           portd= 0B01110111;
           delay_ms(50);
           portb= 0B11111101;
           portd= 0B01011110;
           break;
   case 2: portb= 0B11111110;         //Sd
           portd= 0B01101101;
           delay_ms(50);
           portb= 0B11111101;
           portd= 0B01011110;
           break;
   }
}


#use delay(clock=20000000)

void LeerAD(int canal)
{
   lectura_ad = 0;
   set_adc_channel(canal);
   lectura_ad = read_adc();
}



#int_TIMER0                            //directiva para it del timer0
void TIMER0_isr()
{
    actualiza_led(estado_leds);
    set_timer0(81);
}

#use delay(clock=20000000)

#int_TIMER1                            //directiva para it del timer0
void TIMER1_isr()
{
  if(cont_seg > 9)
  {
    cont_seg = 0;
    if(cont_time < time)
     cont_time++;     
    else
     temporal =1;
   }
   cont_seg++;
   set_timer1(3063);   
}

#int_rda
void rda_isr()
{
   if(cont_letras < 7)
   {
      temporal = getc();
      if(Is_num(temporal)==0)
      {
         temporal =temporal-48;
         nums[cont_letras] = temporal;
         printf ("%d",nums[cont_letras]);
         cont_letras++;
      }
      else
      {
         cont_letras = 0;
         printf ("Error");
      }
   }
}


void configurar(void)                     //configuraciones
{
   enable_interrupts(INT_TIMER0);         //habilitar el timer0
   enable_interrupts(INT_TIMER1);         //habilitar el timer1
   enable_interrupts(INT_RDA);            //habilitar para comunicación serie
   enable_interrupts(GLOBAL);             //habilitar el bit de it global
   setup_adc_ports( ALL_ANALOG );
   setup_adc( ADC_CLOCK_INTERNAL );
   set_tris_d(0x00);
   set_tris_b(0x00);
}

#use delay(clock=20000000)

void main()
{
while(1)
{
      cont_seg = 0;
      estado_leds = 0;
      cont_letras = 0;
      var_in_rand = 0;
      cont_time = 1;
      canal_ad = 0;
      cont_var = 0;
      configurar();
      setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
      set_timer0(81);
   
      while(var_in_rand == 0)
      {
         while(cont_letras < 7){}
         cant_var = _mul(nums[0],1000) + _mul(nums[1],100) + _mul(nums[2],10) + nums[3];
         time = _mul(nums[4],100) + _mul(nums[5],10) + nums[6];
         var_in_rand = 1;
         if(time>300 || time<1)
         {
            printf (" Tiempo fuera de rango. ");
            cont_letras = 0;
            var_in_rand = 0;
         }
      else
         if(cant_var>2000)
         {
            printf (" Cantidad de muestras fuera de rango. ");
            cont_letras = 0;
            var_in_rand = 0;
         }
      }
      estado_leds = 1;
      setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
      set_timer1(3063);
      init_ext_eeprom();
      while(cont_var<cant_var)
      {
         if(temporal ==1)
         {
            disable_interrupts(int_TIMER1);
            temporal =0;
            cont_time = 1;
            for(canal_ad=0;canal_ad<8;canal_ad++)
            {       
               LeerAD(canal_ad);
               write_int16_ext_eeprom(_mul(cont_var+canal_ad,2), lectura_ad);
               delay_ms(20);       
            }
            cont_var++;         
            enable_interrupts(INT_TIMER1);
         }
      }
      disable_interrupts(int_TIMER1);
      lectura_ad=0;
      estado_leds = 2;
      printf(" Lecturas: ");
      for(cont_var=0; cont_var<_mul(cant_var,16); cont_var+=2)
      {
      lectura_ad = read_int16_ext_eeprom(cont_var);
      printf("%2x ",lectura_ad);
      delay_ms(20);
      }
      printf(" FIN");
   }
}

Desconectado bmb

  • PIC18
  • ****
  • Mensajes: 423
Re: Interrupciones rs232 y Timer0
« Respuesta #9 en: 28 de Abril de 2011, 18:10:07 »
Hola Yordan, he vuelto a compilar el código que acabas de postear y ahora muestra solo una advertencia de deshabilitación de interrupciones. Yo utilizo la versión 4.120.

Saludos!

Desconectado yeestrada

  • PIC10
  • *
  • Mensajes: 15
Re: Interrupciones rs232 y Timer0
« Respuesta #10 en: 28 de Abril de 2011, 23:10:04 »
Hola Yordan, he vuelto a compilar el código que acabas de postear y ahora muestra solo una advertencia de deshabilitación de interrupciones. Yo utilizo la versión 4.120.

Saludos!

ah, tienes una version mas moderna que la mia, podrias compartirmela si no es mucha molestia, para intentar darle solución a ese warning??, por otro lado ves cual es el error que estoy cometiendo en el ultimo for debe ser, que no me muestra los verdaderos valores??

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re: Interrupciones rs232 y Timer0
« Respuesta #11 en: 29 de Abril de 2011, 00:00:28 »
yo siendo tu quitaría el printf del int_rda, es mas quitaría la mayoría del código y pondría una bandera a true, y luego en el bucle principal metería ese código


funcion procesar_int_rda{
 deshabilitar int_rda
 codigo a procesar del int_rda
 habilitar int_rda
}

La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado yeestrada

  • PIC10
  • *
  • Mensajes: 15
Re: Interrupciones rs232 y Timer0
« Respuesta #12 en: 02 de Mayo de 2011, 12:06:54 »
hola palitroqueZ ya arregle lo que me propusiste, y funciona bien, pero aun tengo un problema, y es que al final, a la hora de mostrar las lecturas que realizó, solo me muestra realmente la 1ra lectura, y el resto de los que me muestra siempre es ff, que error debo estar haciendo, asumo que debe ser a la hora de leer de la eeprom que estoy haciendo algo mal, aqui el codigo arreglado


#include <16F877A.h>                ///   libreria para el manejo del pic16f877a
#device ADC=10 ICD=TRUE
#include <stdlib.h>

#define EEPROM_SDA PIN_c4
#define EEPROM_SCL PIN_c3

#include "24256.c"
#include "external_eeprom.c"
#priority rda,ad,timer1,timer0
#use delay(clock=20000000)          ///   declara  la frecuencia del cristal 20mhz
#use RS232(BAUD=9600,BITS=8,PARITY=N,XMIT=PIN_C6,RCV=PIN_C7)

#FUSES NOWDT                        //No Watch Dog Timer
#FUSES HS                           //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOBROWNOUT                   //No brownout reset
#FUSES NOLVP                        //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O

#use fast_io(A)
#use fast_io(B)
#use fast_io(C)                     ///   con esta instruccion evitamos que
#use fast_io(D)                     ///   se este configurando cada vez que usamos
#use fast_io(E)                     ///   alguna instruccion de entrada o salida

#byte porta = 5
#byte portb = 6
#byte portc = 7                     /// se definen direcciones de memoria
#byte portd = 8
#byte porte = 9

   int nums[7];
   int temporal;
   int cont_letras;                 //variable para contar los 8 numeros que se puede entrar por Tx serie
   int16 time;                      //hasta 300 segundos entre recuperaciones de muestras
   int16 cant_var;                  //hasta 2000 muestras que es necesario recojer
   int cont_seg;
   int16 cont_time;
   int16 cont_var;
   int estado_leds;
   int var_in_rand;
   int16 lectura_ad;
   int canal_ad;
   int tecla_activa;

int Tabla(int a)                    //tabla para visualizar numeros por el 7segmentos
{
  switch(a)
  {
      CASE 0:RETURN 0b00111111;
      CASE 1:RETURN 0B00000110;
      CASE 2:RETURN 0B01011011;
      CASE 3:RETURN 0B01001111;
      CASE 4:RETURN 0B01100110;
      CASE 5:RETURN 0B01101101;
      CASE 6:RETURN 0B01111101;
      CASE 7:RETURN 0B00000111;
      CASE 8:RETURN 0B01111111;
      CASE 9:RETURN 0B01100111;
  }
}

int Is_num(int a)
{
   if(a>=48 && a<=57)
    return 0;                        //si es 0 es un numero sino es otro
   return 1;
}

void actualiza_led(int i)
{
   switch(i)
   {
   case 0: portb= 0B11111110;         //PC
           portd= 0B01110011;
           delay_ms(50);
           portb= 0B11111101;
           portd= 0B00111001;
           break;
   case 1: portb= 0B11111110;         //Ad
           portd= 0B01110111;
           delay_ms(50);
           portb= 0B11111101;
           portd= 0B01011110;
           break;
   case 2: portb= 0B11111110;         //Sd
           portd= 0B01101101;
           delay_ms(50);
           portb= 0B11111101;
           portd= 0B01011110;
           break;
   }
}


#use delay(clock=20000000)

void LeerAD(int canal)
{
   lectura_ad = 0;
   set_adc_channel(canal);
   lectura_ad = read_adc();
}



#int_TIMER0                            //directiva para it del timer0
void TIMER0_isr()
{
    actualiza_led(estado_leds);
    set_timer0(81);
}

#use delay(clock=20000000)

#int_TIMER1                            //directiva para it del timer0
void TIMER1_isr()
{
  if(cont_seg > 9)
  {
    cont_seg = 0;
    if(cont_time < time)
     cont_time++;
    else
     temporal =1;
   }
   cont_seg++;
   set_timer1(3063);
}

#int_rda
void rda_isr()
{
   disable_interrupts(int_rda);
   tecla_activa=1;
}


void configurar(void)                     //configuraciones
{
   enable_interrupts(INT_TIMER0);         //habilitar el timer0
   enable_interrupts(INT_TIMER1);         //habilitar el timer1
   enable_interrupts(INT_RDA);            //habilitar para comunicación serie
   enable_interrupts(GLOBAL);             //habilitar el bit de it global
   setup_adc_ports( ALL_ANALOG );
   setup_adc( ADC_CLOCK_INTERNAL );
   set_tris_d(0x00);
   set_tris_b(0x00);
}

#use delay(clock=20000000)

void main()
{
while(1)
{
      cont_seg = 0;
      estado_leds = 0;
      cont_letras = 0;
      var_in_rand = 0;
      cont_time = 1;
      tecla_activa = 0;
      canal_ad = 0;
      cont_var = 0;
      configurar();
      setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
      set_timer0(81);

      while(var_in_rand == 0)
      {
         while(cont_letras < 7)
         {
            if(tecla_activa ==1)
            {
               temporal = getc();
               if(Is_num(temporal)==0)
               {
                  temporal =temporal-48;
                  nums[cont_letras] = temporal;
                  printf ("%d",nums[cont_letras]);
                  cont_letras++;
               }
               else
               {
                  cont_letras = 0;
                  printf ("Error");
               }
               
               enable_interrupts(int_rda);
               tecla_activa = 0;
               
   }

         }
         cant_var = _mul(nums[0],1000) + _mul(nums[1],100) + _mul(nums[2],10) + nums[3];
         time = _mul(nums[4],100) + _mul(nums[5],10) + nums[6];
         var_in_rand = 1;
         if(time>300 || time<1)
         {
            printf (" Tiempo fuera de rango. ");
            cont_letras = 0;
            var_in_rand = 0;
         }
      else
         if(cant_var>2000)
         {
            printf (" Cantidad de muestras fuera de rango. ");
            cont_letras = 0;
            var_in_rand = 0;
         }
      }
      estado_leds = 1;
      setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
      set_timer1(3063);
      init_ext_eeprom();
      while(cont_var<cant_var)
      {
         if(temporal ==1)
         {
            disable_interrupts(int_TIMER1);
            temporal =0;
            cont_time = 1;
            for(canal_ad=0;canal_ad<8;canal_ad++)
            {
               LeerAD(canal_ad);
               write_int16_ext_eeprom(_mul(cont_var+canal_ad,2), lectura_ad);
               delay_ms(20);
            }
            cont_var++;
            enable_interrupts(INT_TIMER1);
         }
      }
      disable_interrupts(int_TIMER1);
      lectura_ad=0;
      estado_leds = 2;
      printf(" Lecturas: ");
      for(cont_var=0; cont_var<_mul(cant_var,16); cont_var+=2)
      {
      lectura_ad = read_int16_ext_eeprom(cont_var);
      printf("%2x ",lectura_ad);
      delay_ms(20);
      }
      printf(" FIN");
   }
}