volatile是一种类型修饰符,它通知编译器用它声明的类型变量不进行代码优化。因为cpu访问寄存器比访问RAM快,所以编译器在进行代码优化时,如果变量的值已经在寄存器中,而且执行代码过程又没对该变量改变过,那么将会直接取寄存器中的值,而不是RAM中变量的值。
一般情况下,这种优化可以缩短代码执行时间,提高执行效率,但如果此时因系统、硬件或者其他线程使得RAM中变量的值发生改变,那么这个时候,再取寄存器中的值将导致错误执行。显而易见,在对硬件端口进行读操作时,就会出现这种错误。
所以在对硬件端口地址定义时一般都定义为volatile类型,避免代码优化。例如,H8/300H微处理器在对IO定义时如下:
#define P1DDR (*(volatile unsigned char *)0xFEE000) /* P1DDR Address*/
#define P2DDR (*(volatile unsigned char *)0xFEE001) /* P2DDR Address*/