逐步debug DMA发送函数,HAL_UART Transmit DMA,发现函数会对串口句柄的一个状态位,gState 进行判断,只有在 huart->gState==HAL UART STATE READY 的时候才会正常进行发送,
而第一次发送可以成功,便是因为一开始,gState为HAL_UART_STATE_READY,因此,可以成功发送,而在第一次发送时,HAL_UART_Transmit_DMA 函数会将gState 更改为HAL_UART_STATE_BUSY_TX 状态,gState 位随后一直保持为HAL_UART_STATE_BUSY_TX状态,导致后面的发送无法执行,而gState 状态想要被清除必须要进入串口中断HAL_UART_IRQHandler中的UART_EndTransmit_IT里面,在UART_EndTransmit_IT函数中清除了gState标志位。
我的问题就是串口中断只能第一次进入,后面就不进入了,所以发送失败。在调试的时候偶尔能发送和接收都正常,各位能帮忙给点建议吗?下面是我的代码:
[C] 纯文本查看 复制代码 void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART3)
{
if (HAL_UARTEx_ReceiveToIdle_DMA(&huart3, usart3RxBuff, MAX_COM3_RXSIZES) == HAL_BUSY) // 接收发生错误后重启
{
__HAL_UART_CLEAR_OREFLAG(&huart3);
huart3.RxState = HAL_UART_STATE_READY;
huart3.Lock = HAL_UNLOCKED;
HAL_UARTEx_ReceiveToIdle_DMA(&huart3, usart3RxBuff, MAX_COM3_RXSIZES);
}
initSqQueue(&uart[_COM3].Rx, usart3RxBuff, sizeof(usart3RxBuff));
memset(usart3RxBuff, 0, MAX_COM3_RXSIZES);
return;
}
}
[C] 纯文本查看 复制代码 void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
if (huart->Instance == USART3)
{
uart[_COM3].Rx.rear = Size; // 写入rear
// bleAppConfig.rxAct = 1;
#ifdef _UART3_DEBUG
uartxEcho(&huart3, &uart3);
#endif
if (uart[_COM3].rxEnd == true)
{
uart[_COM3].rxIdle = false;
initUartTick(&uart[_COM3], CONST_UART_DLY_TIM);
}
else
{
uart[_COM3].rxIdle = true;
initUartTick(&uart[_COM3], CONST_UART_DLY_TIM);
// MAP_Interrupt_disableSleepOnIsrExit();
}
return;
}
UNUSED(huart);
}
[C] 纯文本查看 复制代码 void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART3)
{
uart[_COM3].sBusy = false;
#ifdef MAX_COM3_TXSIZES
memset(usart3TxBuff, 0, MAX_COM3_TXSIZES);
#endif
return;
}
UNUSED(huart);
}
主程序开始调用函数HAL_UARTEx_ReceiveToIdle_DMA(&huart3, usart3RxBuff, MAX_COM3_RXSIZES); 发送调用的函数为HAL_UART_Transmit_DMA(huart, (const uint8_t *)buf, num);调试时buf和num都是正确的,发出去就没有数据。如果不使用DMA发送的话,那么接收的时候就会进入HAL_UART_ErrorCallback错误回调。
|