Cómo obtener la misma cantidad de ciclos de reloj antes de ISR en un AVR

0

Mientras escribía un código de tiempo crítico para un Attiny13, pensé que podría usar el borde ascendente de una entrada como un activador para leer algunos datos de sincronización automática . Sin embargo, la cantidad de ciclos de reloj necesarios para ingresar a la rutina de interrupción varía según la instrucción que se esté ejecutando en ese momento.

  • ¿Cómo puedo asegurar que el tiempo desde la interrupción de flanco ascendente hasta el inicio de la rutina de interrupción sea siempre el mismo número de ciclos de reloj?

Excepto por la rutina de interrupción, no hay ningún código ejecutándose en este momento, ¿así que tal vez haya una manera de hacer un bucle con una única instrucción en el código principal?     

pregunta Douwe66

3 respuestas

2

Una opción sería tener dos disparadores, el primero hace que el código salte a un bucle esperando que la señal se apague y luego vuelva a subir. Tan pronto como la señal vuelva a ser alta, comience a sincronizar los datos.

Algo como:

while(PINREG & (1<<PORTBIT)); //wait for low
while(!(PINREG & (1<<PORTBIT))); //wait for next high
//Clock in your data here...

En ese código, los dos bucles while deberían simplificarse para bifurcarse cuando el bit en el registro se establece (o borra), lo que significa que cada 2 ciclos de reloj verificará el bit de activación, y una vez que se encuentre el segundo borde, comenzar con una latencia predecible.

Sin embargo, la latencia sería de +/- 1 ciclo dependiendo de dónde ocurrió el flanco ascendente en relación con el reloj, pero este sería el caso en todos los escenarios, ya que las señales pasan por un reloj sincronizado en la cadena de E / S.

Si su tasa de símbolo de datos es menor que ~ F_CPU / 4, entonces una pequeña variación en la latencia de lo anterior no debería ser un problema. Más rápido que eso, y probablemente no podría procesar nada; no hay tiempo para hacer nada con los datos a medida que los registra.

    
respondido por el Tom Carpenter
0

Tal vez pueda marcar la disponibilidad para aceptar una interrupción desde su código. Esto luego registra un flip flop tipo D y si la entrada D estaba configurada (lo que significa una interrupción pendiente), la salida del tipo D se convierte en el borde de interrupción "nuevo". Todo depende de tu habilidad para marcar la preparación.

    
respondido por el Andy aka
0

Creo que puedes girar en un bucle infinito RJMP esperando la interrupción. RJMP siempre toma 2 ciclos, por lo que debería tener menos de 2 ciclos de jitter entre el cambio de pin y la entrada al ISR.

Para salir del bucle RJMP, el ISR puede sacar la dirección de retorno de la pila y luego saltar al siguiente estado. También puede usar el temporizador para generar una interrupción para salir del bucle RJMP.

    
respondido por el bigjosh

Lea otras preguntas en las etiquetas