while(HAL_UART_GetState(&UartHandle) != HAL_UART_STATE_READY)
{
}
在DMA 的时候可能不会返回HAL_UART_STATE_READY
1. HAL_UART_GetState() 的工作原理
HAL_UART_GetState() 返回的是 两个状态的组合:
c
HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart)
{
uint32_t temp1 = 0x00U, temp2 = 0x00U;
temp1 = huart->gState; // 发送状态
temp2 = huart->RxState; // 接收状态
return (HAL_UART_StateTypeDef)(temp1 | temp2); // 按位或!
}
2. 状态组合表
| 发送状态 (gState) | 接收状态 (RxState) | GetState() 返回值 |
|---|---|---|
| READY (0x20) | READY (0x20) | READY (0x20) |
| BUSY_TX (0x21) | READY (0x20) | BUSY_TX (0x21) |
| READY (0x20) | BUSY_RX (0x22) | BUSY_RX (0x22) |
| BUSY_TX (0x21) | BUSY_RX (0x22) | BUSY_TX_RX (0x23) |
关键点 :GetState() 返回的是 组合状态 ,不是简单的 READY!
原因1:DMA接收导致状态为 BUSY_RX
// 当你调用这个函数后
HAL_UART_Receive_DMA(&UartHandle, aRxBuffer, sizeof(aRxBuffer));
// HAL库内部会设置:
huart->RxState = HAL_UART_STATE_BUSY_RX; // 0x22
// 所以 GetState() 返回的是:
// gState | RxState = 0x20 | 0x22 = 0x22 (BUSY_RX)
// 不是 0x20 (READY)!
原因2:DMA循环模式保持 BUSY 状态
// 如果DMA是循环模式(CIRCULAR)
hdma_usart2_rx.Init.Mode = DMA_CIRCULAR;
// 那么接收永远不会"完成"
// RxState 会一直保持为 BUSY_RX
// 所以 GetState() 永远不会返回 READY