background image

#include“lcd_device.h // 包 含 液 晶 驱 动 程 序 头 文 件 , 之 后 就 可 以 在 该 .c 文 件 中 调
用//lcd_device.h 中的全局函数,使用液晶驱动程序里的全局//变量(如果有的话)。

//调用向 LCD 写入字符函数
wr_lcd (0x01,0x30);

//对全局变量赋值
value=0xff;

(2  

) 某模块提供给其它模块调用的外部函数及数据需在.h 中文件中冠以 extern 关键字

声明;
这句话在上面的例子中已经有体现,即某模块提供给其它模块调用的外部函数和全局变
量需在.h 中文件中冠以 extern 关键字声明,下面重点说一下全局变量的使用。使用模块化
编程的一个难点(相对于新手)就是全局变量的设定,初学者往往很难想通模块与模块
公用的变量是如何实现的,常规的做法就是本句提到的,在.h 文件中外部数据冠以 extern
关键字声明。比如上例的变量 value 就是一个全局变量,若是某个模块也使用这个变量,
则和使用外部函数一样,只需在使用的模块.c 文件中包含#include“lcd_device.h”即可。
另一种处理模块间全局变量的方法来自于嵌入式操作系统 uCOS-II,这个操作系统处理全
局变量的方法比较特殊,也比较难以理解,但学会之后妙用无穷,这个方法只需用在头
文件中定义一次。方法为:
在定义所有全局变量(uCOS-II 将所有全局变量定义在一个.h 文件内)的.h 头文件中:
#ifdef xxx_GLOBALS
#define xxx_EXT
#else
#define xxx_EXT extern
#endif
.H 文件中每个全局变量都加上了 xxx_EXT 的前缀。xxx 代表模块的名字。
该模块的.C 文件中有以下定义:
#define xxx_GLOBALS
#include "includes.h"
当编译器处理.C 文件时,它强制 xxx_EXT(在相应.H 文件中可以找到)为空,(因为
xxx_GLOBALS 已经定义)。所以编译器给每个全局变量分配内存空间,而当编译器处理
其他.C 文件时,xxx_GLOBAL 没有定义,xxx_EXT 被定义为 extern,这样用户就可以调
用外部全局变量。为了说明这个概念,可以参见 uC/OS_II.H,其中包括以下定义:
#ifdef OS_GLOBALS
#define OS_EXT
#else
#define OS_EXT extern
#endif
OS_EXT INT32U OSIdleCtr;
OS_EXT INT32U OSIdleCtrRun;
OS_EXT INT32U OSIdleCtrMax;
同时,uCOS_II.H 有中以下定义: