Problema con el circuito real, no con la simulación.

Hola a todos. Realice un programa que a partir de una señal de entrada que es periodica, pero que puede variar su periodo, genera 2 pulsos de disparo en un determinado instante de tiempo, que se calcula a partir de una ecuación y que depende del periodo de esa señal de entrada.
Dicha señal, es generada con otro PIC, la misma es un tren de 35 pulsos, 34 cortos y 1 largo, que determina el final de la señal, para luego volver a comenzar. Esa señal es generada en la simulación y en la vida real, con un PIC12F683, en la cual permite a partir de 2 pulsadores poder bajar/subir su periodo, estableciendo un periodo máximo de 300 mseg y un periodo mínimo de 10 mseg.
Ahora bien, el otro PIC que toma la señal generada de 35 pulsos, debe realizar 2 pulsos de disparo, por 2 pines diferentes en instantes de tiempo que dependen de una ecuación lineal, y la duración de dichos pulsos es de 3 mseg.
Pues luego de relizar el programa inicial, el mismo presentaba algunos problemas menores, que luego subsane, quedando la simulación funcionando como debe. Pero me encontré con que cuando lo armo no genera los pulsos de disparo, el programa corre pero no ingresa en los IF donde le indican el momento que deben dispara. A medida que el periodo de la señal se modifica tambien se modifican los instante de tiempo de disparo, habiendo siempre una separación de T/2 entre el pulso 1 y el 2.
Antes de realizar los ajustes al programa inicial, lo probe en la protoboard y andaba, con problemas pero los pulsos aparecian, ahora que realice los ajustes para el correcto funcionamiento, ya no están, pero en la siulación anda bien, eso es lo que me extraña.
Probe con otro PIC y es lo mismo, puse banderas durante el programa para que me prenda un led para indicarme por donde pasaba y que cosas hacia y que cosas no, y pude determinar que no ingresa a los IF donde verifica el instante en el que debe realizar el disparo, pero no se porque.
Adjunto la simulación andando y el programa de ambos pic para ver si alguien ve por donde puede venir el problema.

Generación de la señal de entrada
Código:
#include <12F683.H> // Directivas del PIC 12F683

// Declaro la palabra de configuración del microcontrolador //

#fuses INTRC_IO,NoWdt,NoBrownout,Protect // Intrc_io(no clkout), NoWatchDog, NoBrownOut, Protect 
#fuses NoMclr,NoCpd,Put,NoIeso,NoFcmen     // NoMasterClear, EEProtection, Put, NoIeso, NoFcmen

// Configuro el cristal que voy a utilizar //

#use delay(clock=4000000) // Frecuencia de 4MHz interna

// Modo de configurar los pines de entrada/salida

#use fast_io(A) // Asignación rápida de los pines del puerto A

#locate Puerto_A = 0x05 // Defino el puerto A con una etiqueta
#bit RPM       = Puerto_A.0 // GP0 como salida
#bit Bajar_RPM = Puerto_A.1 // GP1 como entrada
#bit Subir_RPM = Puerto_A.2 // GP2 como entrada
#bit Led       = Puerto_A.4 // GP4 como salida

// Definición de variables

long contador = 4166;
int i;

// Declaro las funciones utilizadas

void Inicializacion_dispositivo (); // Rutina de inicialicación del dispositivo

// Comienzo del programa principal

void main (void)
{
   Inicializacion_dispositivo();       // Inicializo el dispositivo
   for(;;)
   {
      if (Bajar_RPM == 1)
      {
         Led = 0;
         if (Contador < 4166)
            Contador+=20;
         else
            Led = 1;
      }
      if (Subir_RPM == 1)
      {
         Led = 0;
         if (Contador > 138)
            Contador-=20;
         else
            Led = 1;
      }
      for (i=0;i<34;i++)
      {
         RPM = 0;
         Delay_us (Contador);
         RPM = 1;
         Delay_us (Contador);
      }
      RPM = 0;
      Delay_us (2*Contador);
      RPM = 1;
      Delay_us (2*Contador);
   }
}

void Inicializacion_dispositivo(void)  // Rutina de inicialicación del dispositivo
{
   set_tris_a (0b00000110);                     // Pines como entrada: A1,A2 - Pines como salida: A0,A3,A4,A5
   output_a (0);                                // Borro las salidas del puerto A
}
Programa que genera los pulsos de disparo a partir de la señal de entrada
Código:
#include <12F683.H> // Directivas del PIC 12F683

