一个嵌入式系统通常包括两类(注意是两类,不是两个)模块:
**硬件驱动模块**,一种特定硬件对应一个模块;<br />**软件功能模块**,其模块的划分应满足低偶合、高内聚的要求。
模块化方法
模块即是一个.c 文件和一个.h 文件的结合,头文件(.h)中是对于该模块接口的声明;
- 将一个功能模块的代码单独编写成一个.c文件
- 把该模块的接口函数放在.h文件中
具体实现方法:
- .c文件
- 定义变量
- 定义函数
- .h文件
- 声明全局变量
- 声明接口函数
注意事项:
- keil中,extern及时不声明也不会报错,但不保证其他编译器不报错,最好加上
- .c中只有被其他模块调用的函数才出现在.h文件中,用不到的用static修饰
- .h文件中声明的函数句末加分号“;”
模块应用:包含头文件即可调用
.c文件
#include …
…
//定义变量
unsigned char value;//全局变量
…
//定义函数
//这是本模块第一个函数,起到延时作用,只供本模块的函数调用,所以用到static关键字修饰
/********************延时子程序************************/
static void delay (uint us) //delay time
{}
//这是本模块的第二个函数,要在其他模块中调用
/*********************写字符程序**************************
** 功能:向LCD写入字符
** 参数:dat_comm 为1写入的是数据,为0写入的是指令
content 为写入的数字或指令
******************************************************/
void wr_lcd (uchar dat_comm,uchar content)
{}
……
……
/***************************** END Files***********************************/
.h文件
//声明全局变量
extern unsigned char value;
//声明接口函数
extern void wr_lcd (uchar dat_comm,uchar content); //向LCD写入字符
……
/***************************** END Files***********************************/
注意事项
某模块提供给其它模块调用的外部函数及数据需在.h 中文件中冠以extern 关键字声明;
全局变量的使用:
常规方法:在要使用全局变量的模块中包含定义了全局变量的模块头文件
常规的做法就是本句提到的,在.h文件中外部数据冠以extern关键字声明。比如上例的变量value就是一个全局变量,若是某个模块也使用这个变量,则和使用外部函数一样,只需在使用的模块.c文件中包含#include“lcd_device.h”即可。
将所有全局变量定义在一个头文件中
未理解
模块内的函数和全局变量需在.c 文件开头冠以static 关键字声明
static 对函数和变量做约束(作用范围在本地),传递一些信息(不会被其他函数调用)
作用:
- 函数体内,被声明静态的变量在函数被调用过程维持不变
- 在模块内,函数外,被声明为静态的变量可被模块内的其他函数访问,但不能被模块外的函数访问,是本地的全局变量
- 模块内,被声明为静态的函数只能在模块内被其他函数调用,即,被限制在模块本地范围使用
永远不要在.h 文件中定义变量!
在一个模块的.h文件中定义变量之后,其他模块包含该模块的.h文件,会多次定义该变量,该变量在不同模块对应不同地址元。
/*module1.h*/
int a = 5; /* 在模块1 的.h 文件中定义int a */
/*module1 .c*/
#include "module1.h" /* 在模块1 中包含模块1 的.h 文件 */
/*module2 .c*/
#include "module1.h" /* 在模块2 中包含模块1 的.h 文件 */
/*module3 .c*/
#include "module1.h" /* 在模块3 中包含模块1 的.h 文件 */
以上程序的结果是在模块1、2、3 中都定义了整型变量a,a 在不同的模块中对应不同的地址元,这个世界上从来不需要这样的程序。正确的做法是:
/*module1.h*/
extern int a; /* 在模块1 的.h 文件中声明int a */
/*module1 .c*/
#include "module1.h" /* 在模块1 中包含模块1 的.h 文件 */
int a = 5; /* 在模块1 的.c 文件中定义int a */
/*module2 .c*/
#include "module1.h" /* 在模块2 中包含模块1 的.h 文件 */
/*module3 .c*/
#include "module1.h" /* 在模块3 中包含模块1 的.h 文件 */
这样如果模块1、2、3 操作a 的话,对应的是同一片内存单元。
文章地址
https://mp.weixin.qq.com/s?__biz=MzI5NzM5MjMxNw==&mid=2247485356&idx=1&sn=d2e459b46f05d99b085bc96dae299139&chksm=ecb4867edbc30f6835016e13920c4476ab117a81585ee220e54f720966a85a86cd2e43ecb588&scene=21#wechat_redirect
mp.weixin.qq.com_s___biz=MzI5NzM5MjMxNw==&mid=2247485356&idx=1&sn=d2e459b46f05d99b085bc96dae299139&chksm=ecb4867edbc30f6835016e13920c4476ab117a81585ee220e54f720966a85a86cd2e43ecb588&scene=21.png