1,使用DMA通过串口发送字符串,通过改写printf实现DMA传输调试中间信息,可避免字符丢失造成显示乱码,尤其在FreeRTOS下容易被其他进程中断造成丢失;
2,如果在程序中连续调用printf,则发现只把第一次发送的字符串传了出来,后面的都没发出;
3,查看HAL_UART_Transmit_DMA函数可知,在函数开头即检查DMA状态,如果忙则不进行发送即返回;
HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
uint32_t *tmp;
/* Check that a Tx process is not already ongoing */
if (huart->gState == HAL_UART_STATE_READY)
{
if ((pData == NULL) || (Size == 0U))
{
return HAL_ERROR;
}
......
else
{
return HAL_BUSY;
}
}
4,程序中连续调用printf即连续调用了HAL_UART_Transmit_DMA函数,而串口发送往往很慢,所以不等串口完成发送就再次调用,会导致发送函数直接返回BUSY而不实际发送数据;
5,解决的方法很简单:1,不连续调用printf,中间加延时,按传输量及波特率计算传输时间;2,加入DMA状态判断语句,如下:
while(HAL_DMA_GetState(&hdma_usart1_tx)==HAL_DMA_STATE_BUSY)
osDelay(5);
如果是裸机,用相应的延时函数即可;
Tip:程序调用DMA发送函数后,CPU不在发送函数代码中等待,而是继续执行后续代码。这和直接用串口发送不同。
本文探讨了在FreeRTOS环境下使用DMA通过串口发送字符串以避免字符丢失的问题。通过改写printf实现DMA传输,可以确保调试信息完整显示。当连续调用printf时,由于串口发送速度慢,可能导致HAL_UART_Transmit_DMA函数因DMA忙碌而返回Busy状态,从而丢失后续数据。解决方法包括在调用间加入适当延时或检查DMA状态。对于裸机系统,可使用相应延时函数,而在FreeRTOS中,可以使用osDelay配合DMA状态检查来确保数据发送完成。



7659

被折叠的 条评论
为什么被折叠?



