一、在工程文件夹下创建一个新的文件夹,命名为"ModulesCodesFiles",译为"模块化代码文件",用于存放所有模块化代码文件。
二、在"ModulesCodesFiles"文件夹下为每个模块创建一个新的文件夹,命名为模块的名称,例如"Main"、"KEY"或"LED"。
1、在每个模块的文件夹下创建两个文件,主函数的模块除外,KEY模块可创建一个.c源文件(例如:KEY.c)和一个.h头文件(例如:KEY.h),LED模块可创建一个.c 源文件(例如:LED.c)和一个.h头文件(例如:LED.h)。
(1)、.c文件:实现函数功能、定义变量 (允许赋初值)、定义I/0口、定义宏等
(2)、.h文件:声明函数、声明变量 (不允许赋初值)、声明常量、声明I/0口、声明宏等。
2、例如:在Main模块的Main.c文件中,可以编写以下代码:
c
#include <reg52.h> //51单片机头文件
#include "LED.h" //包含LED模块的头文件
#include "KEY.h" //包含KEY模块的头文件
void main(void)
{
LED_Init(); //初始化LED模块和LED控制引脚(P2.0)为输出模式,初始为关闭状态(低电平),LED状态变量默认为LED_OFF(0)状态。
KEY_Init(); //初始化KEY输入引脚为输入模式,初始为释放状态(高电平),KEY状态变量默认为KEY_RELEASED(0)状态。
while(1)
{ //循环检测按键状态
if (KEY_Scan() == KEY_PRESSED)
{ //按键被按下
LED_Control(LED_ON); //打开LED
}
else
{ //按键未按下
LED_Control(LED_OFF); //关闭LED
}
}
}
3、不用在Main模块创建Main.h文件,直接在Main模块的Main.c文件完成。
4、例如:在KEY模块的KEY.c文件中,可以编写以下代码:
c
#include "KEY.h"
void KEY_Init(void)
{
//初始化KEY输入引脚为输入模式(默认为高电平)
KEY_PIN = KEY_RELEASED; //将KEY输入引脚初始化为释放状态(高电平),KEY状态变量默认为KEY_RELEASED(0)状态。
}
void KEY_Scan(void)
{
//扫描按键状态
if (KEY_PIN == KEY_RELEASED)
{
//按键未按下
key_state = KEY_RELEASED; //保持当前按键状态为释放状态
}
else
{
//按键被按下
key_state = KEY_PRESSED; //反转按键状态为按下状态
}
}
5、例如:在KEY模块的KEY.h文件中,可以编写以下代码:
c
#ifndef KEY_H
#define KEY_H
//IO口定义
#define KEY_PIN P3_0 //按键输入引脚
//变量定义
unsigned char key_state = KEY_RELEASED; //按键状态变量(默认为释放状态)
//常量定义
#define KEY_PRESSED 1 //按键按下状态常量(1表示按下)
#define KEY_RELEASED 0 //按键释放状态常量(0表示释放)
//宏定义
#define Detection_Button() do { if (KEY_PIN == KEY_PRESSED) {Reverse_Key_Status();} } while(0)
#define Reverse_Key_Status() do { key_state = 1 - key_state; } while(0)
//KEY初始化函数
void KEY_Init(void);
//KEY扫描函数,返回按键状态(按下为1,释放为0)。
int KEY_Scan(void);
#endif
6、例如:在LED模块的LED.c文件中,可以编写以下代码:
c
#include "LED.h"
void LED_Init(void)
{
//初始化LED控制引脚为输出模式
LED_PIN = LED_OFF; //将LED控制引脚初始化为关闭LED状态(低电平),LED状态变量默认为LED_OFF(0)状态。
}
void LED_Control(unsigned char state)
{
if (state == LED_ON)
{
OPEN_LED(); //打开LED
}
else
{
CLOSE_LED(); //关闭LED
}
}
7、例如:在LED模块的LED.h文件中,可以编写以下代码:
c
#ifndef LED_H
#define LED_H
//IO口定义
#define LED_PIN P2_0 //LED控制引脚
//变量定义
unsigned char led_state = 0; //LED状态变量
//常量定义
#define LED_ON 1 //LED打开状态常量
#define LED_OFF 0 //LED关闭状态常量
//宏定义
#define OPEN_LED() do { LED_PIN = LED_ON; } while(0)
#define CLOSE_LED() do { LED_PIN = LED_OFF; } while(0)
//LED初始化函数
void LED_Init(void);
//LED控制函数
void LED_Control(unsigned char state);
#endif
三、如何编写构建脚本(例如:MakeFile)来指定编译和链接的规则
1、在工程文件夹下创建一个名为"MakeFile"的文件,该文件是构建脚本的入口。
2、在MakeFile文件中,定义需要编译的源文件和目标文件,以及编译规则和选项。
c
1 # MakeFile
2 # 定义目标文件名
3 TARGET = Name_Program
4 # 定义需要编译的源文件和头文件
5 SRC = Main.c ModulesCodesFiles/KEY/KEY.c ModulesCodesFiles/LED/LED.c
6 INC = ModulesCodesFiles/KEY/KEY.h ModulesCodesFiles/LED/LED.h
7 # 定义编译规则和选项
8 CC = gcc
9 CFLAGS = -Wall -I.
10 # 定义目标文件的编译规则
11 $(TARGET): $(SRC) $(INC)
12 $(CC) $(CFLAGS) $(SRC) -o $(TARGET)
13 # 定义清理规则,用于删除生成的目标文件和其他临时文件
14 clean:rm -f $(TARGET)
3、在MakeFile文件中,使用规则来指定如何编译源文件和链接目标文件。例如:在MakeFile文件中,可以使用以下规则来指定如何编译源文件。
c
1 $(TARGET): $(SRC) $(INC)
2 $(CC) $(CFLAGS) $(SRC) -o $(TARGET)
解释以上:这个规则表示将所有的源文件(包括Main.c、ModulesCodesFiles/KEY/KEY.c和ModulesCodesFiles/LED/LED.c)编译并链接成一个名为"Name_Program"的可执行文件。
4、在Makefile文件中,可以使用其他规则来定义其他构建任务,例如"clean"任务,用于删除生成的目标文件和其他临时文件。
5、最后,在命令行中运行"make"命令来执行MakeFile文件中的构建任务。例如,在命令行中输入以下命令来执行构建任务。
c
make