当前位置:首页 > 单片机 > 单片机
[导读]  目前我们在学习和开发单片机时广泛采用 c 语言进行编程,当我们开发的单片机项目较小时,或者我们所写的练习程序很小时,我们总是习惯于将所有代码编写在同一个 c 文件下,由于程序代码量较少,通常为几十行或者

  目前我们在学习和开发单片机时广泛采用 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 文件都应该包含自己的头文件。
  ? 防止头文件被重复包含
  避免一个头文件被重复包含,通常使用条件编译命令#ifndef--#endif,如下示例:
示例 1:

#ifndefTIME_H#defineTIME_H……#endif


示例 2:

#ifndefLED_H#defineLED_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 文件H 头文件描述main.c无Main 文件可以没有对应的头文件timer0.ctimer0.h定时器 0 定时 50ms 中断led.cled.hLed 闪烁实现uart.cuart.h串口通信配置实现digitron.cdigitron.h数码管显示

  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工程到目录 Project 下。

( 2) 选择目标器件,点击“ OK”确认。
( 3) 出现是否添加启动文件到工程中对话框,选择否。
( 4) 目标选项设置, 点击 target option 工具进入选项配置界面。
( 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 文件下,并分别命名为 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 头文件。其程序代码如下:

#include#include"led.h"#include"timer0.h"voidLight_LED(void){staticunsignedcharTickFlag=0;if(TimeCounter==0)//判断500ms定时是否到{TickFlag=1;TimeCounter=10;}if(TickFlag==1)//每间隔500msP1口取反{P1=~P1;TickFlag=0;}}


这个文件中,仅有 Light_LED()函数提供给外部使用,故在 led.h 仅声明该函数即可,声明时要使用关键字 extern 表明该函数可供外部模块使用, led.h 头文件内容如下:

#ifndefLED_H#defineLED_HexternvoidLight_LED(void);#endif


3.2定时器0中断文件
定时器 0 文件 timer0.c 代码如下:

#include#include"timer0.h"unsignedcharTimeCounter=10;voidTimer0Config(void){TMOD|=0x01;//定时器0工作在方式2,即16位计数器TH0=0x3C;TL0=0xB0;//定时器0重赋初值ET0=1;//使能定时器0中断TR0=1;//开启定时器0}voidtimer0(void)interrupt1//定时器0中断函数{TH0=0x3C;TL0=0xB0;//定时器0重赋初值if(TimeCounter!=0){TimeCounter--;}}


其对应的头文要向 led.c 文件提供 TimeCounter 变量,向 main.c 提 Timer0Config 函数,因此要在头文件中进行声明,具体内容如下:

#ifndefTIMR0_H#defineTIMR0_HexternunsignedcharTimeCounter;externvoidTimer0Config(void);#endif

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