Múltiples interrupciones simultáneas PIC16F88

3

Soy nuevo en los microcontroladores PIC (tengo algo de experiencia con Arduino pero quería una experiencia "real" = P). Me conseguí un PIC16F88 y tengo la intención de hacer un robot simple con dos motores de 2 CC. Cada motor será controlado de forma independiente a través de PWM.

Quiero implementar las señales PWM en el software (ya sé, ¡una experiencia de aprendizaje bastante buena!). Este microcontrolador solo tiene un módulo PWM, pero me gustaría hacerlo en software incluso si tuviera más.

Sin más preámbulos:

¿Qué sucede cuando se producen dos interrupciones de desbordamiento del temporizador al mismo tiempo? ¿El controlador ignora uno? ¿Ambos llamarán al vector de interrupción uno tras otro?

    
pregunta Ethienne

1 respuesta

4

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 :)

    
respondido por el bitsmack

Lea otras preguntas en las etiquetas