¿Borrar banderas de interrupción USART (UART) en un STM32?

8

Estoy usando un STM32F105 para comunicarme con un chip GPS Linx usando un UART.

Si no uso interrupciones (si solo sondeo el indicador RX), entonces funciona bien. Pero obtengo resultados inesperados cuando trato de usar interrupciones.

Por ejemplo, si solo habilito el uso de la interrupción RXNE ("RX no está vacío") USART_ITConfig(USARTx, USART_IT_RXNE), el código solo debería vectorizar al ISR para este evento específico. Pero la interrupción también se activa por una condición de Desbordamiento.

En cuanto a borrar las banderas, parece que el método depende de la bandera. Para borrar la bandera de Desbordamiento ( USART_IT_ORE), el Manual del usuario explica que primero debería leer el USARTx_SRregistro y luego leer el USARTx_DRregistro. Esto funciona La bandera se borra.

También hay una USART_ClearITPendingBit()función, pero solo acepta un pequeño subconjunto de banderas.

Hay ocho fuentes de interrupción diferentes que se pueden habilitar selectivamente y diez banderas diferentes. ¿Hay algún resumen en alguna parte sobre cómo administrar todas estas banderas?

bitsmack
fuente

Respuestas:

16

En general, solo necesita manejar los indicadores de interrupción con los que ha habilitado específicamente USART_ITConfig().

Sin embargo, si habilita la interrupción RXNE ( USART_ITConfig(USARTx, USART_IT_RXNE)), ¡esto también habilita la interrupción Overrun! Así que debes manejar ambos.

intmap

Las banderas USART pueden ser confusas. Hay indicadores de estado e indicadores de interrupción separados y comparten nombres similares. Por ejemplo: USART_IT_RXNEy USART_FLAG_RXNE.

Además, hay varios métodos para borrar estas banderas. Por ejemplo, la USART_ClearITPendingBit()función solo funciona para cuatro (de los diez) posibles indicadores.

Aquí hay un resumen de las banderas de interrupción y cómo usarlas. Estos son específicos para el STM32F105, pero son representativos:


USART_IT_TXE - "Transmitir registro de datos vacío"

  • Se borra automáticamente al llamar USART_SendData()

USART_IT_RXNE - "El registro de recepción de datos no está vacío"

  • Se borra automáticamente al llamar USART_ReceiveData(USARTx)

  • Se puede borrar manualmente llamando USART_ClearITPendingBit(USARTx, USART_IT_RXNE)


USART_IT_TC - "Transmisión completa"

  • Se borra automáticamente por:

    • USART_GetITStatus(USARTx, USART_IT_TC) seguido por
    • USART_SendData()
  • También se puede borrar manualmente llamando USART_ClearITPendingBit(USARTx, USART_IT_TC)


USART_IT_CTS - "Cambio de CTS"

  • Aclarado llamando USART_ClearITPendingBit(USARTx, USART_IT_CTS)

USART_IT_LBD : "LIN Break detectado"

  • Aclarado llamando USART_ClearITPendingBit(USARTx, USART_IT_LBD)

USART_IT_PE - "Error de paridad"

  • Autorizado por:
    • USART_GetITStatus(USARTx, USART_IT_PE) seguido por
    • USART_ReceiveData(USARTx)

USART_IT_NE - "Error de ruido"

  • Autorizado por:
    • USART_GetITStatus(USARTx, USART_IT_NE) seguido por
    • USART_ReceiveData(USARTx)

USART_IT_ORE - "Error de desbordamiento "

  • Autorizado por:
    • USART_GetITStatus(USARTx, USART_IT_ORE) seguido por
    • USART_ReceiveData(USARTx)()

USART_IT_IDLE - "Línea inactiva detectada"

  • Autorizado por:
    • USART_GetITStatus(USARTx, USART_IT_IDLE) seguido por
    • USART_ReceiveData(USARTx)()
bitsmack
fuente
Sí, respondí mi propia pregunta :) Si hubiera encontrado una lista como esta antes, me habría ahorrado una buena cantidad de tiempo. ¡Espero que esto ayude a alguien!
Bitsmack
2
Esta respuesta es oro; referencia muy clara de cómo borrar cada una de estas interrupciones.
jjmilburn
2

Solo quiero agregar algo de mi experiencia en este problema, sigo las instrucciones:

USART_IT_ORE - "Error de desbordamiento"

Autorizado por: USART_GetITStatus (USARTx, USART_IT_ORE) seguido de USART_ReceiveData (USARTx) ()

Parece que no funciona, y el siguiente comando funciona para mí:

USART_GetFlagStatus (USARTx, USART_IT_ORE) seguido de USART_ReceiveData (USARTx)

Si nos fijamos en las funciones:

USART_GetFlagStatus () y USART_ReceiveData ()

Encontrará exactamente lo que Bitsmack escribió antes ... "Primero lea el registro USARTx_SR, luego lea el registro USARTx_DR".

Espero que funcione para usted y ahorre mucho más tiempo en este tema. =)

LostInCoding
fuente
¡Gracias por tu información! No reconozco USART_GetFlat (). ¿Me puede decir de dónde viene?
bitsmack
Lamento haber escrito incorrectamente el comando, debería ser USART_GetFlagStatus () seguido de USART_ReceiveData (), se corrigió la publicación original. Gracias Bitsmack
LostInCoding
¡Excelente gracias! Parece que los nombres de las funciones han cambiado. ¿Está utilizando una biblioteca periférica estándar o uno de los HAL de STMCube? ¿Para qué familia de microcontroladores?
bitsmack