Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

STM32 UART 中斷無法進入排查:TXE 中斷衝突根因與修復方案

編輯:Linux 教學

STM32 串口調試中常遇到「配置正確、NVIC/GPIO 無誤,卻進不了 RXNE 接收中斷」的詭異現象。經大量實戰驗證,罪魁禍首往往是 **同時啟用 TXE(發送資料暫存器空)中斷** 導致的中斷風暴。本文深度剖析根因並給出標準化修復流程。

現象複現

USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE); // 接收中斷
USART_ITConfig(USARTx, USART_IT_TXE, ENABLE);  // 發送中斷 ← 關鍵問題行
USART_Cmd(USARTx, ENABLE);

現象:
🔴 程式跑飛、主迴圈卡死
🔴 RXNE 中斷服務程式 (ISR) 從未被調用
🔴 註釋掉 TXE 啟用行後一切恢復正常

根因深度解析

TXE 中斷觸發機制

  • USART 啟用瞬間,發送資料暫存器 (TDR) 為空 → **TXE 旗位立即置 1**
  • 若同時啟用 TXE 中斷,**中斷控制器會持續觸發 TXE ISR**
  • TXE ISR 必須寫入 USART_SendData() 才能清除旗位,否則無限重入

為何阻塞 RXNE?

  1. Cortex-M3/M4 採用**固定優先級搶佔**,若 TXE 與 RXNE 同優先級且 TXE 先響應
  2. TXE ISR 若未寫入資料(常見於「僅啟用中斷、無發送邏輯」的初始化階段),CPU 陷入**無限中斷循環**
  3. RXNE 中斷永遠無法獲得 CPU 時間片 → 表現為「進不了接收中斷」

標準修復方案

方案 A:按需啟用 TXE(推薦)

// 初始化時僅啟用 RXNE
USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE);

// 實際需要發送資料時,再動態啟用 TXE
void USART_SendString(USART_TypeDef* USARTx, char *str) {
    while (*str) {
        USART_SendData(USARTx, *str++);
        while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET); // 輪詢等待
    }
}
// 或配合 DMA 發送,完全避免 TXE 中斷

方案 B:TXE ISR 內正確清旗位

void USARTx_IRQHandler(void) {
    if (USART_GetITStatus(USARTx, USART_IT_TXE) != RESET) {
        if (tx_buffer_has_data()) {
            USART_SendData(USARTx, tx_buffer_pop()); // 寫入資料 → 自動清 TXE
        } else {
            USART_ITConfig(USARTx, USART_IT_TXE, DISABLE); // 無資料時關閉中斷
        }
    }
    if (USART_GetITStatus(USARTx, USART_IT_RXNE) != RESET) {
        rx_buffer_push(USART_ReceiveData(USARTx));
    }
}

最佳實踐清單

  • ✅ **預設不啟用 TXE 中斷**,改用輪詢或 DMA 發送
  • ✅ 若必須用 TXE 中斷,ISR 內**必須**寫入資料或關閉該中斷
  • ✅ 發送緩衝區設計為環狀隊列,支援中斷安全讀寫
  • ✅ 中斷優先級分組配置:NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2)(2 位搶佔 + 2 位響應)
  • ✅ 使用 CubeMX 生成初始化代碼後,**務必人工核對中斷啟用邏輯**

延伸:TC vs TXE

旗位含義適用場景
TXE發送暫存器空,可寫入下一幀連續發送、中斷/DMA 驅動
TC傳輸完全結束(移位寄存器也空)最後一幀發送後切換模式/進入低功耗

掌握 TXE 中斷特性,杜絕「中斷風暴」導致的系統假死,是 STM32 串口穩定運行的關鍵一環。

Copyright © Windows教程網 All Rights Reserved