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

关于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)每次取该变量值时要从其实际地址的寄存器取,不要从内存的副本中取,因其值可能随时比改变了。

你可能感兴趣的:(c,timer,优化,编译器)