STM32, C语言: sprintf写入字符串过长导致发送失败

   日期:2021-02-04     浏览:237    评论:0    
核心提示:问题描述最近在做的一个基于HAL库的STM32项目需要从多个SPI总线设备读取数据并通过DMA从串口发送,程序如下:(RxData为从SPI总线读取到的数据)sprintf(tempt, "%c%c%s%c%c%s%c%c%s%c%c%s", format[0], format[1], (char *)RxData1, format[2], format[3], (char *)RxData2, format[4], format[5], (char *)RxData3, format[6],

问题描述

最近在做的一个基于HAL库的STM32项目需要从多个SPI总线设备读取数据并通过DMA从串口发送,程序如下:
(RxData为从SPI总线读取到的数据)

sprintf(tempt, "%c%c%s%c%c%s%c%c%s%c%c%s",
	format[0], format[1], (char *)RxData1,
	format[2], format[3], (char *)RxData2,
	format[4], format[5], (char *)RxData3,
	format[6], format[7], (char *)RxData4);  // 格式化输出到字符串,每个RxData数组末尾已添加\0结束符
HAL_UART_Transmit_DMA(&huart1, (uint8_t *)&tempt, 72);

在电脑上位机观察接收,发现接收到的数据是完全错误的,而且在完成一次发送之后MCU程序卡死。

尝试解决

最初怀疑是格式化输出字符串长度过长而导致堆栈溢出,在CubeMX配置中将Heap和Stack大小改大,编译运行仍然会卡死。
由于是采用DMA发送,并且项目对性能要求较高,所以无法分别发送每组数据(因为若分别发送,则必须在每个发送间隙设置延时函数等待DMA发送完成,如果有更好的方法欢迎告诉我:-)),所以只能另想办法。

问题解决

最后,将程序改为以下形式,成功解决问题:
(使用额外的四个tempt数组暂存字符串,最后将这四个数组合并到另一个大数组再进行输出)

sprintf(tempt1, "%c%c%s", format[0], format[1], (char *)RxData1);
sprintf(tempt2, "%c%c%s", format[2], format[3], (char *)RxData2);
sprintf(tempt3, "%c%c%s", format[4], format[5], (char *)RxData3);
sprintf(tempt4, "%c%c%s", format[6], format[7], (char *)RxData4);
tempt1[18]='\0'; tempt2[18]='\0'; tempt3[18]='\0'; tempt4[18]='\0';
sprintf(tempt, "%s%s%s%s", (char *)tempt1, (char *)tempt2, (char *)tempt3, (char *)tempt4);
HAL_UART_Transmit_DMA(&huart1, (uint8_t *)&tempt, 72);

原因不明,由于占用了双倍的内存,所以肯定不是最优解决方法,如果有高手知道还请赐教。

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服