C51中的volatile关键字

C51中的volatile关键字  

2009-08-07 13:12:05|  分类: 51单片机|举报|字号 订阅

这几天写了个程序,说它,是因为在单片调试它的时候,有一个变量的值老是不变的。最典型的语句是:_uKey=P2;。结果_uKey的值还是初定义时的值(0x00),我被它气死了。上网问高手,好在用高手指点用volatile这个关键字。一用真的行了。我不理解这个关键字的含意,上网找了点资料,如下:

内存访问速度远不及CPU处理速度,为提高机器整体性能,在硬件上引入硬件高速缓存Cache,加速对内存的访问。

编译器优化常用的方法有:将内存变量缓存到寄存器;

由于访问寄存器的速度快于访内存,所以编译器一般 
都会作优化以减少访内存。如果变量加上volatile修饰,则编译器就不会对此变量
 
的读写操作进行优化,即不通过寄存器缓冲而直接访内存。

C语言关键字volatile表明某个变量的值可能在外部被改变,因此对这些变量的存取不能缓存到寄存器,每次使用时需要重新存取。

该关键字在多线程环境下经常使用,因为在编写多线程的程序时,同一个变量可能被多个线程修改,而程序通过该变量同步各个线程,

对于C编译器来说,它并不知道这个值会被其他线程修改。自然就把它cache在寄存器里面。记住,编译器是没有线程概念的

volatile 的本意是指:这个值可能会在当前线程外部被改变。

下面有个例子:


volatile易变的” 意思
由于访问寄存器的速度要快过RAM,所以编译器一般都会作减少存取外部RAM的优化。比如:

bit bFlag=0;

int main(void)
{
...
while (1)
{
if (bFlag) dosomething();
}
}

/* 
中断程序*/
void ISR(void)
{
bFlag=1;
}

程序的本意是希望ISR中断产生时,在main当中调用dosomething函数,但是,由于编译器判

断在main函数里面没有修改过bFlag,因此
可能只执行一次对从bFlag到某寄存器的读操作,然后每次if判断都只使用这个寄存器里面
“bFlag副本,导致dosomething永远也不会被调用。如果将将变量加上volatile修饰,
则编译器保证对此变量的读写操作都不会被优化(肯定执行)。此例中bFlag也应该如此说
明。


一般说来,volatile用在如下的几个地方:

1
、中断服务程序中修改的供其它程序检测的变量需要加volatile;

2
、多任务环境下各任务间共享的标志应该加volatile;

3
、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义;

另外,以上这几种情况经常还要同时考虑数据的完整性(相互关联的几个标志读了一半被打断了重写),1中可以通过关中断来实现,2中可以禁止任务调度,3中则只能依靠硬件的良好设计了。

 

 

 

c语言中volatile关键字是什么含义

在C语言中经常会遇到volatile关键字,一直看不懂加了这个和不加会有什么样的区别,哪位大侠能否给点解释!!!!

最佳答案

volatile 影响编译器编译的结果,指出,volatile 变量是随时可能发生变化的,与volatile变量有关的运算,不要进行编译优化,以免出错,(VC++ 在产生release版可执行码时会进行编译优化,加volatile关键字的变量有关的运算,将不进行编译优化。)。

 

例如:

volatile int i=10;

int j = i;

...

int k = i;

 

volatile 告诉编译器i是随时可能发生变化的,每次使用它的时候必须从i的地址中读取,因而编译器生成的可执行码会重新从i的地址读取数据放在k中。

 

而优化做法是,由于编译器发现两次从i读数据的代码之间的代码没有对i进行过操作,它会自动把上次读的数据放在k中。而不是重新从i里面读。这样以来,如果i是一个寄存器变量或者表示一个端口数据就容易出错,所以说volatile可以保证对特殊地址的稳定访问,不会出错。

 

其他回答    共 2 条

flyingduck1 - 童生 一级  2006-8-3 23:21

 

不使用volatile定义的变量,可能因为编译器优化而出现一些问题,具体可以看给出的参考资料,里面有一个例子。

 

建议使用volatile变量的场所:

(1) 并行设备的硬件寄存器

(2) 一个中断服务子程序中会访问到的非自动变量(全局变量)

(3) 多线程应用中被几个任务共享的变量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值