单片机模块化编程方法

上传人:mg****85 文档编号:44592808 上传时间:2018-06-14 格式:PDF 页数:10 大小:755.47KB
返回 下载 相关 举报
单片机模块化编程方法_第1页
第1页 / 共10页
单片机模块化编程方法_第2页
第2页 / 共10页
单片机模块化编程方法_第3页
第3页 / 共10页
单片机模块化编程方法_第4页
第4页 / 共10页
单片机模块化编程方法_第5页
第5页 / 共10页
点击查看更多>>
资源描述

《单片机模块化编程方法》由会员分享,可在线阅读,更多相关《单片机模块化编程方法(10页珍藏版)》请在金锄头文库上搜索。

1、单片机模块化编程方法单片机模块化编程方法 目前我们在学习和开发单片机时广泛采用 c 语言进行编程, 当我们开发的单片机项目较 小时, 或者我们所写的练习程序很小时, 我们总是习惯于将所有代码编写在同一个 c 文件下, 由于程序代码量较少,通常为几十行或者上百行,此时这种操作是可行方便的,也没有什么 问题。但如果要开发的项目较大,代码量上千行或者上万行甚至更大,如果你还继续将所有 代码全部编写在仅有的一个 c 文件下,这种方式的弊病会凸显出来,它会给代码调试、更改 及后期维护都会带来极大的不便。 试想一下, 当你尝试着从几千几万行代码中定位到某一位 置或者去寻找某一错误点,上下拉动巨长的滚动条慢

2、慢地、一点点地浏览整个 c 文件,是件 多么令人眼花缭乱,头昏脑胀的事。模块化编程可解决这个问题,我们只要根据实际需要使 用模块化编程的思维将具有不同功能的程序封装在不同模块中, 将各个不同模块存放在不同 的 c 文件中。 模块化编程后的程序不但使整体的程序功能结构清晰明了,同时也提高程序代 码的利用率, 有些模块代码我们可以直接进行移植或者经简单修改就可另作他用, 好比封装 好的函数。 那么什么是模块化呢?首先我们来简单来聊聊模块概念, 我们可能听说过电源模块, 通 信模块,这些是硬件模块,它们都提供一些接口,譬如电源模块会有输出额定电压电流的接 口,通信模块可能提供了 RS232、USB

3、等接口。那么对软件来说模块是怎样的呢?软件里 的模块跟硬件模块类似,抽象地说就像一个黑盒子,盒子内部细节我们可以不予理会,我们 只关心盒子给我们提供什么东西,即提供了什么接口,利用这些接口我们能实现什么功能。 我们把相对独立, 具有独立功能用代码编写在一个 c 文件下, 把需要对外的函数或变量进行 声明供外部使用,把不需要的细节尽可能对外部屏蔽起来,这就是软件模块化编程的思维。 这样不同的模块占用不同 c 文件,一个个 c 文件将整个项目串接起来实现所有的功能。 1. 模块模块化化编程编程的的原则:原则: 模块化编程通常要遵循以下几个原则: 每一个每一个 c 文件对应一个同名的文件对应一个同名

4、的 h 头文件头文件 一个 h 文件伴随相应 c 文件存在,头文件是为了声明对外公开的接口。如果一个 c 文件 不需要对外公布任何接口,则其就不应当存在,除非它是程序的入口,如 main 函数所在 的文件,同时 main 函数所在文件可以没有对应的头文件。如有一个 led.c,那应该同时 制作一个 led.h 头文件。 头文件中适合放置接口的声明,不适合放置实现头文件中适合放置接口的声明,不适合放置实现 头文件是模块的对外的接口,供外部程序调用。头文件中应放置对外部的声明,如对外 提供的函数声明、宏定义、变量类型声明等。 函数的实现、变量的赋值、语句的操作 等决不能放在头文件中。因为头文件的功

5、能是向外提供接口,譬如函数,变量,具体如 何实现是在 c 文件中进行,头文件仅是进行了描述声明。 任意一个任意一个 c 文件只要使用了其他文件只要使用了其他 c 文件提供的接口文件提供的接口, 都都要同时包含其对应的头文件, 每要同时包含其对应的头文件, 每 个个 c 文件应该文件应该头文件头文件自包含自包含 任意一个 c 文件只要使用了其他 c 文件提供的接口,都要将其对应的头文件包含到该 c 文件中,没有使用到其他 c 文件的接口就不应该将其匹配的头文件包含,并且每个 c 文 件都应该包含自己的头文件。 防止头文件被重复包含防止头文件被重复包含 避免一个头文件被重复包含,通常使用条件编译命

6、令#ifndef-#endif,如下示例: 示例 1: #ifndef TIME_H #define TIME_H #endif 示例 2: #ifndef LED_H #define LED_H #endif 其中#define FILENAME_H 为基本格式,FILENAME_H 为头文件名称,但要全部使用 大写形式,使用单下划线后紧跟一个 H 表明是头文件。不要在宏名最前面加上“_“或“_” , 即使用 FILENAME_H 代替_FILENAME_H_,因为一般以“_“和”_“开头的标识符为系统保 留或者标准库使用。 2. 模块化编程实例模块化编程实例 我们使用 AT89C52 单片

