• 单片机的变量竟然被无故修改了.


    有个变量 int GDValues[1200] ={0}
    竟然无缘无故的数值变动来变动去. 我禁用了所有与这个变量相关的代码仍然无法阻止数值变动. 真是奇怪了…长这么大第一次遇到这种情况.

    就想看看是那段代码在修改它. 不知道Keil有没有这个功能. 最后竟然找到了. 文章如下. 使用这个功能要先进入断点, 光标放在有效的行上, 然后在
    如下图操作.
    参考自. https://blog.csdn.net/mealu00/article/details/103461857

    1.首先进入仿真调试,打开想要查看的变量的watch窗口,在改变量右击,出现Set Access Breakpoint,
    在这里插入图片描述

    2.进入选项框 选中Write,然后定义,关闭窗口,运行软件,当改变量地址的值被篡改,则软件停止运行,便于查看内存溢出的现象
    在这里插入图片描述

    在这里插入图片描述
    等中断时发现, 竟然是被sprintf() 给修改了.
    在这里插入图片描述
    于是各种百度.貌似无果, 最后不得不放弃sprintf , 从原理上讲, sprintf 是可以自己实现的, 这样方便以后的开发. 毕竟解析json比解析二进制数据要方便的多. 临时比较急所以就暂时放弃了.
    再后来2天后, 才从人工智能哪里得知, sprintf的第一个参数buffer[] 的大小要足够长才行, 否则会溢出导致修改其它变量的数据. so, 只要改大sprintf 第一个参数buffer[] 的长度就可以了. 尽量盈余多一些,能够存下所有生成的字符串.

    sprintf() 函数还有个bug, 不知道是不是我的环境的问题, 对float类型无法转换, 不支持 %.2f这个 格式化.
    后来采取一个比较恶心人的方法, 先将小数 * 100 再强制转换成int类型. 发到上位机之后再除以100… 这样就保留了原来的2位小数. …

    下面是自己写了一个double转字符串的小工具.

    里面还是用的sprintf 它对%d , 不会出现什么问题. %f就不行.
    如果更彻底一些可以考虑自己从0实现一个.

    void doubleToStr(double v,int digits,char outstr[] )
    { 
    	//这里并没有考虑负数, 一般也不会出现负数, 如果有负数,请自行处理.
    	int zhengshu= (int)v; 
    	int xiaoshu = 0;
    	
    	if(digits==1)
    	{
    		xiaoshu = (int) ((v - zhengshu)*10);
    	}
    	if(digits==2)
    	{
    			xiaoshu = (int) ((v - zhengshu)*100);
    	}
    	if(digits==3)
    	{
    			xiaoshu = (int) ((v - zhengshu)*1000);
    	}
    	sprintf(outstr,"%d.%d",zhengshu,xiaoshu);
    	return ;  
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
  • 相关阅读:
    02-线性结构3 Reversing Linked List
    C语言练习百题之求100之内的素数
    Redis的set数据类型——Redis
    MyBatis3-源码剖析
    小程序中wxs
    记录npm的版本问题
    .NET Core Apollo 配置中心
    C语言实现扫雷小游戏
    mysql高阶语句
    深度神经网络检测方法,深度神经网络检测系统
  • 原文地址:https://blog.csdn.net/phker/article/details/134056670