Lograr conteo exacto en microsegundos con PIC16f76 y ccs para detector de velocidad

#1
Hola como estan, estoy intentando hacer un detector de velocidad con un pic16f876 y utilizando ccs para hacer el programa, la cuestion esta en que para ello requiero que el pic me logre contrar almenos en centenas de microsegudos, es decir, de 100u en 100u, asi que empece por hacer una rutina que me active el timer0 cuando se active el puerto A0 y que se detenga cuando se active el puerto A1, ya que usare dos detectores de presencia para calcular la velocidad. pero al hacerlo me da tiempos equivocados y por tanto velocidadades equivocadas, pense en principio que era por los retardos que me dan las instrucciones del ccs, por eso entré en la opcion del compilador que me da el assembler de cada instruccion, saque mis cuentas de los retardos por instruccion y observo que las cuentas se cumplen perfectmente cuando la cuenta estaba por los segundos, pero cuando se cuenta en milisegundos que va!! da errores y peor aun llego un punto en el que solo era de contar 18.4 milisegundos, es decir, a partir de 30 milisegundos para abajo solo contaba 18,4 milisegundos por favor requiero ayuda que puedo hacer para tener el tiempo mas exacto sin tener que usar nada mas que el pic?

aca coloco el codigo:

#include <16f876.h>
#fuses HS,NOWDT
#use delay(clock=20000000)
#include <lcd.c>

double useg=0;
double v=0,th=0;

#int_TIMER0
void TIMER0_isr()
{
useg=useg+1;
set_timer0(220);
}

void main()
{
lcd_init();
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2|RTCC_8_BIT);
enable_interrupts(int_timer0);
enable_interrupts(global);
WHILE (1)
{
while (input(PIN_A0)==0){}//Espera activación de primer sensor
set_timer0(220);
enable_interrupts(INT_TIMER0);
while (input(PIN_A1)==0){}//Espera activación de segundo sensor
th=useg*0.0001;
v=(1.5/th)*3.6;// calculando la velocidad asumiendo distancia de 1.5 metros
printf(lcd_putc,"\fTiempo:\n%01.4g",th);
useg=0;
while (input(PIN_A0)==1){}//Espera desactivación de primer sensor
}

}
 
#2
Hola @arcadio, te comento que si quieres exactitud, lo mejor es programar en assembler, incluso con ello hay que hacer pequeñas correcciones, en lenguaje c con mas razon ya que el compilador introduce codigos adcionales que estan fuera de control del programador y nada se puede hacer mas que tener un buen depurador(PROTEUS).

bueno, te mando unas correciones a tu codio y me parece que de algun modo satisface las necesidades.

Un saludo.
 

Adjuntos

#3
Gracias Saint_ por tu ayuda, pues te conenbto que yo estaba usando proteus para probar, y pues hice las modificaciones que me recomendaste pero sigue andando igual, si pongo tiempos menores a 32 milisegundos me marca 0.0000 y si los pongo de ahi para arriba tengo errores, por ejemplo, si pruebo con 60 milisegundos el pic me arroja 28 milisegundos, lo raro es que a mayor tiempo menor es el error, que podra ser? por cierto dos cosas: una es que no pude ver tu esquematico de proteus ya que me dice que tienes una version anterior podrias colocarme una foto de tu esquematico? y la otra es que hace el delay_cycles(1)?
 
#4
¿No tiene una unidad de comparación-captura? Son para eso precisamente y se hace todo tranquilamente en harware. Igual te interesa un derivado que la lleve.
 
#5
Hola arcadio, te comento que delay_cycles(1) es para ajustar que la interrupcion del timer0 sea de 100us.

aqui los esquemas con los que hice la prueba el desempeño del programa.
 

Adjuntos

#6
No scooter debo hacerlo todo con el pic porque asi es el proyecto, y Saint_ no entiendo como a mi no me da bien si yo utilizo dos generadores de pulso que raro, por cierto que reloj le colocaste al pic en proteus?
 
Última edición:

Temas similares

Arriba