7、机,在编程软件 keil 环境下实施一个工程,来说明模块化编程 具体操作的方法和步骤。例子要实现的功能:和 P1 相连的 8 个 LED 灯每 500ms 亮灭交替 闪烁, 通过串口将数字 0-9 发送给单片机并显示在一个数码管上。 LED 闪烁的时间使用定时 器 0 中断方式来控制,T0 每 50ms 溢出产生中断,定义一个计数器,每次 T0 中断就计数一 次,累计计数 10 次,那么时长为 500ms,作为 LED 闪烁时间间隔。单片机的时钟为 11.0592MHz。那么使用模块化编程的方法,整个项目将会有如下表中的文件。 表 1 工程文件清单 C 文件 H 头文件 描述 main.c 无

8、 Main 文件可以没有对应的头文件 timer0.c timer0.h 定时器 0 定时 50ms 中断 led.c led.h Led 闪烁实现 uart.c uart.h 串口通信配置实现 digitron.c digitron.h 数码管显示 2.1 创建工程步骤创建工程步骤 2.1.1 新建工程文件目录新建工程文件目录 新建工程文件目录(如 test) ,在工程目录下创建 Project、Source、Output、Listing 和 Readme 这 5 个文件夹,并在文件夹 Readme 下创建 Readme.txt 文件。这样做的目的是为 了增强工程文件的可读性及结构化,便于维

9、护和管理。 Project 存放工程文件 Source 存放用户编写的 c 文件及 h 头文件 Output 存放各种输出文件,如 hex 文件 Listing 存放编译过程中产生的各种中间文件 Readme 存放工程项目的说明文件 2.1.2 创建创建 keil 工程工程 (1)启动软件 Keil Vision,点击工具栏上的 Project,选择 NewVision Project,新建 test工程到目录 Project 下。 (2)选择目标器件,点击“OK”确认。 (3)出现是否添加启动文件到工程中对话框,选择否。 (4)目标选项设置,点击 target option 工具进入选项配置

10、界面。 (5)选中 Target 项,根据实际情况设置晶振频率。本例子频率为 11.0592MHz。 (6)选中 output 选项,点击“Select Folder for Objects”选择工程目录下的 Output 文件 夹,将“Create HEX File”勾选中。 (7)选中 Listing 选项,点击“Select Folder for Listings”选择工程目录下的 Listing 文件 夹。 (8)最后点击“OK”保存各选项的设置,至此完成 Target Option 的配置。 (9) 新建 5 个文件, 以 c 为后缀名保存到工程目录的 Source 文件下, 并分别

11、命名为 main.c、led.c、uart.c、timer0.c 和 digitron.c。右击“Source Group1”选择“Add Existing Flies to Group Source Group1”,将以上新建的 5 个文件添加到工程中。 (10)至此,就完成整个 keil 工程的创建。 (11) 工程 test 目录文件结构 3. 程序代码编写程序代码编写 3.1 LED 闪烁文件闪烁文件 首先编写 led.c 文件代码,主要内容就是 LED 闪烁实现的函数,由于使用到 timer0.c 中 TimeCounter 变量,故需要包含 timer0.h 头文件。其程序代码如下

12、: #include #include “led.h“ #include “timer0.h“ void Light_LED( (void) ) static unsigned char TickFlag = = 0; ; ifif ( (TimeCounter = 0) ) /判断 500ms 定时是否到 TickFlag = = 1; ; TimeCounter = = 10; ; ifif ( (TickFlag = 1) ) / 每间隔 500ms P1 口取反 P1 = = P1; ; TickFlag = = 0; ; 这个文件中,仅有 Light_LED()函数提供给外部使用,故

13、在 led.h 仅声明该函数即可,声 明时要使用关键字 extern 表明该函数可供外部模块使用,led.h 头文件内容如下: #ifndef LED_H #define LED_H extern void Light_LED( (void);); #endif 3.2 定时器定时器 0 中断文件中断文件 定时器 0 文件 timer0.c 代码如下: #include #include “timer0.h“ unsigned char TimeCounter = = 10; ; void Timer0Config( (void) ) TMOD |=|= 0x01; ; /定时器 0 工作在方

14、式 2,即 16 位计数器 TH0 = = 0x3C; ; TL0 = = 0xB0; ; /定时器 0 重赋初值 ET0 = = 1; ; /使能定时器 0 中断 TR0 = = 1; ; /开启定时器 0 void timer0( (void) ) interrupt 1 /定时器 0 中断函数 TH0 = = 0x3C; ; TL0 = = 0xB0; ; /定时器 0 重赋初值 ifif ( (TimeCounter !=!= 0) ) TimeCounter-; ; 其对应的头文要向 led.c 文件提供 TimeCounter 变量,向 main.c 提 Timer0Config

15、函数, 因此要在头文件中进行声明,具体内容如下: #ifndef TIMR0_H #define TIMR0_H extern unsigned char TimeCounter; ; extern void Timer0Config( (void);); #endif 3.3 3.3 串口通信文件串口通信文件 串口配置及中断服务程序 uart.c 文件,该文件的代码如下: #include #include “uart.h“ unsigned char tem = = 0; ; void UartConfig( (void) ) SCON = = 0x50; ; /串口工作在方式 1,即 10 位收发器模式 PCON = = 0x00; ; /波特率不增倍 TMOD |=|= 0x20; ; /定时器 1 做波特率发生器,工作在方式 2 即 8 位自动重装初值模式 TH1 = = 0xFD; ; /定器 1 赋初值 TL1 = = TH1; ; ES = = 1; ; /使能串口中断 TR1 = = 1; ; /开启定时器 1 void InterruptUart( (void) ) interrupt 4 /串口中断服务函数 ifif ( (RI = 1) ) RI =

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 生活休闲 > 科普知识

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号