Tiempo de respuesta de interrupciones en PIC16F84A

Hola amigos.

Tengo un problema:
Me dispongo a programar un temporizador para arcades (máquinas de videojuegos) en el cual son varios los procesos que tienen que ejecutarse con precisión como sonidos de frecuencias exactas, multiplexión en displays, tiempo de juego, tiempo de aviso, etc.
Para todo esto estoy utilizando una resolución de tiempo de 50µs y la quiero marcar con el desbordamiento del Timer0.
Quiero que cada ciclo quede exacto pero para esto, quiero que no se me escape ningún ciclo máquina fuera del cálculo, que en mi caso es de 1µs ya que utilizo un cristal de 4MHz.

Yo se que para temporizaciones exactas debo disminuir un poco los pasos de la cuenta del Tmr0 y ajustar el tiempo con algunas instrucciones de relleno como la nop.
Digamos, si quiero contar 50µs entonces cargo al Tmr0 con una cantidad relativamente menor como -.45 (el signo menos es porque se resta de 256 ya que es un contador de 8 bits) que es lo mismo que .211 = 03. Dejo tal holgura para compensar los saltos del algoritmo. Conozco los tiempos de ejecución de cada instrucción de transferencia así como las de salto, pero el problema es que no conozco el tiempo de respuesta de cualquiera de las cuatro interrupciones que maneja este micro. Es decir, no se cuantos ciclos máquina (1µs) transcurren desde que se provoca la interrupción en cualquiera de sus orígenes (en este caso, por desbordamiento del Tmr0) hasta que el PC (contador de programa) se carga con la dirección 0004h.

Y es que en el libro "Microcontrolador PIC16F84 - Desarrollo de proyectos" menciona en el capítulo 17.2 que una interrupción es como una subrutina que atiende inmediatamente a la interrupción, si esto es realmente cierto el PC estaría cargado con la dirección 0x0004 un ciclo máquina (1µs) después de que se detecte la interrupción.

Por otro lado, el mismo libro en el capítulo 17.3 explica que desde el punto de vista del control del programa, una interrupción produce el mismo efecto que si se tuviese un "call 004h" en el instante preciso en que se produjo la interrupción. Si el mecanismo de interrupción trabaja igual en función del tiempo entonces podemos deducir que: desde el momento de la interrupción se ejecuta un salto de 2 ciclos máquina para llegar al vector de interrupción ORG 4.

En verdad necesito saber cuántos ciclos máquina consume el salto provocado por cualquier interrupción hasta el vector de interrupción. Esta información es realmente necesaria para realizar cálculos precisos en función del tiempo.

Les agradeceré cualquier ayuda.
Saludos.
 
Interrupt Latency

A very useful and unique property of PICs is that their interrupt latency is constant (it's also low: 3 instruction cycles). The delay is constant even though instructions can take one or two instruction cycles: a dead cycle is optionally inserted into the interrupt response sequence to make this true. External interrupts have to be synchronized with the four clock instruction cycle, otherwise there can be a one instruction cycle jitter. Internal interrupts are already synchronized.

The constant interrupt latency allows PICs to achieve interrupt driven low jitter timing sequences. An example of this is a video sync pulse generator. Other microcontrollers can do this in some cases, but it's awkward. The non-interrupt code has to anticipate the interrupt and enter into a sleep state before it arrives. On PICs, there is no need for this.

The three-cycle latency is increased in practice because the PIC does not store its registers when entering the interrupt routine. Typically, 4 instructions are needed to store the W-register, the status register and switch to a specific bank before starting the actual interrupt processing.

Lo saque de wikipedia.

Traducción mia: Una propiedad única y muy útil de los pics es que su latencia de interrupciones es constante (y tambien baja: 3 ciclos de reloj). La demora es constante aunque las instrucciones puedan tardar uno o dos ciclos: un ciclo muerto es generalmente insertado en la secuencia de recepcion de las interrupciones para hacer que sea verdad. Las interrupciones externas tienen que ser sincronizadas con el ciclo de cuatro instrucciones, de lo contrario puede haber un ciclo de más. Las interrupciones internas son sincronizadas automaticamente.
 
si vas a usar el timer, el timer es un contador que se incrementa cada pulso de reloj ; pasa de FD a FE a FF a 00 a 01 a 02 etc con cada ciclo de reloj (claro, tambien depende del prescalador) , no se detiene (a menos que lo hagas en el programa); en el paso de FF a 00 manda un pulso que se toma como interrupcion.
 
La información de gzaloprgm es muy interesante pero el documento que encontró habla sobre la suma de los retrasos totales de las interrupciones, lo cual es constante y por lo tanto no se incrementa la latencia. Y aqué habla sobre los ciclos de reloj, pero a lo que yo me refiero es a los ciclos máquina que son 4 ciclos de reloj, y en mi caso, cada uno es de 1µs porque el cristal que uso es de 4MHz.

Agradezco sus prontas respuestas, sin embargo seguí investigando y encontré un programa llamado PIC Simulator IDE de OshonSoft el cual, aunque es una copia de evaluación me sirvió para darme cuenta de cómo cambia cada registro del PIC a través de cada ciclo o instrucción. Entonces probando el software y llegué a la conclusión de que las interrupciones son ejecutadas inmediatamente un ciclo máquina después de que son provocadas o detectadas, en mi caso, 1µs después de haberse desbordado el TMR0. Si alguien quiere sacar sus propias conclusiones, pues les dejo el link de descarga del software y el adjunto del código fuente en .asm y su respectivo .hex para que comprueben lo que digo, así como también una diapositiva de los recortes de las fases del programa en ejecución con las acotaciones pertinentes para tomar en cuenta el funcionamiento del mismo y la evolución del programa del microcontrolador simulado.

Descarga PIC SIimulator
 

Adjuntos

  • interrupcin_tmr0_751.rar
    443 KB · Visitas: 39
Atrás
Arriba