1、2023 年1 月Jan2023DigitalTechnology&Application第 41 卷第 1 期Vol.41No.1数字技术与应用190中图分类号:TP368.2文献标识码:A 文章编号:1007-9416(2023)01-0190-03DOI:10.19695/12-1369.2023.01.58模块化设计在单片机编程中的应用贵州电子信息职业技术学院张定祥模块化编程在嵌入式学习中是比较常用的方法。本文以单片机控制温度传感器为例,介绍模块化设计在单片机学习中的应用,阐述了模块化设计的概念、发展历程以及模块化设计在单片机学习中的编写方法,为将来学习开发嵌入式项目打下良好的基础。学
2、习单片机的同学都会遇到一个疑问。为什么我在课堂上学习单片机之后,却不能做一个复杂的项目?这是因为在设计较复杂的程序时,一般采用自顶向下的方法,将问题划分为几个部分,各个部分再进行细化,直到分解为较好解决问题为止。这就是模块化设计,其基本思想是自顶向下、逐步分解、分而治之,即将一个较大的程序按照功能分割成一些小模块,各模块相对独立、功能单一、结构清晰、接口简单。模块化设计,就是程序的编写不是一开始就逐条录入计算机语句和指令,而是首先用主程序、子程序、子过程等框架把软件的主要结构和流程描述出来,并定义和调试好各个框架之间的输入、输出链接关系逐步求精的结果,得到一系列以功能块为单位的算法描述。以功能
3、块为单位进行程序设计,实现其求解算法的方法称为模块化。1 模块化设计的发展历史模块化程序设计与结构化程序设计和面向对象程序设计密切相关,它们的全部目标都是通过分解成较小的部分来促进大型软件程序和系统的构建,并且都起源于1960 年代。1968 年 7 月在信息和系统研究所由拉里康斯坦丁组织的全国模块化编程研讨会上提出“模块化编程”。1980 年代开始普及模块化编程。最初的 Pascal 语言不包含模块,但后来的版本,尤其是 UCSD Pascal 和Turbo Pascal,就像 Pascal 一样以“单元”的形式包含了它们。1990 年代,由于 C+和 Java 的流行,模块化编程被面向对象
4、的编程所遮盖,并且常常与之混淆。例如,C 语言家族在 C+中支持对象和类和 Objective-C,仅支持 30 年或更长时间的模块。Java(1995)支持包形式的模块,尽管代码组织的主要单位是类。模块化编程现已普及,并且几乎可以使用 1990 年代以来开发的所有主要语言。2 模块化编程模块化编程是指将大型、笨拙的编程任务分解为单独的、更小更易于管理的子任务或模块的过程。然后像构建块一样拼凑单个模块以创建更大的应用程序。在传统方法编程方式中,所有的函数均放在主函数(main.c)里,若使用的模块比较多,则一个文件内会出现很多的代码,不利于代码的组织和管理,而且很影响编程者的思路。而模块化编程
5、方式中,把各个模块的代码放在不同的.c 文件里,在.h 文件里提供外部可调用函数声明,其他.c 文件想使用其中的代码时,只需要#include“xxx.h”文件即可。模块化编程强调将程序的功能分为独立的,可互换的模块,这使得模块化设计的系统比传统的整体式设计具有更高的可重用性,因为所有模块都可以在其他项目中重复使用。模块化编程在嵌入式中是必须要掌握的技能。3 单片机编程中的模块化设计模块化编程在编程当中十分重要,因为模块化编程的代码可以重复使用,可以减轻编程工作者的工作量,在单片机的编程设计中尤为重要。这里以 AT89C51 单片机,在编程软件 Keil 环境下实施一个工程,来说明模块化编程具
6、体操作的方法和步骤。例子要实现的功能:采用液晶显示温度传感器 DS18B20 提取的温度值,并通过串口将温度值发送出去。(1)在同一文件夹下新建一个 main.c 文件(或主文件或运行文件)和 xxx.c 文件(或功能文件)和 xxx.h 文件(头文件),其中 xxx.c 文件(或功能文件)和收稿日期:2022-07-08作者简介:张定祥(1978),男,贵州黄平人,本科,副教授,研究方向:单片机应用技术、EDA 技术。2023 年第 1 期191张定祥:模块化设计在单片机编程中的应用xxx.h 文件(头文件)的文件名“xxx”要有意义,最好可以体现该文件的功能。如图 1 所示。(2)编写 x
7、xx.c 文件(或功能文件)内容(如图 2所示):1)包含 xxx.h 文件(或头文件);2)声明变量或定义变量;3)编写功能函数。注意事项:模块内不想被外部引用的函数和全局变量需在“.c”文件头冠以 static 关键字声明。函数的声明有无 extern都行,变量的声明必须加上 extern,否则编译器无法识别声明1。(3)编写xxx.h文件(或头文件)内容(如图3所示):1)#ifndef xxx /*表示如果没有定义 xxx,则执行后面的语句,如果已经定义则不执行。*/#ifndef _DELAY_H_ 2)#define xxx /表示如果没有定义 xxx.h,这里就定义一个 xxx.
8、h。#define _ DELAY_H_ 3)#endif /表示条件命令的结束。注意事项:函数默认是 extern 属性,也就是我们声明函数的时图 1 代码(code)文件夹下文件Fig.1 Files in the code folder图 2 延时功能模块的 C 文件内容Fig.2 C file content of delay function module图 3 延时头文件Fig.3 Delayed header file2021/1/9 12:132021/1/9 12:132021/1/15 11:292021/1/15 9:512021/1/15 9:512021/1/9 12
9、:132021/1/13 11:112022/7/5 17:152021/1/15 22:092021/1/7 16:15delaydelayDS18B20DS18B20globallcd1602lcd1602mainuartuartC文件H文件C文件H文件H文件C文件H文件C文件C文件H文件+液晶显示+串口发送名称DS18B20测温+液晶显示+串口发送 code修改日期类型大小1 KB1 KB4 KB1 KB1 KB2 KB1 KB2 KB2 KB1 KB延时模块主函数温度传感器模块液晶显示模块串口通信模块#includeglobal.h#include delay.h/可预设ms值延时vo
10、id DelayMs(uint16 ms)uint8 i;while(ms-)for(i=115;i0;i-);/I2C专用延时void Delay8us(void)_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();123456789101112131415161718变量声明功能函数delay.c包含头文件ProjectProject:Lcd_Ds18b20Target 1Source Group 1delay.hglobal.hintrins.hreg51.hlcd1602.cuart.cmain.cDS1882
11、0.cdelay.hDS18820.hglobal.hintrins.hreg51.hglobal.hdelay.huart.hDS18#ifndef _DELAY_H_#define _DELAY_H_extern void DelayMs(uint16 ms);/可预设 Ms 值延时extern void Delay8us(void);/I2C 专用延时#endif1234567global.hDS18B20.hdelay.hlcd1602.huart.huart.cdel数字技术与应用 第 41 卷192候前面的 extern 可有可无。“.h”文件中不可以定义变量,在“.h”中只能声明
12、,不能定义。声明变量不会占用内存,定义变量才会2。(4)编写 main.c 文件(或主文件或运行文件)内容(如图 4 所示):1)包含功能模块 xxx.h 文件(或头文件):#include global.h /包含单片机头文件或定义变量#include delay.h /延时头文件#include lcd1602.h /液晶显示头文件#include DS18B20.h /温度传感器头文件#include uart.h /串口通信头文件2)主函数(如图 5 所示):void main()Init_Lcd();/液晶显示初始化,来自 lcd1602.h 头文件UartInit();/串口通信初
13、始化,来自 uart.h 头文件DelayMs(200);/来自 delay.h 头文件while(1)图 4 函数包含文件Fig.4 Main function contains files图 5 读取温度传感器 DS18B20 液晶显示并串口发送的仿真结果Fig.5 Reading the simulation results of temperature sensor DS18B20 LCD display and serial port transmission下转第216页#include global.h#include delay.h#include lcd1602.h#incl
14、ude DS18B20.h#include uart.huint8 code str1=DS18B20Measure:;uint8 data str2=Temp:0000.00C;/uint8 data array11=”;uint8 data array11-温度:0000.0;uint16 tvalue;/温度值uint8 tflag;/温度正负标志void string_copy(uint8*value1,uint8*value2,uint8 width)uint8 i;For(i=5;i=width;i+)温度传感器模块液晶显示模块global.hDS18B20.hdelay.hlcd
15、1602.huart.huart.c12345678910111213141516171819ProjectProject:Lcd_Ds18b20Target 1Source Group 1delay.hglobal.hintrins.hreg51.hlcd1602.cuart.cmain.cDS18820.cdelay.hDS18820.hglobal.hintrins.hreg51.h串口通信模块delay.c数字技术与应用 第 41 卷216的工作状态,通过监测终端记录被测设备的状态信息、异常日志及报警信息,捕获设备异常崩溃的状态信息。(3)网络攻击测试:通过测试平台发送各种 Dos 攻
16、击报文、通信业务的重放包,或大量发送精心构造的畸形网络包,检测被测设备的资源占用和对通信业务的影响情况。此外,通过测试终端 2 直连设备,对被测设备进行静态测试。重点是通过串口进行操作系统的安全配置测试,包括安全登录、文件系统检查、安全运行策略等。3.2 测试结果分析通过上述安全性测试,发现该设备存在多个冗余端口和应用服务,操作系统和应用程序还存在严重安全漏洞。通过协议模糊测试,发现设备多处协议处理存在内存溢出问题,可导致系统崩溃;同时,设备通信协议字段检查不严格,Dos 攻击和畸形包均可引起设备资源耗尽,甚至重启。操作系统也存在弱口令登录、安全运行策略未配置等安全隐患。以上测试结果说明综合采用多种安全性测试方法有效。4 结论开展对嵌入式通信设备的安全测试可以评估设备的安全风险,提升设备的安全能力,也能为制定适当、有效的设备安全防护策略提供参考,从而保障嵌入式通信设备的安全运行。本文从嵌入式通信设备的安全脆弱性分析出发,研究了传统安全测试手段的局限性,提出了嵌入式通信设备的安全性测试方法并在设备上进行了测试实践,为提升嵌入式通信设备的安全防护能力提供了技术支撑和设计依据。引用1熊婧,黄