关于Keil C 中全局变量的值出错的问题

2019-04-15 16:13发布

关于Keil C 中全局变量的值出错的问题 在一次偶然的实验中,我发现全局变量使用时,值会出现异常,准确的说应该是:当在中断中使用全局变量的时候,值会出错。当时我用的是C52,我想比较一下T0T2做精确时钟能不能实现,误差有多少。 于是,我写了一个定时器模块,包括一个Timer.c文件和一个Timer.h文件,里面分别写了T0T2的初始化函数和中断函数如下: void Timer2_Init(void);             //T2初始化函数 void Timer2(void);                    //T2中断函数 void Timer0_Init(void);             //T0初始化函数 void Timer0(void);                    //T0中断函数 定义了8个全局变量如下: //定时器T0时钟参数 T0_S            // T0_M          // T0_H           // T0_Cycle     //循环次数   //定时器T2时钟参数 T2_S            // T2_M          // T2_H           // T2_Cycle     //循环次数 分别用来记录T0T2时钟的秒,分,时,和循环次数。 后来Test.C里面写了主函数来调用它们,后来发现总是有一个定时器显示不正常,或者两个显示都不正常,但时钟都有很有规律的在走,我对了电脑上的时钟,差不多是一秒钟跳一回,只不过显示的数字不正常,有时对,有时不对。我仔细考虑了一下,时钟应该是没有问题的,不然不会一秒一秒的跳,肯定是显示的数据出了问题,所以我就来查了查程序,看看变量的值会不会传错。但是找来找去,找不出问题。 我查了查关于全局变量的使用,看到有个帖子说到全局变量会跟中断用的寄存器组发生冲突,也就是全局变量的地址会被KEIL分配到中断用的寄存器组里。 下面是我从网上搜集到的关于全局变量使用的注意点: 1.      全局变量要少用,能不用就不用; 2.      在主程序外面只对全局变量做声明,不做定义; 3.      使用中断时,要加上使用的寄存器组; 4.      裸露的全局变量全部用结构体封装起来; 5.      中断与主程序共享全局变量,用函数(含临界段)封装起来; 6.      使用全局变量出错时,可以给它指定一个地址(注意:不要和当前使用的寄存器组发生冲突) 7.      将大部分全局/静态变量(特别是数组)定义到xdata段中; 8.      有些变量可能会随时改变,例如:在中断中赋值的变量,以及硬件修改的输入/输出寄存器等,在程序中使用这些变量时,最好加上“volatile”关键词,告诉C51编译器: (1)不要优化该变量,例如相连的两个相同的赋值语句,第二个不要优化掉,因其处于不同“时刻”赋值结果可能不一样。 (2)每次取该变量值时要从其实际地址的寄存器取,不要从内存的副本中取,因其值可能随时比改变了。