background image

     while (1){

if (i) dosomething();

}

 

void ISR_2(void)

{

      i=1;

}

程序的本意是希望 ISR_2 中断产生时,在 main 函数中调用 dosomething 函数,但是,

由于编译器判断在 main 函数里面没有修改过 i,因此可能只执行一次对从 i 到某寄存器的

读操作,然后每次 if

判断都只使用这个寄存器里面的 i

副本 ,导致 dosomething 永远也

不会被调用。如果将变量加上 volatile 修饰,则编译器保证对此变量的读写操作都不会被

优化(肯定执行)。此例中 i 也应该如此说明。

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

3>存储器映射的硬件寄存器通常也要加 voliate,因为每次对它的读写都可能有不同

意义。

例如:

假设要对一个设备进行初始化,此设备的某一个寄存器为 0xff800000。

int  *output = (unsigned  int *)0xff800000;//定义一个 IO 端口;

int   init(void)

{

      int i;

      for(i=0;i< 10;i++){

         *output = i;

}

}

经过编译器优化后,编译器认为前面循环半天都是废话,对最后的结果毫无影响,

因为最终只是将 output 这个指针赋值为 9,所以编译器最后给你编译编译的代码结果相当

于:

int  init(void)