// Declaro la palabra de configuración del microcontrolador //

#fuses INTRC_IO,NoWdt,NoBrownout,Protect // Intrc_io(no clkout), NoWatchDog, NoBrownOut, Protect 
#fuses NoMclr,NoCpd,Put,NoIeso,NoFcmen     // NoMasterClear, EEProtection, Put, NoIeso, NoFcmen

// Configuro el cristal que voy a utilizar //

#use delay(clock=4000000) // Frecuencia de 4MHz interna

// Modo de configurar los pines de entrada/salida

#use fast_io(A) // Asignación rápida de los pines del puerto A

#locate Puerto_A = 0x05 // Defino el puerto A con una etiqueta
// Registro de PORTA ==> BITS: 5 4 3 2 1 0
//                             | | | | | |_ Disparo_1 : Salida para el disparo de la bobina 1
//                             | | | | |___ Disparo_2 : Salida para el disparo de la bobina 2
//                             | | | |_____ RPM : Entrada de los pulsos de la rueda dentada
//                             | | |_______ No usado : Bit no utilizado
//                             | |_________ No usado : Bit no utilizado
//                             |___________ No usado : Bit no utilizado

#bit Disparo_1 = Puerto_A.0 // GP0 como salida
#bit Disparo_2 = Puerto_A.1 // GP1 como salida
#bit RPM       = Puerto_A.2 // GP2 como entrada
#bit Led       = Puerto_A.4 // GP4 como salida

// Definiciones

#define T0_CONTADOR_H_TO_L 0xB8

// Definición de variables

long Tiempo, Periodo_T_Disco_Dentado;
int Diente_Encontrado, Nuevo_Periodo;
int Band_Disparo_1, Band_Disparo_2, Reset_Banderas;
signed int32 Td;
long Td1_viejo, Td2_viejo, Td1_nuevo, Td2_nuevo;
float p1 = 0.18887;
float p2 = -544.64;

// Declaro las funciones utilizadas

void Inicializacion_dispositivo (); // Rutina de inicialicación del dispositivo
void Deteccion_Diente_Faltante ();  // Rutina de detección del diente doble

// Interrupcion Timer 0
#int_timer0
void Periodo_T (void)
{
   Periodo_T_Disco_Dentado = get_timer1 (); // Obtengo el tiempo del periodo de la vuelta del disco dentado
   set_timer1 (0);                          // Pone a cero el Timer 1
   set_timer0 (221);                        // Lo seteo para que desborde con 35 pulsos ==> 220 + 35 = 255 ==> Interrupción
   Td1_viejo = Td1_nuevo;
   Td2_viejo = Td2_nuevo;
   Nuevo_periodo = 1;
   Reset_Banderas = 1;
}

void main ()
{
   Inicializacion_dispositivo();       // Inicializo el dispositivo
   Delay_ms (10);                     // Espero 100 mseg a que el burro llegue a un regimen permanente para buscar la referencia
   Deteccion_Diente_Faltante ();       // Función que ubica el diente doble de la rueda dentada
   set_timer1(0);                      // Pone a cero el Timer 1
   setup_timer_0 (T0_CONTADOR_H_TO_L); // Seteo el timer 0 como contador de alto a bajo
   set_timer0 (221);                   // Lo seteo para que desborde con 35 pulsos ==> 220 + 35 = 255 ==> Interrupción
   enable_interrupts (INT_TIMER0);
   enable_interrupts (GLOBAL);
   while (Periodo_T_Disco_Dentado == 0);
   Td = p1*Periodo_T_Disco_Dentado + p2;
   Td1_nuevo = Td;
   Td2_nuevo = Td1_nuevo + Periodo_T_Disco_Dentado/2;
   while (Td1_viejo == 0);
   for(;;)
   {
      if ((Td1_viejo<get_timer1())&(Band_Disparo_1 == 0))
      {
         Led = 1;
         Disparo_1 = 1;
         Delay_ms (3);
         Disparo_1 = 0;
         if (Nuevo_Periodo == 1)
         {
            Td = p1*Periodo_T_Disco_Dentado + p2;
            if (Td < 0)
            {
               Td1_nuevo = Periodo_T_Disco_Dentado + Td;
               Td2_nuevo = Td1_nuevo - Periodo_T_Disco_Dentado/2;
            }
            else
            {
               Td1_nuevo = Td;
               Td2_nuevo = Td1_nuevo + Periodo_T_Disco_Dentado/2;
            }
            Nuevo_Periodo = 0;
         }
         Band_Disparo_1 = 1;
      }
      if ((Td2_viejo<get_timer1())&(Band_Disparo_2 == 0))
      {
         Led = 0;
         Disparo_2 = 1;
         Delay_ms (3);
         Disparo_2 = 0;
         if (Nuevo_Periodo == 1)
         {
            Td = p1*Periodo_T_Disco_Dentado + p2;
            if (Td < 0)
            {
               Td1_nuevo = Periodo_T_Disco_Dentado + Td;
               Td2_nuevo = Td1_nuevo - Periodo_T_Disco_Dentado/2;
            }
            else
            {
               Td1_nuevo = Td;
               Td2_nuevo = Td1_nuevo + Periodo_T_Disco_Dentado/2;
            }
            Nuevo_Periodo = 0;
         }
         Band_Disparo_2 = 1;
      }
      if (Reset_Banderas == 1)
      {
         Band_Disparo_1 = 0;
         Band_Disparo_2 = 0;
         Reset_Banderas = 0;
      }
   }
}

