Diga que ha habilitado las interrupciones TMR0 y TMR1 configurando TMR0IE y TMR1IE. Cuando cualquiera de los eventos de interrupción ocurre, sus indicadores de interrupción (TMR0IF o TMR1IF) se establecen. Esto no hace que el código se transmita a la rutina de interrupción a menos que también se establezca el bit GIE (habilitación de interrupción global).
Entonces, digamos que GIE se ha establecido y se obtiene un desbordamiento de TMR0. Esto establece TMR0IF, los vectores a la ubicación de la interrupción, y borra el bit GIE . Ahora que GIE está desactivado, los desencadenadores de interrupciones futuras no causarán ningún vector de código. Sin embargo, los indicadores de interrupción aún se establecen.
Ahora, di que estás en tu rutina de interrupción. La interrupción TMR1 se dispara. Esto establece el bit TMR1IF, pero no hace nada más. El bit simplemente se mantiene establecido.
Cuando finaliza su rutina de interrupción, usa una declaración RETFIE
(en ensamblaje) o un return();
(en c). Este vector vuelve a su código de línea principal, y establece el bit GIE .
Ahora que los bits GIE y TMR1IF están configurados, se genera un vector inmediato en su código de interrupción.
Entonces, realmente no pierdes datos de interrupción; simplemente se retrasa.
Una forma común de estructurar un ISR es la siguiente:
if (TMR0IF && TMR0IE)
{
(do something)
TMR0IF = 0; // Clear the flag!
return();
}
else if (TMR1IF && TMR1IE)
{
(do something else)
TMR1IF = 0;
return();
}
Pero, si espera tener interrupciones simultáneas, es posible que desee permitir que ambas se procesen en una sola pasada a través del ISR:
if (TMR0IF && TMR0IE)
{
(do something)
TMR0IF = 0;
}
if (TMR1IF && TMR1IE) // Notice this isn't an "else if"
{
(do something else)
TMR1IF = 0;
}
return();
Hay un último problema a tener en cuenta. Digamos que ambos indicadores de interrupción se establecen al mismo tiempo (o casi al mismo tiempo). En el momento en que el código de los vectores a la rutina de interrupción, ambos indicadores ya estarán configurados. El ISR no sabe cuál se configuró primero ; simplemente se ejecuta a través de su código. Así que en mis ejemplos anteriores, la interrupción TMR0 se reparará primero, incluso si el indicador TMR1 fue ligeramente anterior.
Espero que esto ayude :)