¿Cómo verificar si una interrupción periférica específica está habilitada en NVIC?

1

Estoy usando una placa de descubrimiento STM32F4 con la biblioteca de periféricos estándar (SPL) de ST. Tengo una situación con un búfer circular: la interrupción del temporizador es hacer clic en los botones y llenar un búfer circular cada milisegundos si se presiona un botón, con un índice de ese botón. El bucle principal luego lo saca del búfer circular y ejecuta el comando apropiado. Ambas acciones requieren varios pasos (verificación y cambio de índices a búfer circular, ...).

Cuando esto sucede en el bucle principal, la interrupción del temporizador se debe desactivar durante un breve período de tiempo (para que los índices no se desordenen), pero no quiero desactivar todas las interrupciones solo para eso. Además, es preferible que una interrupción siga siendo reparada si sucedió mientras estaba desactivada.

Intenté hacer esto deshabilitando la interrupción del temporizador para ese temporizador específico (TIM6 en mi caso) en el NVIC (pero lo dejé habilitado en el propio temporizador). Pero luego descubrí que no hay forma de verificar si las interrupciones estaban deshabilitadas en primer lugar, antes de deshabilitarlas (no puedo habilitar las interrupciones nuevamente si no estaban habilitadas antes, ya que puede desordenar las cosas).

Así que mis preguntas son:

  • ¿Cómo verifico si una interrupción periférica específica está habilitada en el NVIC? (Solo hay funciones EnableIRQ y DisableIRQ ).

    Intenté verificar el valor en

    NVIC->ICER[((uint32_t)(IRQn) >> 5)];

    y

    NVIC->ISER[(uint32_t)((int32_t)IRQn) >> 5];

    pero salen 0 incluso si la interrupción está habilitada.

  • ¿Se seguirá atendiendo la interrupción (si se produjo cuando se deshabilitó solo en el lado de NVIC) cuando se habilite nuevamente?

pregunta Terraviper-5

1 respuesta

3

Respuesta rápida:

Yo usaría el siguiente código (feo):

if (NVIC->ISER[(uint32_t)((int32_t)IRQn) >> 5] &
   (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F))
{
    // It's enabled!
}

Explicación :

Los registros NVIC_ISERx son de doble propósito. Si escribe un 1 en un bit específico, se habilitará la interrupción. Si lees un bit específico, te dirá si la interrupción está habilitada:

EstáutilizandolaSPLy,porlotanto,estágestionandolaasignacióndelasfuentesdeinterrupciónalosregistrosdeISERylasubicacionesdelosbits.

Enelarchivocore_cm4.h,versión3.00,estaeslafunciónNVIC_EnableIRQ():

__STATIC_INLINEvoidNVIC_EnableIRQ(IRQn_TypeIRQn){/*NVIC->ISER[((uint32_t)(IRQn)>>5)]=(1<<((uint32_t)(IRQn)&0x1F));enableinterrupt*/NVIC->ISER[(uint32_t)((int32_t)IRQn)>>5]=(uint32_t)(1<<((uint32_t)((int32_t)IRQn)&(uint32_t)0x1F));/*enableinterrupt*/}

Esinteresantequecomentaronlaprimeralínea(queeraidénticaalamismafunciónencore_cm3.h)yladejaronallí;Supongoquefueunacorreccióndeerroresyseolvidarondeeliminarelcódigoincorrecto.Meperdíportodaslastipografías,peroesperoqueseannecesarias.

MirespuestaanteriorsebasaenestafunciónNVIC_EnableIRQ().

Encuantoalcomportamientodelsistema,setomalosiguientedeldocumentoPM0056deST(queesparaM3,noM4,peroelcomportamientoessimilar):

  

Sisehabilitaunainterrupciónpendiente,elNVICactivalainterrupciónenfuncióndesuprioridad.Siunainterrupciónnoestáhabilitada,laafirmacióndesuseñaldeinterrupcióncambiaelestadodeinterrupciónapendiente,peroelNVICnuncaactivalainterrupción,independientementedesuprioridad.

Sielindicador"pendiente" se establece, la interrupción se servirá tan pronto como vuelva a habilitar la interrupción.

    
respondido por el bitsmack

Lea otras preguntas en las etiquetas