单片机模块化编程方法

相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

{ TMOD |= 0x01; TH0 = 0x3C; TL0 = 0xB0; ET0 = 1; TR0 = 1; } void timer0(void) interrupt 1 //定时器 0 中断函数 { TH0 = 0x3C; TL0 = 0xB0; //定时器 0 重赋初值 if (TimeCounter != 0) { TimeCounter--; } } 其对应的头文要向 led.c 文件提供 TimeCounter 变量,向 main.c 提 Timer0Config 函数, 因此要在头文件中进行声明,具体内容如下: #ifndef TIMR0_H #define TIMR0_H extern unsigned char TimeCounter; extern void Timer0Config(void); #endif 3.3 串口通信文件 串口配置及中断服务程序 uart.c 文件,该文件的代码如下: #include <reg52.h> #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; //定时器 0 工作在方式 2,即 16 位计数器 //定时器 0 重赋初值 //使能定时器 0 中断 //开启定时器 0
(7)选中 Listing 选项,点击“Select Folder for Listings…”选择工程目录下的 Listing 文件 夹。
(8)最后点击“OK”保存各选项的设置,至此完成 Target Option 的配置。 (9) 新建 5 个文件, 以 c 为后缀名保存到工程目录的 Source 文件下, 并分别命名为 main.c、
3. 程序代码编写
3.1 LED 闪烁文件 首先编写 led.c 文件代码,主要内容就是 LED 闪烁实现的函数,由于使用到 timer0.c 中 TimeCounter 变量,故需要包含 timer0.h 头文件。其程序代码如下: #include <reg52.h> #include "led.h" #include "timer0.h" void Light_LED(void) { static unsigned char TickFlag = 0; if (TimeCounter == 0) //判断 500ms 定时是否到 { TickFlag = 1; TimeCounter = 10; } if (TickFlag == 1) { P1 = ~P1; TickFlag = 0; } } 这个文件中,仅有 Light_LED()函数提供给外部使用,故在 led.h 仅声明该函数即可,声 明时要使用关键字 extern 表明该函数可供外部模块使用,led.h 头文件内容如下: #ifndef LED_H #define LED_H extern void Light_LED(void); #endif 3.2 定时器 0 中断文件 定时器 0 文件 timer0.c 代码如下: #include <reg52.h> #include "timer0.h" unsigned char TimeCounter = 10; void Timer0Config(void) // 每间隔 500ms P1 口取反
工程到目录 Project 下。
(2)选择目标器件,点击“OK”确认。
(3)出现是否添加启动文件到工程中对话框,选择否。
(4)目标选项设置,点击 target option 工具进入选项配置界面。
(5)选中 Target 项,根据实际情况设置晶振频率。本例子频率为 11.0592MHz。
(6)选中 output 选项,点击“Select Folder for Objects…”选择工程目录下的 Output 文件 夹,将“Create HEX File”勾选中。
led.c、uart.c、timer0.c 和 digitron.c。右击“Source Group1”选择“Add Existing Flies to Group ‘Source Group1’”,将以上新建的 5 个文件添加到工程中。
(10)至此,就完成整个 keil 工程的创建。
(11) 工程 test 目录文件结构
ES =Fra Baidu bibliotek1; TR1 = 1; }
//使能串口中断 //开启定时器 1
void InterruptUart(void) interrupt 4 //串口中断服务函数 { if (RI == 1) { RI = 0; tem = SBUF; } } uart.h 头文件向 mian.c 提供变量 tem 和函数 UartConfig(),故要进行声明,内容如下: #ifndef UART_H #define UART_H extern void UartConfig(void); extern unsigned char tem; #endif 3.4 数码管显示文件 数码管显示模块文件 digitron.c 代码如下: #include <reg52.h> #include "digitron.h" unsigned char code table[16] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8, 0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; void DigiShow(unsigned char num) { P2 = 0xFE; //打开第一个数码管的位码 P0 = table[num]; //将串口发送过来的数字送到数码上显示 } 文件 main.c 调用该文件的 DigiShow()函数,因此 digitron.h 头文件要声明这个函数, 其头文件内容如下: #ifndef DIGITRON_H #define DIGITRON_H extern void DigiShow(unsigned char num);


