二级考试C技巧:volatile实例技巧讲解
来源:优易学  2010-1-14 11:41:03   【优易学:中国教育考试门户网】   资料下载   IT书店
  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;//6j = 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 7E00R MOV R6,#HIGH xdata_junk
  0002 7F00R MOV R7,#LOW xdata_junk
  ;---- Variable ’p’ assigned to Register ’R6/R7’ ----
  0004 8F82MOV DPL,R7
  0006 8E83MOV DPH,R6
  ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 注意
  0008 E0MOVXA,@DPTR
  0009 F500R MOV t1,A
  000B F500R MOV t2,A
  ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  000D 22RET
  将函数变为:
  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 7E00R MOV R6,#HIGH xdata_junk
  0002 7F00R MOV R7,#LOW xdata_junk
  ;---- Variable ’p’ assigned to Register ’R6/R7’ ----
  0004 8F82MOV DPL,R7
  0006 8E83MOV DPH,R6
  ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  0008 E0MOVXA,@DPTR
  0009 F500R MOV t1,Aa处
  000B E0MOVXA,@DPTR
  000C F500R MOV t2,A
  ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  000E 22RET
  比较结果可以看出来,未用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();

责任编辑:cyth

文章搜索:
 相关文章
热点资讯
资讯快报
热门课程培训