STM32串口,发送数据有几率错误的一个原因,需要避免DMA指向临时变量地址

本文主要是介绍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指向临时变量地址的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/962281

相关文章

Debian 13升级后网络转发等功能异常怎么办? 并非错误而是管理机制变更

《Debian13升级后网络转发等功能异常怎么办?并非错误而是管理机制变更》很多朋友反馈,更新到Debian13后网络转发等功能异常,这并非BUG而是Debian13Trixie调整... 日前 Debian 13 Trixie 发布后已经有众多网友升级到新版本,只不过升级后发现某些功能存在异常,例如网络转

GO语言短变量声明的实现示例

《GO语言短变量声明的实现示例》在Go语言中,短变量声明是一种简洁的变量声明方式,使用:=运算符,可以自动推断变量类型,下面就来具体介绍一下如何使用,感兴趣的可以了解一下... 目录基本语法功能特点与var的区别适用场景注意事项基本语法variableName := value功能特点1、自动类型推

深度剖析SpringBoot日志性能提升的原因与解决

《深度剖析SpringBoot日志性能提升的原因与解决》日志记录本该是辅助工具,却为何成了性能瓶颈,SpringBoot如何用代码彻底破解日志导致的高延迟问题,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言第一章:日志性能陷阱的底层原理1.1 日志级别的“双刃剑”效应1.2 同步日志的“吞吐量杀手”

SpringBoot3匹配Mybatis3的错误与解决方案

《SpringBoot3匹配Mybatis3的错误与解决方案》文章指出SpringBoot3与MyBatis3兼容性问题,因未更新MyBatis-Plus依赖至SpringBoot3专用坐标,导致类冲... 目录SpringBoot3匹配MyBATis3的错误与解决mybatis在SpringBoot3如果

MySQL 临时表与复制表操作全流程案例

《MySQL临时表与复制表操作全流程案例》本文介绍MySQL临时表与复制表的区别与使用,涵盖生命周期、存储机制、操作限制、创建方法及常见问题,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随小... 目录一、mysql 临时表(一)核心特性拓展(二)操作全流程案例1. 复杂查询中的临时表应用2. 临时

Linux查询服务器 IP 地址的命令详解

《Linux查询服务器IP地址的命令详解》在服务器管理和网络运维中,快速准确地获取服务器的IP地址是一项基本但至关重要的技能,下面我们来看看Linux中查询服务器IP的相关命令使用吧... 目录一、hostname 命令:简单高效的 IP 查询工具命令详解实际应用技巧注意事项二、ip 命令:新一代网络配置全

MySQL 临时表创建与使用详细说明

《MySQL临时表创建与使用详细说明》MySQL临时表是存储在内存或磁盘的临时数据表,会话结束时自动销毁,适合存储中间计算结果或临时数据集,其名称以#开头(如#TempTable),本文给大家介绍M... 目录mysql 临时表详细说明1.定义2.核心特性3.创建与使用4.典型应用场景5.生命周期管理6.注

nginx配置错误日志的实现步骤

《nginx配置错误日志的实现步骤》配置nginx代理过程中,如果出现错误,需要看日志,可以把nginx日志配置出来,以便快速定位日志问题,下面就来介绍一下nginx配置错误日志的实现步骤,感兴趣的可... 目录前言nginx配置错误日志总结前言在配置nginx代理过程中,如果出现错误,需要看日志,可以把

Django开发时如何避免频繁发送短信验证码(python图文代码)

《Django开发时如何避免频繁发送短信验证码(python图文代码)》Django开发时,为防止频繁发送验证码,后端需用Redis限制请求频率,结合管道技术提升效率,通过生产者消费者模式解耦业务逻辑... 目录避免频繁发送 验证码1. www.chinasem.cn避免频繁发送 验证码逻辑分析2. 避免频繁

Java.lang.InterruptedException被中止异常的原因及解决方案

《Java.lang.InterruptedException被中止异常的原因及解决方案》Java.lang.InterruptedException是线程被中断时抛出的异常,用于协作停止执行,常见于... 目录报错问题报错原因解决方法Java.lang.InterruptedException 是 Jav