I am using an STM32F105 to communicate with a Linx GPS chip using a UART.
If I don't use interrupts (if I just poll the RX flag) then it works just fine. But I'm getting unexpected results when trying to use interrupts.
For example, if I only enable the RXNE ("RX not empty") interrupt using USART_ITConfig(USARTx, USART_IT_RXNE)
, then the code should only vector to the ISR for this one specific event. But the interrupt is being triggered for an Overrun condition, too.
As far as clearing the flags, it seems that the method depends on the flag.
To clear the Overrun flag (USART_IT_ORE
), the User Manual explains that I should first read the USARTx_SR
register, then read the USARTx_DR
register. This does work; the flag is cleared.
There is also a USART_ClearITPendingBit()
function, but it only accepts a small subset of flags.
There are eight different interrupt sources that can be selectively enabled, and ten different flags. Is there a summary somewhere of how to manage all of these flags?
Best Answer
Generally, you only need to handle the interrupt flags which you have specifically enabled with
USART_ITConfig()
.However, if you enable the RXNE interrupt (
USART_ITConfig(USARTx, USART_IT_RXNE)
) then this also enables the Overrun interrupt! So you must handle both of those.The USART flags can be confusing. There are separate status flags and interrupt flags and they share similar names. For example:
USART_IT_RXNE
andUSART_FLAG_RXNE
.In addition, there are various methods to clear these flags. For example, the
USART_ClearITPendingBit()
function only works for four (of the ten) possible flags.Here is a summary of the interrupt flags and how to use them. These are specific for the STM32F105, but are representative:
USART_IT_TXE - "Transmit Data register empty"
USART_SendData()
USART_IT_RXNE - "Receive Data register not empty"
It is cleared automatically when calling
USART_ReceiveData(USARTx)
It can be cleared manually by calling
USART_ClearITPendingBit(USARTx, USART_IT_RXNE)
USART_IT_TC - "Transmission complete"
It is cleared automatically by:
USART_GetITStatus(USARTx, USART_IT_TC)
followed byUSART_SendData()
It can be also be cleared manually by calling
USART_ClearITPendingBit(USARTx, USART_IT_TC)
USART_IT_CTS - "CTS change"
USART_ClearITPendingBit(USARTx, USART_IT_CTS)
USART_IT_LBD - "LIN Break detected"
USART_ClearITPendingBit(USARTx, USART_IT_LBD)
USART_IT_PE - "Parity error"
USART_GetITStatus(USARTx, USART_IT_PE)
followed byUSART_ReceiveData(USARTx)
USART_IT_NE - "Noise error"
USART_GetITStatus(USARTx, USART_IT_NE)
followed byUSART_ReceiveData(USARTx)
USART_IT_ORE - "Overrun error"
USART_GetITStatus(USARTx, USART_IT_ORE)
followed byUSART_ReceiveData(USARTx)()
USART_IT_IDLE - "Idle line detected"
USART_GetITStatus(USARTx, USART_IT_IDLE)
followed byUSART_ReceiveData(USARTx)()