Creo que lo que decis es mas "exactitud" que precision, pero si es de tanta exactitud imagino que lo estas haciendo en Assembler. Ya que sino estarias agregando instrucciones que no sabes en el codigo y cada instruccion es tiempo. A 20Mhz tenes un ciclo cada 0.05us , son 4 ciclos hasta que la bandera se pone en 1 detectando el cambio. Luego tenes el salto del procesador al vector, los cuales son otros 4 ciclos, finalmente estos vectores son saltos, por lo cual tenes otros 3 ciclos. Suponiendo que se ejecutaba alguna instruccion simple ( de 1 ciclo ) sino se termina la instruccion y procede al salto, lo cual puede agregarse unos 2 o 3 ciclos mas, Luego tenes todas las instrucciones ejecutadas, y tenes otros 4 ciclos mas de vuelta.
Hace alguna otra cosa el micro ademas de conectar la alarma?
Si no hace nada.. entonces lo podes hacer en el while(1) tranquilamente:
//Espero el flanco:
while(!PIND.2);
while(PIND.2);
// aca delay
delay_us(10);
// si esta en uno continuo aca
if(PIND.2)
{
//Activo alarma
}
Esa es una de las formas. Pero no deberias hacer nada mas en el while.
La otra es ir por el timer, interrupcion externa si es que tenes mas cosas en el while.
¿Como hacerlo con el timer?
Suponiendo que tenes esos 1+4+4+3 ciclos asegurados ( el 1 es un promedio de las instrucciones que puede llegar a cortar), tenes que son 12 ciclos de entrada mas 4 de salida.
Luego dentro de la interrupcion externa (flanco ascendente detectado) tenes que:
- Borrar el flag
- Cambiar el flanco de la interrupcion externa.
- Activar el timer (es decir darle entrada de reloj al mismo )
- Salir de interrupcion
Ahora falta el flanco descendente cuando es que vamos a calcular el tiempo. De entrar tenes:
- Borrar el flag
- Cambiar el flanco a ascendente
- Desactivar el reloj del timer
- Borrar flag del timer
- Cargar valor al timer
- Salir de interrupcion
El anterior caso es si no llego a detectarse nada. O que llego el flanco primero antes que el timer a completar, ahora falta el del timer.
- Borrar flag
- Desactivar timer
- Activar alarma
- Salir de interrupcion
Si suponemos que cada operacion ocupa al menos 3 ciclos cada uno, tenemos lo siguiente:
Flanco ascendente: 9 ciclos hasta activar el timer, mas 12 ciclos de entrada. desde que se detecto el flanco
Flanco descendente: Hasta detectarse 4 ciclos
Entonces el timer que deberia cargarlo con un valor de
10us / 0.05us = 200
Pero desde que se activa el flanco hasta que se pone en marcha el timer pasan 21 ciclos. Pero luego para detectar el otro flanco se tarda 4 mas. Dejandolo en 17 ciclos a restarle a esos 200
Quedando en 183, o cargarle el valor 256 - 183 = 73 al timer.
El apagado de la alarma se hace desde el while..
En resumen, lo que busco es una "carrera".. El flanco ascendente me activa el timer, y me configura la int externa.
De ahi pasa a ser una carrera entre la int externa y el timer.
Quien termina primero significa que el pulso es menor o mayor a 10us.
Si termina el timer significa que es mayor a 10us, si ocurre el flanco primero, entonces quiere decir que fueron menos de 10us.
Mayor precision y exactitud se lograria con ASM.