void Inicializacion_dispositivo(void)  // Rutina de inicialicación del dispositivo
{
   set_tris_a (0b00000100);                     // Pines como entrada: A2 - Pines como salida: A0,A1,A3,A4,A5
   output_a (0);                                // Borro las salidas del puerto A
   setup_timer_1 (T1_INTERNAL | T1_DIV_BY_8);   // Seteo el timer 1 para funcionar a 8 useg
}

void Deteccion_Diente_Faltante (void)
{
   while(RPM == 1);                       // Si está en alto espera a que baje
   while(RPM == 0);                       // Si está en bajo espera a que suba y comienza a contar el tiempo
   set_timer1(0);                         // Pone a cero el Timer 1
   while(RPM == 1);                       // Se mantiene en el pulso alto hasta que cambie
   Tiempo = get_timer1();                 // Guardo el tiempo del primer pulso encontrado para ser comparado luego
   do
   {
      while(RPM == 0);                    // Si está en bajo espera a que suba y comienza a contar el tiempo
      set_timer1(0);                      // Pone a cero el Timer 1
      while(RPM == 1);                    // Se mantiene en el pulso alto hasta que cambie
      if (Tiempo > get_timer1 ())         // Pregunto si el tiempo medido antes es mayor que el medido luego para poder descartarlo
      {
         while(RPM == 0);                 // Si está en bajo espera a que suba y comienza a contar el tiempo
         set_timer1(0);                   // Pone a cero el Timer 1
         while(RPM == 1);                 // Se mantiene en el pulso alto hasta que cambie
         Tiempo = get_timer1();           // Guardo el tiempo del primer pulso encontrado para ser comparado luego
      }
      if ((get_timer1() - Tiempo) > 8)    // Si la diferencia entre un tiempo y otro es chica significa que tiene el mismo ancho
         Diente_Encontrado = 1;        // Hago verdadera la bandera cuando encuentro el diente faltante
   }while(Diente_Encontrado == 0);    // Termino el bucle cuando encuentro el lugar del diente faltante
}
 

Adjuntos

  • EE.rar
    36 KB · Visitas: 5
Última edición:
Monté el circuito con los dos PIC y si funciona, porque obtengo los pulsos en ambos.
Hago el cambio de frecuencia con los pulsadores y en el segundo PIC si obtengo los dos pulsos variables.
(Visto con osciloscopio)

Si quieres ver los oscilogramas, los puedo capturar y subir.
 
Muchas gracias Dark byte, entonces tengo mi problema en algun conexionado de mi protoboard, muchas gracias. Aunque si fuera falso contacto en alguno de los cables o anda o no anda, pero al poner banderas para visualizar por donde andaba el programa, determine que no ingresa en los IF de los pulsos de disparo, lo cual no se porque. Pero por lo visto está andando como muestra la simulación. Nuevamente muchas gracias.
 
Última edición:
Saludos.

Pues sí. Así como lo hace la simulación, también lo hace físicamente.
A mi también me ha pasado y he tenido que tirar protoboards que han dejado de funcionar.

Cambia de protoboard o prueba en otro sector.

Suerte con tu proyecto.
 
Atrás
Arriba