本文主要是介绍STM32串口,发送数据有几率错误的一个原因,需要避免DMA指向临时变量地址,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
/// @brief 串口发送一条格式化数据
void send_OneWeld_list_to_uart(uint16_t id)
{uint8_t char_data_uart[ONE_WEld_LIST_BYTE +2];char_data_uart[0] = 'M';//MCU 的数据char_data_uart[1] = 'I';//listmemcpy(&char_data_uart[2], &OneWeld_Data_new, sizeof(OneWeld_Data_TypeDef));Send_Data_toLCD(char_data_uart, sizeof(char_data_uart),100);
}/// @brief 通过DMA发送数据到LCD
/// @param pData 数据指针
/// @param Size 数据长度
/// @param timeout 超时时间
#pragma location = ".ccmram"
void Send_Data_toLCD(const uint8_t *pData, uint16_t Size,uint32_t timeout)
{uint32_t tickstart; tickstart = HAL_GetTick();while (huart1.gState != HAL_UART_STATE_READY) //等待发送完成{if (((HAL_GetTick() - tickstart) > timeout) || (timeout == 0U))return;Refresh_ModbusData_and_IWDG();}HAL_UART_Transmit_DMA(&huart1, pData, Size);
}
代码如上图,调用send_OneWeld_list_to_uart函数发送数据到LCD时,有几率出错!
原因是因为串口使用DMA发送,而给DMA的发送数据地址是一个临时变量,
在退出发送函数后,临时变量的地址被释放用于存储其他数据,
而串口发送速度是比较慢的(相较于CPU),这导致发送的数据有几率被修改。
解决方法:
- 将临时变量char_data_uart变量改为全局变量或静态变量,避免内存被释放。
- 或在send_OneWeld_list_to_uart函数内等待DMA发送完成后再进行后续的操作,避免退出函数后内存被释放!
- 修改Send_Data_toLCD函数,根据数据量拷贝数据到静态或全局变量,DMA指向拷贝后的变量
教训:一定要注意DMA的问题,之前还遇到过调试断点导出数据总是出错,运行时则没问题的情况,是因为DMA等大部分外设都不会因为CPU核心的停止而停止工作,调试断点时,CPU停止了,但是DMA并没有停止,导致导出的内存数据是错的。
这篇关于STM32串口,发送数据有几率错误的一个原因,需要避免DMA指向临时变量地址的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!