STM32串口收发问题解决方案——HAL_UART_GetState使用技巧
一、背景
使用STM32串口同时接收和发送数据时。使用HAL_UART_GetState函数检查串口状态时,串口处于忙状态,就不会变回正常状态。这种情况让我想到有没有可能是stm32HAL库没有支持全双工,理论上来说串口应是全双工发送接收。
二、实验思路

HAL_UART_STATE_READY = 0x20U, //正常收法
HAL_UART_STATE_BUSY = 0x24U, //串口忙
深入查看UART_HandleTypeDef的定义
UART_HandleTypeDef huart1
typedef struct __UART_HandleTypeDef
{
USART_TypeDef *Instance; /*!< UART registers base address */
UART_InitTypeDef Init; /*!< UART communication parameters */
const uint8_t *pTxBuffPtr; /*!< Pointer to UART Tx transfer Buffer */
uint16_t TxXferSize; /*!< UART Tx Transfer size */
__IO uint16_t TxXferCount; /*!< UART Tx Transfer Counter */
uint8_t *pRxBuffPtr; /*!< Pointer to UART Rx transfer Buffer */
uint16_t RxXferSize; /*!< UART Rx Transfer size */
__IO uint16_t RxXferCount; /*!< UART Rx Transfer Counter */
__IO HAL_UART_RxTypeTypeDef ReceptionType; /*!< Type of ongoing reception */
DMA_HandleTypeDef *hdmatx; /*!< UART Tx DMA Handle parameters */
DMA_HandleTypeDef *hdmarx; /*!< UART Rx DMA Handle parameters */
HAL_LockTypeDef Lock; /*!< Locking object */
__IO HAL_UART_StateTypeDef gState; /*!< UART state information related to global Handle management
and also related to Tx operations.
This parameter can be a value of @ref HAL_UART_StateTypeDef */
__IO HAL_UART_StateTypeDef RxState; /*!< UART state information related to Rx operations.
This parameter can be a value of @ref HAL_UART_StateTypeDef */
__IO uint32_t ErrorCode; /*!< UART Error code */
...
根据注释可知状态有发送状态gState和接收状态RxState。接着查看HAL_UART_GetState函数内容。
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);
}
果然,官方是结合了两者的状态,只要其中一个处于忙状态就无法获取到真正的状态。
三、解决方法
以上图huart1为串口句柄为例,直接访问这两个状态即可。
int ret_state = HAL_UART_STATE_READY;
ret_state = huart3.RxState;
while (ret_state != HAL_UART_STATE_READY)//等待就绪
{
//huart1.gState = HAL_UART_STATE_READY;
printf("ret_state = %d\r\n",ret_state);
timeout++;超时处理
if (timeout > HAL_MAX_DELAY)
{
break;
}
ret_state = huart3.RxState;
}
if(timeout > HAL_MAX_DELAY)
{
break;
}
ret_state = huart3.RxState;
}