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不在发送函数代码中等待,而是继续执行后续代码。这和直接用串口发送不同。