volatile在程序中的作用!!

赵何祺 2013-03-30 06:13:35
求教volatile在程序中的作用!!
...全文
515 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
jdygrdzh 2013-04-01
  • 打赏
  • 举报
回复
不过还是可能访问了cache,如果被访问的区域没有被禁止cache的话。这个不是volatile和编译器能决定的
lbing7 2013-04-01
  • 打赏
  • 举报
回复
简单的说:这个关键字就是告诉编译器,这个变量不能优化。必须每次访问都真实去访问该变量的物理空间。
schlafenhamster 2013-04-01
  • 打赏
  • 举报
回复
单片机有cache的问题,请参考: http://wenku.baidu.com/view/20f5e079168884868762d6e8.html
schlafenhamster 2013-03-30
  • 打赏
  • 举报
回复
volatile 实例讲解 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();

27,375

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