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
Programa que genera los pulsos de disparo a partir de la 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
}
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
Última edición: