51单片机的全局变量被莫名其妙地修改了

仿真51单片机程序时发现一个很严重的BUG,程序里一个很重要的全局变量在运行时居然被改变了,原本设置的值是2000,但是调用时值居然是0,大致的代码如下:

//全局变量aaa值是2000
unsigned short aaa=2000;
void fun1(unsigned short x)
{
	unsigned short b;
	b=x;//这里仿真时发现全局变量莫名其妙变成0了
}
void fun2()
{
	...
	fun1(aaa);//调用全局变量
	...
}

全局变量为何会被改动呢?而且还被初始化为0了。

在前面加上关键字volatile防止编译器对变量进行优化,仿真后还是不行,全局变量仍被修改。我又尝试换成数组类型、结构体类型,结果仍然不能阻止全局变量被修改。为什么一个全局变量在内存里好好地待着,生命周期那么长,结果还被莫名其妙改动了?

我用的单片机是STC12C5A,之前看到过STC-ISP里延时函数定义变量用data修饰,然后查询关键字data是干什么用的。其实宏晶他们的单片机RAM有两个部分,一部分是兼容传统8051的RAM共256 Bytes,另一部分是XRAM扩展区比较大,这部分的大小根据不同型号是不一样的,我的这片的XRAM好像是2K Bytes。由于程序里变量太多,需要的RAM比较多,我在配置的时候选择较大内存区域,如下图
在这里插入图片描述
然后查询编译生成的map文件(也就是.m51文件),发现那个全局变量是被存在了扩展XRAM里,不是传统RAM里。变量那么多,很有可能放在XRAM里会被修改,而且单片机对传统RAM的访问速度比XRAM要快,所以我尝试将全局变量放在传统RAM里,程序如下

//用关键字data修饰就能把变量放在传统RAM里
unsigned short data aaa=2000;

仿真之后成功了,全局变量没有再被莫名其妙修改了。其实挺奇怪的,这些底层的编译和硬件居然也是会变,我还没搞明白为啥传统RAM里的变量更安全。

总结就是,如果全局变量存放在扩展XRAM里可能会被莫名其妙地被修改(就是不太安全),而存放在传统RAM里就挺安全的,尽管容量小了点。以后也尽量遵循这个规律:局部变量放在扩展XRAM里(用xdata修饰),全局变量最好放在传统RAM里(data修饰)。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值