AXD仿真中关于变量不会被改变的疑惑?

[复制链接]
2661|5
 楼主| kevinleez 发表于 2008-6-18 08:40 | 显示全部楼层 |阅读模式
我在仿真的时候发现一个问题:<br />unsigned&nbsp;char&nbsp;A,B;<br /><br />void&nbsp;test(void)<br />{<br />&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;tmp;<br />&nbsp;&nbsp;&nbsp;A=0;<br />&nbsp;&nbsp;&nbsp;B=0;<br />&nbsp;&nbsp;&nbsp;while(1){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp&nbsp;=&nbsp;A&nbsp;-&nbsp;B;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(tmp&nbsp;&gt&nbsp;12){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//执行特殊功能<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//.....<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;}<br />}<br />我在中断程序中有对A进行不断加1的操作,可是永远进不去“执行特殊功能”执行并且跳出的功能,我看了汇编,似乎程序while(1)上面对A和B赋值为0后,tmp就定死是0了。中断对A的增加,在此处无效了。<br /><br />难道是被ADS编译优化掉了?搞了一天没有搞定。<br /><br />unsigned&nbsp;char&nbsp;BootPt(void)<br />{<br />&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;tmp;<br />&nbsp;&nbsp;&nbsp;tmp&nbsp;=&nbsp;A&nbsp;-&nbsp;B;<br />&nbsp;&nbsp;&nbsp;return&nbsp;tmp;<br />}<br /><br />void&nbsp;test(void)<br />{<br />&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;tmp;<br />&nbsp;&nbsp;&nbsp;A=0;<br />&nbsp;&nbsp;&nbsp;B=0;<br />&nbsp;&nbsp;&nbsp;while(1){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp&nbsp;=&nbsp;BootPt();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(tmp&nbsp;&gt&nbsp;12){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//执行特殊功能<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//.....<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;}<br />}<br />把程序变成这样,勉强可以使用。<br /><br />为什么会这样,求教了,急!!!!<br />在线等待中......<br />
gugou 发表于 2008-6-18 09:17 | 显示全部楼层

难道volatile?

曾经,用avr经常用到的,你可以试一下。
dld2 发表于 2008-6-18 09:38 | 显示全部楼层

2楼正解

  
computer00 发表于 2008-6-18 09:40 | 显示全部楼层

恩,中断和主程序中都使用的全局变量,用volatile声明

这样编译器就不会优化掉它了。
 楼主| kevinleez 发表于 2008-6-18 16:02 | 显示全部楼层

ok了。

加了volatile就好了。哈哈。谢谢各位。
tigerots 发表于 2008-6-20 10:48 | 显示全部楼层

volatile

一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:&nbsp;<br />1).&nbsp;并行设备的硬件寄存器(如:状态寄存器)&nbsp;<br />2).&nbsp;一个中断服务子程序中会访问到的非自动变量(Non-automatic&nbsp;variables)&nbsp;<br />3).&nbsp;多线程应用中被几个任务共享的变量&nbsp;<br />&nbsp;&nbsp;&nbsp;这是区分C程序员和嵌入式系统程序员的最基本的问题。嵌入式系统程序员经常同硬件、中断、RTOS等等打交道,所用这些都要求volatile变量。不懂得volatile内容将会带来灾难。&nbsp;<br /><br />1).&nbsp;一个参数既可以是const还可以是volatile吗?解释为什么。&nbsp;<br />2).&nbsp;一个指针可以是volatile&nbsp;吗?解释为什么。&nbsp;<br />3).&nbsp;下面的函数有什么错误:&nbsp;<br />int&nbsp;square(volatile&nbsp;int&nbsp;*ptr)&nbsp;<br />{&nbsp;return&nbsp;*ptr&nbsp;*&nbsp;*ptr;&nbsp;<br />}&nbsp;<br /><br />下面是答案:&nbsp;<br />1).&nbsp;是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。&nbsp;<br />2).&nbsp;是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。&nbsp;<br />3).&nbsp;这段代码的有个恶作剧。这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:&nbsp;<br />int&nbsp;square(volatile&nbsp;int&nbsp;*ptr)&nbsp;<br />{&nbsp;int&nbsp;a,b;&nbsp;<br />a&nbsp;=&nbsp;*ptr;&nbsp;<br />b&nbsp;=&nbsp;*ptr;&nbsp;<br />return&nbsp;a&nbsp;*&nbsp;b;&nbsp;<br />}&nbsp;由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:&nbsp;<br />long&nbsp;square(volatile&nbsp;int&nbsp;*ptr)&nbsp;<br />{&nbsp;int&nbsp;a;&nbsp;<br />a&nbsp;=&nbsp;*ptr;&nbsp;<br />return&nbsp;a&nbsp;*&nbsp;a;&nbsp;<br />}&nbsp;<br /><br />看看上面的描述是否和你出现的问题相匹配。<br />
您需要登录后才可以回帖 登录 | 注册

本版积分规则

46

主题

137

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部