正文

volatile 实例讲解2005-06-21 20:10:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/wegang/1974.html

分享到:

volatile的本意是一般有两种说法--1.“暂态的”;2.“易变的”。 这两种说法都有可行。但是究竟volatile是什么意思,现举例说明(以Keil-c与a51为例 例子来自Keil FQA),看完例子后你应该明白volatile的意思了,如果还不明白,那只好 再看一遍了。 例1. void main (void) { volatile int i; int j; i = 1;  //1  不被优化 i=1 i = 2;  //2  不被优化 i=1 i = 3;  //3  不被优化 i=1 j = 1;  //4  被优化 j = 2;  //5  被优化 j = 3;  //6  j = 3 } --------------------------------------------------------------------- 例2. 函数: void func (void) { unsigned char xdata xdata_junk; unsigned char xdata *p = &xdata_junk; unsigned char t1, t2; t1 = *p; t2 = *p; } 编译的汇编为: 0000 7E00    R     MOV     R6,#HIGH xdata_junk 0002 7F00    R     MOV     R7,#LOW xdata_junk ;---- Variable 'p' assigned to Register 'R6/R7' ---- 0004 8F82          MOV     DPL,R7 0006 8E83          MOV     DPH,R6 ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 注意 0008 E0            MOVX    A,@DPTR 0009 F500    R     MOV     t1,A 000B F500    R     MOV     t2,A ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 000D 22            RET      将函数变为: void func (void) { volatile unsigned char xdata xdata_junk; volatile unsigned char xdata *p = &xdata_junk; unsigned char t1, t2; t1 = *p; t2 = *p; } 编译的汇编为: 0000 7E00    R     MOV     R6,#HIGH xdata_junk 0002 7F00    R     MOV     R7,#LOW xdata_junk ;---- Variable 'p' assigned to Register 'R6/R7' ---- 0004 8F82          MOV     DPL,R7 0006 8E83          MOV     DPH,R6 ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 0008 E0            MOVX    A,@DPTR 0009 F500    R     MOV     t1,A        a处 000B E0            MOVX    A,@DPTR 000C F500    R     MOV     t2,A ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 000E 22            RET      比较结果可以看出来,未用volatile关键字时,只从*p所指的地址读一次 如在a处*p的内容有变化,则t2得到的则不是真正*p的内容。 --------------------------------------------------------------------- 例3 volatile unsigned char bdata var;  // use volatile keyword here sbit var_0 = var^0; sbit var_1 = var^1; unsigned char xdata values[10]; void main (void)  {   unsigned char i;   for (i = 0; i < sizeof (values); i++)  {     var = values[i];     if (var_0)  {       var_1 = 1; //a处               values[i] = var;  // without the volatile keyword, the compiler                         // assumes that 'var' is unmodified and does not                         // reload the variable content.     }   } } 在此例中,如在a处到下一句运行前,var如有变化则不会,如var=0xff; 则在 values[i] = var;得到的还是values[i] = 1; --------------------------------------------------------------------- 应用举例: 例1. #define DBYTE ((unsigned char volatile data  *) 0) 说明:此处不用volatile关键字,可能得不到真正的内容。 --------------------------------------------------------------------- 例2. #define TEST_VOLATILE_C //*************************************************************** // verwendete Include Dateien //*************************************************************** #if __C51__ < 600   #error: !! Keil 版本不正确 #endif //*************************************************************** // 函数 void v_IntOccured(void) //*************************************************************** extern void v_IntOccured(void); //*************************************************************** // 变量定义 //*************************************************************** char xdata cvalue1;          //全局xdata char volatile xdata cvalue2; //全局xdata //*************************************************************** // 函数: v_ExtInt0() // 版本: // 参数: // 用途:cvalue1++,cvalue2++ //*************************************************************** void v_ExtInt0(void) interrupt 0 {   cvalue1++;   cvalue2++; } //*************************************************************** // 函数: main() // 版本: // 参数: // 用途:测试volatile //*************************************************************** void main() { char cErg; //1. 使cErg=cvalue1; cErg = cvalue1; //2. 在此处仿真时手动产生中断INT0,使cvalue1++; cvalue2++ if (cvalue1 != cErg)   v_IntOccured(); //3. 使cErg=cvalue2; cErg = cvalue2; //4. 在此处仿真时手动产生中断INT0,使cvalue1++; cvalue2++ if (cvalue2 != cErg)   v_IntOccured();    //5. 完成   while (1); } //*************************************************************** // 函数: v_IntOccured() // 版本: // 参数: // 用途: 死循环 //*************************************************************** void v_IntOccured() {   while(1); } 仿真可以看出,在没有用volatile时,即2处,程序不能进入v_IntOccured(); 但在4处可以进入v_IntOccured();

阅读(17662) | 评论(1)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

loading...
您需要登录后才能评论,请 登录 或者 注册