溢出錯誤
出現的串口接收過程中,中斷接收在溢出后無法進入,需要重點考慮溢出問題,以下是溢出恢復代碼
波特率115200? ? ? 優先級0-1? 高于定時器? ? ?初步診斷是數據流導致的接收溢出問題
/*** @brief 檢查并清除UART溢出錯誤(帶狀態驗證)* @param huart: UART句柄指針* @retval HAL_OK: 成功清除 | HAL_ERROR: 無溢出或清除失敗*/
HAL_StatusTypeDef UART_CheckAndClearOverrun(UART_HandleTypeDef *huart)
{// 1. 檢查ORE標志是否存在if(!__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE)) {return HAL_ERROR; // 無溢出錯誤}// 2. 原子操作保護uint32_t primask = __get_PRIMASK();__disable_irq();// 3. 清除流程(嚴格順序)volatile uint8_t tmp = huart->Instance->RDR; // 必須讀取DR__HAL_UART_CLEAR_OREFLAG(huart); // 官方推薦清除方式__HAL_UART_FLUSH_DRREGISTER(huart); // 確保FIFO清空// 4. 驗證是否清除成功HAL_StatusTypeDef status = __HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) ? HAL_ERROR : HAL_OK;// 5. 重啟接收中斷(可選)if(status == HAL_OK) {__HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);__HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);}// 6. 恢復中斷狀態if(!(primask & 1)) __enable_irq();return status;
}
問題查找方式
溯源方式:DEBUG查找判斷是否執行
// 1. 檢查ORE標志是否存在if(!__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE)) {return HAL_ERROR; // 無溢出錯誤}
重點,不要加在串口接收中斷函數中,不會觸發,采用定時器一段時間檢查一次即可
讀串口對應的CR1可以確認接收中斷有沒有使能,2D代表對應的位使能,0D則不使能說明被意外關閉了。
對應的STATE則用來進一步輔助判斷,因為中斷和ISR會有延遲的情況發生,不可單獨依靠這兩個去判斷。
發送阻塞卡死
另外一種出現的發送卡死在以下函數中的問題:
HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout)
{/* Wait until flag is set */while((__HAL_UART_GET_FLAG(huart, Flag) ? SET : RESET) == Status){/* Check for the Timeout */if(Timeout != HAL_MAX_DELAY){if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)){/* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE));CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);huart->gState = HAL_UART_STATE_READY;huart->RxState = HAL_UART_STATE_READY;/* Process Unlocked */__HAL_UNLOCK(huart);return HAL_TIMEOUT;}}}return HAL_OK;
}
溯源發生在兩種情況下,第一種是中斷優先級過低,被打斷導致;第二種則是錯誤的在其他地方,人為的去操作串口的STATE位的狀態,導致的串口狀態混亂,所以請務必遵守HAL庫默認的狀態機情況,不要雜亂的修改導致狀態混亂的情況發生。
// 在初始化末尾添加(HAL_UART_Init之后)__HAL_UART_DISABLE_IT(huart, UART_IT_TXE | UART_IT_TC); // 明確禁用發送中斷huart->Instance->CR1 &= ~(USART_CR1_TXEIE | USART_CR1_TCIE); // 寄存器級禁用
串口發送中斷被禁用的情況下請不要調用對應的清理串口發送中斷的HAL庫函數,一定幾率造成堵死。
HAL_GetTick
計數失效導致的問題
請確保HAL_GetTick函數未失效,不管是使用WDT硬件計數器還是滴答定時器,在使用滴答定時器的時候請注意滴答定時器的中斷優先級問題導致的一系列問題。
緩沖器資源沖突問題
環形緩沖區在讀取和寫入的時候,特別針對主函數一邊讀涉及到刪除,中斷寫入的情況下,需要注意資源沖突問題,在寫或者讀的時候,進行保護。