清除 STM32 中的 USART (UART) 中断标志​​?

电器工程 微控制器 stm32 UART 中断 stm32f1
2022-01-06 10:22:49

我正在使用 STM32F105 通过 UART 与 Linx GPS 芯片进行通信。

如果我不使用中断(如果我只是轮询 RX 标志),那么它工作得很好。但是当我尝试使用中断时,我得到了意想不到的结果。

例如,如果我只使用 启用 RXNE(“RX 非空”)中断USART_ITConfig(USARTx, USART_IT_RXNE),那么代码应该只针对这一特定事件引导到 ISR。但是中断也会因溢出条件而被触发。

至于清除标志,似乎该方法取决于标志。要清除溢出标志 ( USART_IT_ORE),用户手册说明我应该先读取USARTx_SR寄存器,然后再读取USARTx_DR寄存器。这确实有效;标志被清除。

还有一个USART_ClearITPendingBit()函数,但它只接受一小部分标志。

有八种不同的中断源可以选择性地启用,以及十种不同的标志。 是否有关于如何管理所有这些标志的摘要?

3个回答

通常,您只需要处理您专门启用的中断标志USART_ITConfig()

但是,如果您启用 RXNE 中断 ( USART_ITConfig(USARTx, USART_IT_RXNE)),那么这也会启用溢出中断!所以你必须同时处理这两个问题。

内部图

USART 标志可能会造成混淆。有单独的状态标志和中断标志,它们具有相似的名称。例如:USART_IT_RXNEUSART_FLAG_RXNE

此外,还有多种方法可以清除这些标志。例如,该USART_ClearITPendingBit()函数仅适用于四个(十个)可能的标志。

以下是中断标志及其使用方法的摘要。这些特定于 STM32F105,但具有代表性:


USART_IT_TXE - “发送数据寄存器为空”

  • 调用时自动清除USART_SendData()

USART_IT_RXNE - “接收数据寄存器不为空”

  • 调用时自动清除USART_ReceiveData(USARTx)

  • 可以通过调用手动清除USART_ClearITPendingBit(USARTx, USART_IT_RXNE)


USART_IT_TC - “传输完成”

  • 它通过以下方式自动清除:

    • USART_GetITStatus(USARTx, USART_IT_TC)其次是
    • USART_SendData()
  • 也可以通过调用手动清除USART_ClearITPendingBit(USARTx, USART_IT_TC)


USART_IT_CTS - “CTS 更改”

  • 通过调用清除USART_ClearITPendingBit(USARTx, USART_IT_CTS)

USART_IT_LBD - “检测到 LIN 中断”

  • 通过调用清除USART_ClearITPendingBit(USARTx, USART_IT_LBD)

USART_IT_PE - “奇偶校验错误”

  • 清除者:
    • USART_GetITStatus(USARTx, USART_IT_PE)其次是
    • USART_ReceiveData(USARTx)

USART_IT_NE - “噪音错误”

  • 清除者:
    • USART_GetITStatus(USARTx, USART_IT_NE)其次是
    • USART_ReceiveData(USARTx)

USART_IT_ORE - “溢出错误”

  • 清除者:
    • USART_GetITStatus(USARTx, USART_IT_ORE)其次是
    • USART_ReceiveData(USARTx)()

USART_IT_IDLE - “检测到空闲线路”

  • 清除者:
    • USART_GetITStatus(USARTx, USART_IT_IDLE)其次是
    • USART_ReceiveData(USARTx)()

只是想在这个问题上添加一些我的经验,我按照说明进行操作:

USART_IT_ORE - “溢出错误”

清零:USART_GetITStatus(USARTx, USART_IT_ORE) 后跟 USART_ReceiveData(USARTx)()

似乎不起作用,而以下命令对我有用:

USART_GetFlagStatus(USARTx, USART_IT_ORE) 后跟 USART_ReceiveData(USARTx)

如果您查看功能:

USART_GetFlagStatus() 和 USART_ReceiveData()

你会发现Bitsmack之前写的到底是什么……“先读USARTx_SR寄存器,再读USARTx_DR寄存器。”

希望它对您有用并在此问题上节省更多时间。=)

读取statusdata寄存器清除溢出错误。

uint32_t cnt_rx2_overrun;
void USART2_IRQHandler(void)
{
  uint32_t status = USART2->SR;
  uint8_t ch;
  if (status & USART_SR_RXNE) { // rx data
    ch = USART2->DR;
    // parse data
  }
  else if (status & USART_SR_ORE){ // overrun error
    ch = USART2->DR; // reading clears the ORE flag
    cnt_rx2_overrun++;
  }

}
```