避免一个头文件被重复包含,通常使用条件编译命令#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 单片机,在编程软件 keil 环境下实施一个工程,来说明模块化编程 具体操作的方法和步骤。例子要实现的功能:和 P1 相连的 8 个 LED 灯每 500ms 亮灭交替 闪烁, 通过串口将数字 0-9 发送给单片机并显示在一个数码管上。 LED 闪烁的时间使用定时 器 0 中断方式来控制,T0 每 50ms 溢出产生中断,定义一个计数器,每次 T0 中断就计数一 次,累计计数 10 次,那么时长为 500ms ,作为 LED 闪烁时间间隔。单片机的时钟为 11.0592MHz。那么使用模块化编程的方法,整个项目将会有如下表中的文件。 表 1 工程文件清单 C 文件 main.c timer0.c led.c uart.c digitron.c 2.1 创建工程步骤 2.1.1 新建工程文件目录 新建工程文件目录(如 test) ,在工程目录下创建 Project、Source、Output、Listing 和 Readme 这 5 个文件夹,并在文件夹 Readme 下创建 Readme.txt 文件。这样做的目的是为 了增强工程文件的可读性及结构化,便于维护和管理。 Project 存放工程文件 Source 存放用户编写的 c 文件及 h 头文件 Output 存放各种输出文件,如 hex 文件 Listing 存放编译过程中产生的各种中间文件 Readme 存放工程项目的说明文件 2.1.2 创建 keil 工程 (1)启动软件 Keil μVision,点击工具栏上的 Project,选择 NewμVision Project,新建 test H 头文件 无 timer0.h led.h uart.h digitron.h 描述 Main 文件可以没有对应的头文件 定时器 0 定时 50ms 中断 Led 闪烁实现 串口通信配置实现 数码管显示
单片机模块化编程方法
目前我们在学习和开发单片机时广泛采用 c 语言进行编程, 当我们开发的单片机项目较 小时, 或者我们所写的练习程序很小时, 我们总是习惯于将所有代码编写在同一个 c 文件下, 由于程序代码量较少,通常为几十行或者上百行,此时这种操作是可行方便的,也没有什么 问题。但如果要开发的项目较大,代码量上千行或者上万行甚至更大,如果你还继续将所有 代码全部编写在仅有的一个 c 文件下,这种方式的弊病会凸显出来,它会给代码调试、更改 及后期维护都会带来极大的不便。 试想一下, 当你尝试着从几千几万行代码中定位到某一位 置或者去寻找某一错误点,上下拉动巨长的滚动条慢慢地、一点点地浏览整个 c 文件,是件 多么令人眼花缭乱,头昏脑胀的事。模块化编程可解决这个问题,我们只要根据实际需要使 用模块化编程的思维将具有不同功能的程序封装在不同模块中, 将各个不同模块存放在不同 的 c 文件中。模块化编程后的程序不但使整体的程序功能结构清晰明了,同时也提高程序代 码的利用率, 有些模块代码我们可以直接进行移植或者经简单修改就可另作他用, 好比封装 好的函数。 那么什么是模块化呢?首先我们来简单来聊聊模块概念, 我们可能听说过电源模块, 通 信模块,这些是硬件模块,它们都提供一些接口,譬如电源模块会有输出额定电压电流的接 口,通信模块可能提供了 RS232、USB 等接口。那么对软件来说模块是怎样的呢?软件里 的模块跟硬件模块类似,抽象地说就像一个黑盒子,盒子内部细节我们可以不予理会,我们 只关心盒子给我们提供什么东西,即提供了什么接口,利用这些接口我们能实现什么功能。 我们把相对独立, 具有独立功能用代码编写在一个 c 文件下, 把需要对外的函数或变量进行 声明供外部使用,把不需要的细节尽可能对外部屏蔽起来,这就是软件模块化编程的思维。 这样不同的模块占用不同 c 文件,一个个 c 文件将整个项目串接起来实现所有的功能。
1. 模块化编程的原则:
模块化编程通常要遵循以下几个原则: 每一个 c 文件对应一个同名的 h 头文件 一个 h 文件伴随相应 c 文件存在,头文件是为了声明对外公开的接口。如果一个 c 文件 不需要对外公布任何接口,则其就不应当存在,除非它是程序的入口,如 main 函数所在 的文件,同时 main 函数所在文件可以没有对应的头文件。如有一个 led.c,那应该同时 制作一个 led.h 头文件。 头文件中适合放置接口的声明,不适合放置实现 头文件是模块的对外的接口,供外部程序调用。头文件中应放置对外部的声明,如对外 提供的函数声明、宏定义、变量类型声明等。 函数的实现、变量的赋值、语句的操作 等决不能放在头文件中。因为头文件的功能是向外提供接口,譬如函数,变量,具体如 何实现是在 c 文件中进行,头文件仅是进行了描述声明。 任意一个 c 文件只要使用了其他 c 文件提供的接口, 都要同时包含其对应的头文件, 每 个 c 文件应该头文件自包含 任意一个 c 文件只要使用了其他 c 文件提供的接口,都要将其对应的头文件包含到该 c 文件中,没有使用到其他 c 文件的接口就不应该将其匹配的头文件包含,并且每个 c 文 件都应该包含自己的头文件。 防止头文件被重复包含
相关文档
最新文档