基于单片机的塑料厂房气体检测系统设计

目 录

摘 要 I
Abstract II
引 言 3
1 系统总体架构 5
1.1 需求分析与方案设计 5
1.2 系统器件选择 5
1.3 系统架构 6
2 系统硬件设计 6
2.1 绘制电路板概述 6
2.2 单片机电路设计 7
2.2.1 STC89C52单片机介绍 7
2.2.2 STC89C52单片机外围电路设计 8
2.3 LCD1602液晶显示电路设计 10
2.3.1 LCD1602液晶显示器介绍 10
2.3.2 LCD1602液晶外围电路设计 11
2.4 传感器与AD转换电路设计 12
2.5 电机电路设计 13
2.6 按键系统 14
2.7 调试电路 15
3 系统软件流程设计 16
3.1 程序架构 16
3.2 LCD显示程序设计 17
3.3 按键控制程序设计 19
4 系统验证 22
4.1 焊接与调试 22
4.2 程序烧录与调试 23
结 论 25
参考文献 26
附录1 元器件清单 27
附录2 源程序清单 28
致 谢 44

摘 要

目前,在社会主义现代化建设中,火灾不断的增多,而在塑料厂房中大部分火灾都是因为生产塑料的机器不断的运转导致机体周围的温度不断升高,超过了可燃气的燃点,或者是生产塑料的机器昌盛的可燃气过多,从而导致了很多不安全因素的发生。
为了对火灾进行预警,避免灾害的发生,本文设计了一款基于单片机的塑料厂房可燃气体检测系统。基于单片机的塑料厂房可燃气体检测系统通过传感器对当前环境的可燃气体浓度值进行实时检测,经过AD转换后送交给单片机进行处理;可以通过外部按键来对系统的判决门限即最高浓度值进行设置;单片机对数据处理后,与设定的最高浓度值进行比较,若是大于该浓度值,则输出信号控制蜂鸣器响、电机转动;整个过程中的探测值、设定值均由LCD液晶来进行显示。
本文首先分析了基于单片机的可燃气体检测系统的设计需求,完成了系统架构设计。在此基础上进行了单片机外围电路设计,液晶显示外部电路设计,MQ传感器与AD转换电路设计,电机外部电路设计,开关电路设计。在完成硬件电路设计的基础上,进行了软件流程设计,包括对LCD液晶显示控制程序,读取AD转换后的数据,按键控制程序。
经过调试与验证,基于单片机的可燃气体检测系统已经实现了初始的应用需求,可以对系统所在环境的浓度值进行判断,并通过按键对浓度值进行调整,在超过门限值的时候,能够实现蜂鸣器响、电机转动等报警功能,有着很强的可靠性与实用性。
关键词: 单片机; LCD;声光报警;可燃气体;

Abstract
At present, with the continuous development of the paint market, the demand for mixing equipment is higher and higher. In order to reduce the cost of coating production, reduce a large number of human and material resources and improve the work efficiency through the design of a new type of coating agitator, an automatic mixing system based on single chip microcomputer is designed in this paper.
The automatic mixing system based on single-chip microcomputer can be controlled by external keys. The internal single-chip microcomputer responds to the external keys and then controls the motor. It can adapt to the needs of mixing materials in different situations, and can carry out positive and negative rotation, speed adjustment, timing mixing and other functions.
This paper first a nalyzes the design requirements of the automatic stirring system based on single chip microcomputer, and completes the system architecture design. The peripheral circuit design of single chip microcomputer, the external circuit design of liquid crystal display and the external circuit design of motor are completed. On the basis of hardware circuit design, the software flow is designed, including LCD display program, motor timing and speed control program, key control program.
The experimental results show that the automatic mixing system based on single-chip microcomputer can adjust the working mode flexibly and realize “one set of equipment, one machine with multiple functions, one step in place”.

Keywords: MCU;LCD;Sound and light alarm;Combustible Gas ;

引 言

目前,在社会主义现代化建设中,火灾可以说是一个重大的隐患,尤其是在封闭的工业,如若发生火灾需要处理更是难上加难,所以我们需要早发现早预防,我是在一个塑料厂房参加的实习工作,塑料制品本身就属于可燃易燃难熄灭的种类,而且在一个大的密闭厂房内部,机器融化塑料需要极高的温度,所以必须控制好厂房内部可燃气体的浓度。
姚美玲等设计了基于NB-LOT的智能火灾预警系统,主要包括以下设计,首先是进行网络上线,报警器自动上电并与NB-LOT连接;第二步是在出现情况的时候,实现火灾上报,指示灯闪烁,蜂鸣器响;第三个部分是关于故障上报,当报警器有问题的时候可以通过上报。该系统可以避免布局布线的复杂度,可以降低成本,但是其维护比较困难。
安徽师范大学的研究人员设计了基于电磁导航的巡查机器人。该机器人利用电磁导航进行定位,此外该机器人还配备有红外报警,可燃气体检测,火焰报警,OLED等,故其可以检测明火、可燃气体、是否有外来人员等,并可以通过无线传输将信息实时送交给使用者。其功能十分强大,机器人可以在设定的区域内不停的巡逻,传感器也很齐全,可以实现互补功能。但是,由于其主要传感器安置在机器人的前端,也就是说无法兼顾侧面及背后的情况,同时机器人的持久巡航能力也值得考虑。
刘广潆设计了基于激光式的可燃气体探测器,主要是结合相关气体对特定波长的光信号有吸收作用,在结合光谱来确定当前环境的浓度。设备持续不断的向环境发射光信号,当环境中有可燃气体的时候,返回的光信号由于被气体吸收,则会强度衰弱,由此可判断当前环境是否有可燃气体。该方法只是在特定的场合即油田区域运用,激光会对人体的眼睛造成损伤。
本次所设计的基于单片机的塑料厂房可燃气体检测系统,主要需要实现以下一些功能。基于单片机的可燃气体检测系统通过传感器对当前环境的可燃气体浓度值进行实时检测,经过AD转换后送交给单片机进行处理;可以通过外部按键来对系统的判决门限即最高浓度值进行设置;单片机对数据处理后,与设定的最高浓度值进行比较,若是大于该浓度值,则输出信号控制蜂鸣器响、电机转动,当低于该值的时候,电机停止转动,蜂鸣器不响;整个过程中的探测值、设定值均由LCD液晶来进行显示。

1 系统总体架构

1.1 需求分析与方案设计
为了防止塑料厂房内火灾的发生,就需要检测厂房内部可燃气体的浓度,本文设计了一款基于单片机的塑料厂房可燃气体检测系统。基于单片机的可燃气体检测系统通过传感器对当前环境的可燃气体浓度值进行实时检测,经过AD转换后送交给单片机进行处理;可以通过外部按键来对系统的判决门限即最高浓度值进行设置;单片机对数据处理后,与设定的最高浓度值进行比较,若是大于该浓度值,则输出信号控制蜂鸣器响、电机转动;整个过程中的探测值、设定值来进行显示。
为了实现上述功能,可以有两种方案:
第一种是利用激光探测器,对光谱的吸收来判断是否有可燃气体。
第二种方案是利用单片机作为处理器,结合外部传感器来对当前环境的可燃气体浓度值进行收集、计算,外部使用者可以通过相关操作来对系统的判决门限进行设置,当浓度值超过浓度值,则输出信号控制蜂鸣器响、电机转动。
依据方案设计的复杂度、智能性、可操作性等原因,我们选择第二种方案,即基于单片机的可燃气体检测系统。
1.2 系统器件选择
结合上文的系统需求分析,首先为了检测,采用MQ-2传感器来对塑料厂房内部可燃气体浓度值进行检测,为了便于单片机处理,利用AD芯片来进行转换,为了接收外部对系统工判决门限的控制与改变,在基于单片机的可燃气体检测系统中使用按键电路来实现。
整个系统的运行都依靠单片机来进行操控,不同的单片机类型功能也不一样,经过仔细考虑和结合实际情况,采用的是8052内核的STC89C52单片机。因为此程序的代码不是十分的繁多,所以为了节约成本没有采用比较复杂成本比较昂贵的STM32或者是MSP430等单片机,而去采用528kb的内存单片机。
显示部分用LCD1602液晶来显示当前的信息,相比于数码管显示, LCD1602显示的字符量更多,弥补信息量比较少,显示内容有限的缺陷,它可以显示文字、数字还可以显示特殊的符号。

1.3 系统架构
图1.1为基于单片机的可燃气体检测系统架构框图,系统以STC89C52单片机作为中央处理器。系统工作频率由外部晶振提供,开关按键可以来对系统内的判决门限进行调整;由MQ-2传感器来对当前环境的气体浓度值进行不断检测,经过AD转换后,数据将会送交给单片机;单片机对该数据进行处理,与外部输入的门限值进行比较,当出现大于门限的情况,则输出相应的信号控制报警系统:蜂鸣器响、电机转动;整个工作过程的结果将会由LCD1602进行显示。
在这里插入图片描述

图1.1 基于单片机的可燃气体检测系统架构

2 系统硬件设计

结合第一章的系统需求分析,我们首先需要结合对基于单片机的可燃气体检测系统中的各个模块的硬件电路完成设计。
2.1 绘制电路板概述
本次对基于单片机的可燃气体检测系统设计中使用的是Altium Designer软件完成电路板的绘制,包含以下一些步骤:
(1)新建空的原理图与PCB图;
(2)依据基于单片机的可燃气体检测系统所需要实现的功能选择器件,绘制原理图;
(3)绘制元器件库,如果现有库文件没有相关器件,我们需要自己进行补充,也可以方便下次设计;
(4)PCB封装;
(5)生成PCB;
(6)进行合理的元器件布局,需要充分考虑走线是否方便、散热等问题;
(7)布线,要充分考虑系统电流大小,过孔,焊盘大小等等;
(8)送去加工,找厂家进行板子的制作

2.2 单片机电路设计
本次设计选用主控制器型号是STC89C52的单片机。它的内部ROM存储器:8K;RAM:256K;定时器:2个(ROM:是程序存放指令代码和一些固定数值,程序运行后不可改动;RAM:用于程序运行中数据的随机存取,掉电后数据消失。)单片机对各种传感器和外设进行控制,对外部输入的数据和信号进行收集计算,并进行相应的操作,是工业生产中的大脑。 我们首先需要完成对单片机外围系统的设计。
2.2.1 STC89C52单片机介绍
STC89C52有 32个I/O口可以连接更多的外设和传感器,8K字节的FLASH存储器可以进行更多的计算缓存,521字节的RAM大大提高的反应速度。STC89C52单片机的烧录也非常简单,通过TX和RX口,采用对应的编译器就可以将程序烧录进去。是一款便宜、简单和高性能的单片机。
在这里插入图片描述

图2.1 STC89C52单片机封装引脚
图2.1为STC89C52单片机封装引脚,完成基于单片机的塑料厂房气体检测系统设计之前首先需要对管脚进行了解。
VCC:供电电压。
GND:接地。
P0、P1、P2、P3:I/O引脚,可以在本次设计中作为输入输出端口,用以接收GPS的位置信息或者向LCD液晶输出信息等。
P3口特殊功能口,具体如表2.1所示:
RXD即可在本系统中用以接收GPS传来的位置信息,TXD即可在本系统中用向短信模块发送位置信息;

表2.1 P3口的第二功能
引 脚
位 置 第二功能
符 号 功 能
P3.0 RXD 串行输入口
P3.1 TXD 串行输出口
P3.2 /INT0 外部中断0
P3.3 /INT1 外部中断1
P3.4 T0 记时器0外部输入
P3.5 T1 记时器1外部输入
P3.6 /WR 外部数据存储器写选通
P3.7 /RD 外部数据存储器读选通
P3口同时为闪烁编程和编程校验接收一些控制信号;
RST:复位输入;
PSEN:外部程序存储器的选通信号;
XTAL1:反向振荡放大器的输入及内部时钟工作电路的输入;
XTAL2:来自反向振荡器的输出。

2.2.2 STC89C52单片机外围电路设计
根据第一章对基于单片机的可燃气体检测系统需求分析,结合单片机所完成的具体工作以及单片机的管脚介绍,最终总结单片机外围电路需要进行几个方面的设计。
(1)单片机供电及晶振部分
为保证单片机正常运作,首先根据芯片数据手册中的管脚定义,完成对单片机的供电设计即对应管脚接电源和地。单片机外部晶振如图2.2:本次设计中,单片机使用外部的11.0592MHz晶振,本次设计18管脚是外部晶振的输入端,让19管脚其接地。
在这里插入图片描述

图2.2 晶振电路

(2)报警电路:
基于单片机的可燃气体检测系统工作时,若检测到的可燃气体浓度值超过我们所设定的门限值,那么意味着此时已经出现火灾或有爆发的危险。此时需要通过报警电路进行报警,而后电机开始转动,向外排放气体降低环境内的可燃气体浓度值。
在这里插入图片描述

图2.3 声光报警电路

报警的时候分为两个部分来提醒使用者,第一个是LED灯亮,第二个是蜂鸣器响(本次设计中使其0.5s一次)。电路图如图2.3所示,将LED和蜂鸣器正极接在VCC,负极并联到三极管的发射极,而三极管的基极连接到单片机的P1.4口。这样,在正常情况下,单片机P1.4口输出高电平,三极管没有导通,二级管不亮,蜂鸣器不响;在单片机判断可燃气体浓度值超过我们所设定的门限值,就由P1.4口输出低电平,从而二极管与蜂鸣器导通,二极管灯亮、蜂鸣器响起。二极管工作的时候电流不能太大,一般是5mA左右,在LED正常导通的时候,其两端的的电压一般是1.7V,为了保护二极管,外接了一个1KΩ电阻。
(3)读取内部存储器
依据芯片的数据手册,单片机的31管脚在接高电平时,单片机使用内部存储器。结合上一节介绍,系统中所使用的STC89C52单片机有内部ROM,因此在本次设计中,将该管脚一直接高电平。
2.3 LCD1602液晶显示电路设计
2.3.1 LCD1602液晶显示器介绍
本着实现人机交互,方便观察气体检测结果的原则,我采用了LCD1602的液晶显示器,LCD1602液晶显示器可以清晰的显示出当前塑料厂房内部某点的气体浓度值以及自己设计的气体的预警值,而且LCD1602的显示质量高。LCD1602液晶显示器作为输出显示器具有体积小、重量轻、低功耗等特点,数字式接口液晶显示器都是数字式的,和单片机系统的接口更加简单可靠,操作更加方便。
如表2.2所示为LCD1602数据手册给出的芯片接口定义。是我在进行电路设计以及后续编程实现数据显示过程中的重要依据。
表2.2 LCD1602芯片接口定义

编号 符号 引脚说明
1 VSS 电源地
2 VDD 电源正极
3 VL 液晶显示偏压信号
4 RS 数据/命令选择端(H/L)
5 R/W 读/写选择端(H/L)
6 E 使能信号
7 D0 Date I/O
8 D1 Date I/O
9 D2 Date I/O
10 D3 Date I/O
11 D4 Date I/O
12 D5 Date I/O
13 D6 Date I/O
14 D7 Date I/O
15 BLA 背光源正极
16 BLK 背光源负极

芯片的32到39管脚即P0口是单片机的8个I/O口,本次基于单片机的塑料厂房气体检测系统设计中,液晶需要显示的可燃气体检测系统检测到的当前气体浓度检测值、设定的告警值(及其单位)等相关数据由这个8个端口送交给LCD液晶显示,由于单片机的P0口没有上拉电阻,是高阻状态,因此外接一个10KΩ的排阻;同时依据液晶显示的数据手册,对液晶显示进行操作还需要涉及三个控制管脚,因此在单片机P2.5,P2.6和P2.7三个端口给出三个控制信号。

2.3.2 LCD1602液晶外围电路设计
液晶需要显示的可燃气体检测系统检测到的当前气体浓度检测值、设定的告警值(及其单位)等相关数据。上面一行显示当前浓度值:“NOW GAS:数值 PPM”,下面一行显示设定的报警门限:“Warning:数值 PPM”。结合对整个可燃气体检测系统检的工作设计,LCD1602液晶显示外围电路设计分为以下几个部分。
(1)液晶供电部分
结合LCD1602液晶显示的数据手册,为了在基于单片机的可燃气体检测系统中使的液晶正常工作,需要完成供电设计。
(2)与单片机之间的通信
依据数据手册,7到14号管脚是其数据口,在基于单片机的可燃气体检测系统中,液晶需要通过这个8个数据口从单片机接收信息再进行显示。
(3)液晶显示的控制
为了保证与单片机的通讯,还有三个控制管脚。依据数据手册, 液晶的6管脚为使能端口,在数据传输的时候,高电平有效,连接单片机的P2.5口;5管脚为读写选择端,将其连接到单片机的P2.6口,接受单片机给出的控制信号;4管脚为数据/命令选择端,连接单片机的P2.7口。
(3) 液晶显示的对比度调节:
依据数据手册,LCD1602液晶的3管脚是调节显示对比度的端口,考虑到工人群体对显示屏亮度比较敏感或者有不同喜好,在电路设计中,系统的使用者可对显示对比度的调节。
最终,图2.4即为基于单片机的可燃气体检测系统中LCD液晶显示电路。
在这里插入图片描述

图2.4 LCD1602液晶显示电路图

2.4 传感器与AD转换电路设计
MQ-2型传感器对天然气、液化石油气等烟雾有很高的灵敏度,尤其对烷类烟雾更为敏感具有良好的抗干扰性,可准确排除有刺激性非可燃性烟雾的干扰信息。
MQ-2型传感器具有良好的重复性和长期的稳定性。初始稳定,响应时间短,长时间工作性能好。需要注意的是:在使用之前必须加热一段时间,否则其输出的电阻和电压不准确。其检测可燃气体与烟雾的范围是100~10000ppm。
MQ-2的4脚输出随烟雾浓度变化的直流信号,被加到比较器U1A的2脚,Rp构成比较器的门槛电压。当烟雾浓度较高输出电压高于门槛电压时,比较器输出低电平(0v),此时LED亮报警;当浓度降低传感器的输出电压低于门槛电压时,比较器翻转输出高电平(Vcc),LED熄灭。调节Rp,可以调节比较器的门槛电压,从而调节报警输出的灵敏度。R1串入传感器的加热回路,可以保护加热丝免受冷上电时的冲击。图2.5为传感器与AD转换电路图
在这里插入图片描述

图2.5 传感器与AD转换电路图

2.5 电机电路设计
可燃气体检测系统中,当单片机判断此时检测到的可燃气体浓度大于了所设定的门限值,表明此时有风险,需要打开风扇电机,排放气体,需要设计一个由单片机控制的电机电路
电机电路如图2.6所示,单片机与电机之间通过一个三极管连接,单片机的P3.6口连接到三极管的基极,电机的正极接电源负极接在发射级,集电极接地。这样,在正常情况即没有任何风险的情况下,由单片机P3.6口始终输出一个高电平,三极管不能导通,电机无法转动;在系统判断有风险的时候,由单片机的P3.6口输出低电平,此时三极管导通,电机开始转动。所以电机电路在本设计中的作用是作为用电的动力源驱动风扇进行运转。
在这里插入图片描述

图 2.6电机电路设计
2.6 按键系统
首先需要设计一个开关K1,用来控制整个可燃气体检测系统,对整个系统进行复位。由于单片机的复位端口RST高电平有效,我们将开关K1一端接高电平一端连接到单片机的复位端口RST,这样在开关按下的时候复位端口将会感知电平发生变化。复位电路如图2.7所示。
在这里插入图片描述

图2.7复位电路
实际工程应用中,不同的环境对气体浓度的指标也会不同,为了保证可燃气体检测系统能够灵活适应各种场景,其内部的告警值也应当能够通过外部认为输入调整,避免误报等情况的出现。
在这里插入图片描述

图2.8 按键控制电路

为了实现外部对气体检测系统运作的控制,我们选择按钮开关来进行控制,为了简化后续程序设计复杂度,每个开关负责一个功能。
按键控制电路如图2.8所示,我们设计了2个开关K2与K3,考虑到同时单片机的I/O口既可以做输出也可以作输入,为了对开关按键进行响应,将K2和K3分别通过一个排阻连接到单片机的P3.4和P3.5口,另一端供地,此时I/O口作为输入,这样在开关按下的时候,对应的单片机端口就为低电平,程序再对端口的电平进行判断及后续执行相应的处理操作,即可完成对开关的判别与响应。气体检测系统中各个开关按键的功能分配如下
K2:告警值加,按下以后设定的告警值加1,若持续按键,则持续增加;
K3:告警值减,按下以后设定的告警值减1,若持续按键,则持续减小;(具体实现在程序设计中作详细介绍)。
2.7 调试电路
在完成可燃气体检测系统的电路设计以及完成后续程序设计之后,需要将程序完成烧录,进行功能的调试,因此需要设计一个调试口,调试口的收发分别接到单片机的P3.0(RXD)和P3.1(TXD),还有一端接地。调试口电路如图2.9所示
在这里插入图片描述

图2.9调试电路
最终,图2.10即为基于单片机的可燃气体检测系统中STC89C52单片机外部电路。
在这里插入图片描述

图2.10 STC89C52单片机外部电路设计

3 系统软件流程设计

结合系统需求分析,在完成了系统电路的设计以后,系统的主要功能还需要通过软件实现,需要进行相关软件流程设计,实现基于单片机的可燃气体检测系统预定的相关功能。
软件流程设计采用模块化设计的方法,即在程序编写之前,首先结合基于单片机的可燃气体检测系统硬件电路以及系统需求对程序进行功能模块化,再编写各个模块的程序,使程序易于编写、调试和修改。程序设计过程中的软件开发环境选用Keil软件。
3.1 程序架构
基于单片机的可燃气体检测系统程序架构如图3.1所示,当整个系统运行时,首先是各个部分的初始化,由于系统要实现对开关是否按下的检测,还需要完成包括单片机的中断设置等。
在这里插入图片描述

图3.1程序架构

初始化完成以后,MQ-2传感器开始工作,同时将检测到的物理量送交给AD转换器,单片机对AD转换后的数字量数据不断进行读取,而后经过计算可得到当前气体的浓度值。在此过程中,系统不断对开关按键进行检测,当检测到开关按下时,需要对设定的浓度值执行加或者减,长加或者长减。
单片机对计算得到的浓度值与设定的浓度值进行一个比较,并将检测到的浓度值实时显示。倘若当前浓度值已经超过了设定的门限,则表明处于危险状态,单片机控制蜂鸣器响、电机转动。
3.2 LCD显示程序设计
在基在基于单片机的可燃气体检测系统中,为了便于使用者直观了解系统目前的工作状态,液晶需要显示的可燃气体检测系统检测到的当前气体浓度检测值、设定的告警值(及其单位)等相关数据。上面一行显示当前浓度值:“NOW GAS:数值 PPM”,下面一行显示设定的报警门限:“Warning:数值 PPM”。如图3.2为LCD1602子程序流程图。
在这里插入图片描述

图3.2 LCD1602子程序流程图
根据LCD1602的数据手册,在使用LCD1602之前需要进行初始化,初始化需要完成2个工作,通过程序为LCD1602写入相关设置指令。
如图3.3所示为LCD1602内部的RAM地址映射图。
在这里插入图片描述

图3.3地址映射图
如图3.4所示为LCD1602写操作时序。
在这里插入图片描述

图3.4 LCD1602写操作时序
写入数据需要以下几个步骤:首先需要通过RS信号确定是写数据还是写命令,因为写数据是指显示什么内容,写命令是写入地址这些。
第二步:R/W端口输入一个低电平;
第三步:将数据从单片机的I/O口输送给液晶的数据端口;
第四步:在E端口给一个持续高电平,即可完成写操作。

3.3 按键控制程序设计
在基于单片机的可燃气体检测系统中,单片机需要控制电机持续转动的时间。持续转动的时间就由单片机内部的定时器设定,当计数记满以后产生一个中断,并产生相应的信号以控制电机的EN端口,控制电机停止或转动。
本次基于单片机的可燃气体检测系统中,单片机外界11.0592MHz的晶振,通过计算可得单片机的一个机器周期为:

同时单片机最多可计数65535个,因此中断溢出一次的时间约为65ms。而在实际使用系统的过程中,对电机的定时通常应是设定时间在分秒量级,比如1分10秒,为了程序设计中取整数倍比较方便,我们设定定时器计时时间为10ms。如此,中断一百次以后,就是时间过去了1秒。同时在程序设计中,判断中断为100次以后,则计数参数减1,即为电机还需要运行的时间少1秒。当计数参数为0,也就是计数时间减少为0的时候,通知单片机的P3.4口输出恒为低电平的信号,控制电机的EN端口,使电机停止转动。
转速控制程序设计,在基于单片机的可燃气体检测系统中,为了对电机的转速进行调节,我们需要通过与电机PWM相连的P3.7端口输出不同占空比的PWM波形。
占空比是高电平持续时间占一个周期的百分比,占空比越大,也就是P3.7口输出的高电平时间越长,电机转速越快。
单片机输出PWM波的时候,通常有下列办法:
第一个是利用软件延时,当设定的时间到,对输出的高低电平取反,。
第二个是利用定时器对高低电平时间进行控制。
第三个是PWM控制器。
为了便于程序设计,基于单片机的可燃气体检测系统程序设计中,我们选用上述第二种方案,即单片机内部的定时器实现对高低电平的持续时间控制。结合方案的介绍,我们可以首先需要确定一个恒定的周期(50ms),实现方法即可通过计数器,我们为了保证步长足够小,设定中断时间为10微秒,本次设计中,中断次数用参数usCnt来表示,最大计数次数为5000次,即usCnt最大值为5000,达到5000以后置0。而后我们更改对计数的判决门限(用参数rCnt来表示)来设置不同长度的高电平。
然后计算定时器的初值N:

根据计算得到的初值,计算装入TH1和TH2的数

最终装入的初值为255(0xFF)和246(0xF6)。
单片机每产生中断一次,就对此时的中断计数值usCnt进行判断,若是大于5000则置0,同时对rCnt和usCnt来作比较,若rCnt的值大于usCnt的值,则控制P3.7口输出高电平,控制电机的PWM端口,否则P3.7口输出低电平,如此形成了一个PWM信号,送交给电机的PWM口,控制转速。
在设计中将开关一端接在单片机的P1.0口,另外一端接地,这样通过对单片机的P1.0口的高低电平进行判断,即可知道外部开关按键是否按下。
在这里插入图片描述

图3.5按键程序流程图
由于开关按键连接到单片机的P1.0口,为了方便操作,我们首先对P1.0口进行声明,即将P1.0端口定义为Key,后续程序中不断的对Key值进行检测判断即可再执行相关的指令。
根据电路设计,理论上在Key值为0时,表明开关被按下,但由于手动按下开关再释放的这个过程有一定的抖动现象,因此我们判断Key值为0以后加上一个去抖操作,通常加上一个10ms的延时即可,延时过后再次对Key值进行判断,如果Key值仍为0,即表明开关按下,单片机需要进行发送短信的相关操作处理。然后判断Key值是否恢复到1,如果为1表明按键被释放,再次回到程序入口,不断检测Key值是否为0,判断开关是否按下,如果Key为0则继续等待。
根据基于单片机的可燃气体检测系统设计,系统在开关按下的时候需要设定的浓度判决门限进行调整,分别有浓度加1或减1,浓度长加或长减。
为了实现上述功能,进行按键控制程序设计,如图3.5为按键检测程序流程。以下分别结合电路中的开关K2 和K3 进行介绍。
K2:复位
由于开关按键连接到单片机的复位端口P3.4口,为了方便操作,我们首先对P3.4口进行声明,即将P3.4端口定义为Key1,后续程序中不断的对Key1值进行检测判断即可再执行相关的指令。
根据电路设计,理论上在Key1值为0时,表明开关被按下,但由于手动按下开关再释放的这个过程有一定的抖动现象,因此我们判断Key1值为0以后加上一个去抖操作,通常加上一个10ms的延时即可,延时过后再次对Key1值进行判断,如果Key1值仍为0,即表明开关按下,单片机进行复位,整个程序重新执行。然后判断Key1值是否恢复到1,如果为1表明按键被释放,再次回到程序入口,不断检测Key值是否为0,判断开关是否按下,如果Key为0则继续等待。
在此过程中由于涉及到了延时以及需要判断开关是否是长按,在程序设计中要增加一个定时器中断,当中断产生一次则对开关进行判断。单片机外界11.0592MHz的晶振,通过计算可得单片机的一个机器周期为:

同时单片机最多可计数65535个,因此中断溢出一次的时间约为65ms。而在实际使用系统的过程中,对电机的定时通常应是设定时间在分秒量级,为了程序设计中取整数倍比较方便,我们设定定时器计时时间为10ms。如此,中断一百次以后,就是时间过去了1秒。
我们可以首先需要确定一个恒定的周期(50ms),实现方法即可通过上文的计数器,我们为了保证步长足够小,设定中断时间为10微秒,本次设计中,中断次数用参数usCnt来表示。
然后计算定时器的初值N:

根据计算得到的初值5000,计算装入TH0和TL0的数

最终装入的初值为0x3c和0xB0。
每产生一次中断,即对Key1进行判断,若检测的长按时间到达20次中断,则对门限值持加。
(2)K3:
由于开关按键连接到单片机的P3.5口,为了方便操作,我们首先对P3.5口进行声明,即将P3.5端口定义为Key2,后续程序中不断的对Key2值进行检测判断即可再执行相关的指令。
Key2值为0以后加上一个去抖操作,通常加上一个10ms的延时即可,延时过后再次对Key2值进行判断,如果Key2值仍为0,即表明开关按下,每产生一次中断,即对Key2进行判断,若检测的长按时间到达20次中断,则对门限值持续减。

4 系统验证

4.1 焊接与调试
在完成基于单片机的可燃气体检测系统的电路设计以后,生成PCB,而后进行封装,布线等一系列流程以后,将样板送交给厂家进行绘制。并完成系统中所需要元器件的采购。
当电路板原理图绘制完成后,确认各个模块功能没有错误,根据文章附件中的相关器件,进行采购和测试。在确定原理图没有出现错误的情况下我们开始进行焊接,使用市场上比较常用的万能板进行焊接。
最终得到的实物图如图4.1所示。
在这里插入图片描述

图4.1 系统实物图

4.2 程序烧录与调试
当单片机焊接好之后,将STC89C52单片机和各个模块都插上去,给系统12V供电。
按下启动键以后,电源灯会常亮,屏幕的初始值:上面一行显示当前浓度值:“NOW GAS:数值 PPM”,下面一行显示设定的报警门限:“Warning:数值 PPM”。
为了对系统进行测试,我们在传感器旁边用打火机模拟,可以发现,在点燃火机的时候,探测到的浓度值迅速提高,依据LCD显示,可以发现在瞬间达到一千多,同时蜂鸣器响,电机转动。
我们按下开关K2,可以发现设定的浓度值每按一下会加1,在长按的时候,设定的浓度值持续加1;按下开关K3,可以发现设定的浓度值每按一下会减1,在长按的时候,设定的浓度值持续减1。
经过调试与验证,基于单片机的可燃气体检测系统已经实现了初始的应用需求,可以对系统所在环境的浓度值进行判断,并通过按键对浓度值进行调整,在超过门限值的时候,能够实现蜂鸣器响、电机转动等报警功能,有着很强的可靠性与实用性。

结 论

为了对火灾进行预警,避免灾害的发生,本文设计了一款基于单片机的可燃气体检测系统。基于单片机的可燃气体检测系统通过传感器对当前环境的可燃气体浓度值进行实时检测,经过AD转换后送交给单片机进行处理;可以通过外部按键来对系统的判决门限即最高浓度值进行设置;单片机对数据处理后,与设定的最高浓度值进行比较,若是大于该浓度值,则输出信号控制蜂鸣器响、电机转动;整个过程中的探测值、设定值均由LCD液晶来进行显示。
本文首先分析了基于单片机的可燃气体检测系统的设计需求,完成了系统架构设计。在此基础上进行了单片机外围电路设计,液晶显示外部电路设计,MQ传感器与AD转换电路设计,电机外部电路设计,开关电路设计。在完成硬件电路设计的基础上,进行了软件流程设计,包括对LCD液晶显示控制程序,读取AD转换后的数据,按键控制程序。
经过调试与验证,基于单片机的可燃气体检测系统已经实现了初始的应用需求,可以对系统所在环境的浓度值进行判断,并通过按键对浓度值进行调整,在超过门限值的时候,能够实现蜂鸣器响、电机转动等报警功能,有着很强的可靠性与实用性。

参考文献

[1] 彭伟.单片机C语言程序设计实训100例[M].北京:电子工业出版社.2009.1:108-152
[2] 林若波,李锡丰,郑烁.晴雨智能晾衣架的设计[J].电子技术,2006.1:102-109
[3] 霍孟友.单片机原理与应用[M].北京:机械工业出版社,2004.1:23-45
[4] 周润景,徐宏伟,丁莉.单片机电路设计、分析与制作[M].北京:机械工业出版社,2010.8:89-96
[5] 袁飞,卢文科,胡频. 可燃性气体探测器的设计[J]. 仪表技术, 2009,11(1) :23-24
[6] 邹方勇. 特殊区域使用的探测器[J]. 消防科学与技术, 2006,23:18
[7] 马宝珠. 家用感烟探测器[J]. 消防科学与技术, 2004,10:18
[8] 马忠梅等.单片机的C语言应用程序设计[M].北京航空航天大学出版社,2006.1:102-141
[9] 蒙平. 各类火灾探测器原理分析及应用探讨[J]. 企业科技与发展, 2009,5:15
[10]何立民.单片机应用系统设计[J].北京:航天航空大学出版社.2016,6:52
[11]刘亮. 可燃气体检测报警系统设计[J]. 中国仪器仪表, 2008,6:23
[12]陈杰,黄鸿.传感器与检测技术[M].北京:高等教育出版社,2002.1:23-48
[13]贾良菊,应鹏展.气敏传感器的研究现状与发展趋势[J].煤矿机械.2005,4:56
[14]王百战. 可燃气体检测报警器的安装、使用和维护[J]. 安全.2009,9:45
[15]徐根耀.电子元器件与电子制作[M].北京:机械工业出版社,2017.8:12
[16]胡学海.单片机原理及应用系统设计[M]. 北京: 电子工业出版社,2007:66-156.

附录1 元器件清单
标号 型号 数量 标号
B2 5V风扇+XH-2A白底座 1 B2
C1 10uF电解电容 1 C1
C2, C3 30p瓷片电容 2 C2, C3
C19 104瓷片电容 1 C19
J1 电源接口 1 J1
K1, K2, K3 轻触按键 3 K1, K2, K3
L1 3mm红色LED 1 L1
LS1 蜂鸣器 1 LS1
P1 LCD1602液晶屏+16P排座 1 P1
P4 4P排针 1 P4
PR1 8位10K排阻 1 PR1
Q7, Q9 8550三极管 2 Q7, Q9
R1 3K电阻 1 R1
R2 10K电阻 1 R2

附录2 源程序清单
#include <REGX52.H>
#include <intrins.h>
#include “LCD1602.h”
#include “ADC0832.h”
#include “eeprom52.h”

#define uint unsigned int
#define uchar unsigned char

sbit key1=P3^4; //按键
sbit key2=P3^5;
sbit beep=P1^7; //蜂鸣器
sbit Fan=P3^6; //风扇
bit key1_flag=0; //按键标志位
bit key2_flag=0;

sbit LED0=P1^6; //指示灯
sbit LED1=P1^4;

uchar sec=0;sec1=0; //长按标志位
uchar s0=0,temp,temp1,ms; //浓度值,定时时间,浓度上限
uint Value=0;
uint temp_h;
bit Send_flag=0;
bit flag=1;
//----------> GSM相关变量
uchar phone[11]=“15225939196”; //手机号数组
//-----> Uart1 And GSM Definition
unsigned char xdata Uart1_Buff[50]; //串口1缓冲数组
unsigned char Uart1_Count=0; //串口1累加变量

unsigned char Quest_flag=1; //初始化标志位
unsigned int GSM_Send_Time=0; //GSM延时变量
unsigned char GSM_Num=0; //发送指令变量
unsigned char GSM_Send=0; //发送标志位
unsigned char GSM_Send_Num=0; //发送具体短信内容变量
bit memory_flag=0;
void delay(uint T) //延时程序
{
while(T–);
}
void memory() //掉电存储
{
unsigned char q=0;
if(memory_flag)
{
memory_flag=0;
SectorErase(0x2000);
byte_write(0x2000,temp_h/256);
byte_write(0x2001,temp_h%256);
for(q=0;q<11;q++)
{
byte_write(0x2100+q,phone[q]);
}
}
}

void read_memory() //上电读存储
{
unsigned char q=0;
temp_h=byte_read(0x2000)*256+byte_read(0x2001);
for(q=0;q<11;q++)
{
phone[q]=byte_read(0x2100+q);
}
if(temp_h>255||temp_h<0)
{
temp_h=20;
}
}

void timer_init() //定时器初始化
{
TMOD=0x01; //定时器0,方式1
TH0=0x3c; //初值50ms
TL0=0XB0;
TR0=1;
ET0=1;
EA=1;
}

void display() //显示函数
{
LCD1602_write(0,0x80);
LCD1602_writebyte(“NOW GAS:”);
if(temp/1000)
{
LCD1602_writebyte(" ");
if(temp%100/10
0)
{
LCD1602_writebyte(" ");
}
else
{
LCD1602_write(1,‘0’+temp%100/10);
}
LCD1602_write(1,‘0’+temp%10);
LCD1602_writebyte("PPM ");
}
else
{
LCD1602_write(1,‘0’+temp/100);
LCD1602_write(1,‘0’+temp%100/10);
LCD1602_write(1,‘0’+temp%10);
LCD1602_writebyte("PPM ");
}

LCD1602_write(0,0xc0);
LCD1602_writebyte("WARNING:");
if(temp_h/100==0)
{
	LCD1602_writebyte(" ");	
	if(temp_h%100/10==0)
	{
		LCD1602_writebyte(" ");
	}
	else 
	{
		LCD1602_write(1,'0'+temp_h%100/10);
	}
	LCD1602_write(1,'0'+temp_h%10);
	LCD1602_writebyte("PPM  ");
}
else
{
	LCD1602_write(1,'0'+temp_h/100);
	LCD1602_write(1,'0'+temp_h%100/10);
	LCD1602_write(1,'0'+temp_h%10);
	LCD1602_writebyte("PPM  ");				
}

}

void keyscan() //按键扫描
{
if(!key1)
{
if(key1_flag)
{
key1_flag=0;
if(temp_h<255)temp_h++;
}

	if(sec==0)
	{
		key1_flag=0;
		if(temp_h<255)temp_h++;	
	}
	memory_flag=1;
}
else 
{
	key1_flag=1;
	sec=2;
}
if(!key2)
{
	if(key2_flag)
	{
		key2_flag=0;
		if(temp_h>0)temp_h--;
	}

	if(sec1==0)
	{
		key2_flag=0;
		if(temp_h>0)temp_h--;	
	}
	memory_flag=1;
}
else 
{
	key2_flag=1;
	sec1=2;
}

}

void Timer2_Uart()
{
T2CON = 0x34;
RCAP2H = 0xFF;
RCAP2L = 0xDC;
TH2 = 0xFF;
TL2 = 0xDC;
TR2 = 1;
SCON = 0x50;
ES = 1;
EA=1;
}
void Uart1Data(unsigned char dat) //发送一个字节
{
SBUF=dat;
while(!TI);
TI=0;
}
void UartData_Byte(char *s) //发送一串数据
{
while (*s != ‘\0’)
{
Uart1Data(*s++);
}
}
void GSM_Init2()
{
unsigned char G_Tab[20]=0;
if(Quest_flag1) //开始查询GSM状态//此时还没有初始化完成,首先,先初始化 ,发AT,能够响应上,关回显,设置短信处理方式
{
switch(GSM_Num)
{
case 0: UartData_Byte(“AT\r\n”); break; //AT
case 1: UartData_Byte(“ATE1\r\n”); break;//关回显
case 2: UartData_Byte(“AT+CNMI=3,2,2,0,1\r\n”); break;//设置
case 3: UartData_Byte(“AT+CMGF=1\r\n”); break; //配制
case 4: UartData_Byte(“AT+COPS?\r\n”); break; //查询网络
case 5: Quest_flag=0; GSM_Num=0; break; //初始化彻底结束
}
GSM_Send_Time=10;
}
else
{
GSM_Send_Time=40;
if(GSM_Send
1) //发送短信标志
{
if(GSM_Send_Num==0) //Num 是短信编号,就是发送哪条短信,这个是返回Set End 的
{
switch(GSM_Num)
{
case 0: UartData_Byte(“AT+CMGF=1\r\n”); break;

						case 1: UartData_Byte("AT+CMGS=\"");                                          
								Uart1Data(phone[0]);
								Uart1Data(phone[1]);
  								Uart1Data(phone[2]);
								Uart1Data(phone[3]);
								Uart1Data(phone[4]);
  								Uart1Data(phone[5]);
								Uart1Data(phone[6]);
								Uart1Data(phone[7]);
  								Uart1Data(phone[8]);
								Uart1Data(phone[9]);
								Uart1Data(phone[10]);      
							    UartData_Byte("\"\r\n");                      break; //AT+CMGS="13343851798"
						
						case 2: UartData_Byte("Set End");  GSM_Num=3;                break; 
						
						case 3: G_Tab[0]=0x1a; 
						        Uart1Data(G_Tab[0]);                         break; 
								 
						case 4: GSM_Num=0;   GSM_Send=0; Quest_flag=1;                break; 								
					}			
			 }
			else if(GSM_Send_Num==1)
			 {		
					switch(GSM_Num)
					{
						case 0: UartData_Byte("AT+CMGF=0\r\n");      break;  
						
						case 1: UartData_Byte("AT+CMGS=41\r\n");     break;   

						case 2: UartData_Byte("0011000D9168"); 
                                    G_Tab[0]=phone[1];
							        G_Tab[1]=phone[0];
							        G_Tab[2]=phone[3];
							        G_Tab[3]=phone[2];
							        G_Tab[4]=phone[5];
							        G_Tab[5]=phone[4];
							        G_Tab[6]=phone[7];
							        G_Tab[7]=phone[6];
							        G_Tab[8]=phone[9];
							        G_Tab[9]=phone[8];
							        G_Tab[10]='F';
								    G_Tab[11]=phone[10];
							        UartData_Byte(G_Tab);  
						        UartData_Byte("0008A91A"); //末尾两位数是发送的短信长度,每个汉字占两个字节(18个字节转16进制为12)
                                UartData_Byte("67095BB36C144F536D535EA68FC79AD8FF0C8BF76CE8610FFF01");//有害气体浓度过高,请注意!
                                GSM_Num=3; 
						break;  
						
						case 3: G_Tab[0]=0x1a;  
						         Uart1Data(G_Tab[0]);                  break;   
						case 4: 
							    UartData_Byte("AT+CMGF=1\r\n"); 
						        delay(666);delay(666);
						        GSM_Send = 0; 
							    GSM_Num=0;
								Quest_flag=1;									
						break; 
										
					}
			 }			
		}
		else GSM_Num=0;	
}

}
void Send_message()
{
if(Send_flag1)
{
if(GSM_Send
0&&GSM_Num==0)
{
GSM_Send=1;
GSM_Send_Num=1;
Send_flag=0;
}
}
}
void police() //超限报警
{
if(temp>=temp_h)
{
if(s0)
beep=0;
else beep=1;
Fan=0;
if(flag)
{
flag=0;
Send_flag=1;
}
LED0 = 0;
LED1 = 1;

}				 
else 
{
	beep=1;
	Fan=1;
	flag=1;
	LED0 = 1;
	LED1 = 0;
}

}

void main() //主函数
{
uchar num=0;
temp_h=20; //上限赋初值
LCD1602_cls(); //液晶1602初始化
timer_init(); //定时器初始化
Timer2_Uart();
read_memory(); //读存储数据
num=0;
while(1)
{
if(num<80)
{

	    Value+=A_D();
		num++;
	}
	else 
	{
		num=0;
		temp=temp*0.5+(Value/80)*0.5;	  
		Value=0;			
	}
	memory();
	display();
	police();
	Send_message();
	if(GSM_Send_Time==0) GSM_Init2();
}

}

void timer() interrupt 1
{
TH0=0x3c;
TL0=0XB0;
ms++;
if(GSM_Send_Time!=0) GSM_Send_Time–;
keyscan();
if(ms%100)
{
s0=~s0;
}
if(ms%20
0)
{
if(sec!=0)sec–;
if(sec1!=0)sec1–;
}
}
void Uart1() interrupt 4
{
uchar i=0;
if(RI)
{
RI=0;
Uart1_Buff[Uart1_Count] = SBUF;
Uart1_Count=(Uart1_Count+1)%50;
Uart1_Buff[Uart1_Count]=0;

   if(Quest_flag==1) //说明此时在初始化
	{
	   if(GSM_Num==0||GSM_Num==1||GSM_Num==2||GSM_Num==3) //这里都是返回的  OK
		 {
		   if(Uart1_Count>=4&&Uart1_Buff[Uart1_Count-1]=='\n'&&Uart1_Buff[Uart1_Count-2]=='\r'&&Uart1_Buff[Uart1_Count-3]=='K'&&Uart1_Buff[Uart1_Count-4]=='O')
			 {
			   GSM_Num++;
			   GSM_Send_Time=10;
			 }
		 }
		 else if(GSM_Num==4) //+COPS: 0,0,"CHINA MOBILE"
		 {
		   if(Uart1_Count>=25&&Uart1_Buff[Uart1_Count-1]=='\n'&&Uart1_Buff[Uart1_Count-2]=='\r'&&Uart1_Buff[Uart1_Count-3]=='"'&&Uart1_Buff[Uart1_Count-4]=='E'&&Uart1_Buff[Uart1_Count-11]=='A')
			 {
			   GSM_Num++;
			   GSM_Send_Time=10;
			 }
		 }
	}
	else 
	{
	   if(GSM_Num==0||GSM_Num==2||GSM_Num==3) //这里都是返回的  OK
		 {
		   if(Uart1_Count>=4&&Uart1_Buff[Uart1_Count-1]=='\n'&&Uart1_Buff[Uart1_Count-2]=='\r'&&Uart1_Buff[Uart1_Count-3]=='K'&&Uart1_Buff[Uart1_Count-4]=='O')
			 {
			   	 GSM_Num++;
				 GSM_Send_Time=10;
			 }
		   if(Uart1_Count>=7&&Uart1_Buff[Uart1_Count-1]=='\n'&&Uart1_Buff[Uart1_Count-2]=='\r'&&Uart1_Buff[Uart1_Count-3]=='R'&&Uart1_Buff[Uart1_Count-7]=='E')
			 { //ERROR
			   if(GSM_Num==3) 
				 {
				    GSM_Num=0;
					 GSM_Send_Time=10;
				 }
			 }			 
		 }
		 else if(GSM_Num==1) //>
		 {
		   if(Uart1_Count>=1&&Uart1_Buff[Uart1_Count-1]=='>')
			 {
			     GSM_Num++;
				 GSM_Send_Time=10;
			 }
		 }	 
	}
 
 	 
  if(Uart1_Count>=2&&Uart1_Buff[Uart1_Count-2]=='\r'&&Uart1_Buff[Uart1_Count-1]=='\n') //接收到回车符
	{
		 //PHONE SMS:12345678911 
		 
		 if(Uart1_Count>=23&&Uart1_Buff[Uart1_Count-23]=='P'&&Uart1_Buff[Uart1_Count-19]=='E'&&Uart1_Buff[Uart1_Count-15]=='S'&&Uart1_Buff[Uart1_Count-14]==':')
		  {
			for(i=0;i<11;i++)					   //保存到单片机中的手机号
			{
				phone[i]=Uart1_Buff[(Uart1_Count-13)+i];	
			}
			    GSM_Send=1;  
				GSM_Send_Num=0; 
				memory_flag=1;
		  }
		 Uart1_Count=0;
	}
}

}

#ifndef LCD1602_H
#define LCD1602_H

#define uchar unsigned char
#define uint unsigned int

#define LCD1602_dat P0 //数据并行口宏定义

sbit LCD1602_rs=P2^5;//IO 定义
sbit LCD1602_rw=P2^6;
sbit LCD1602_e=P2^7;

void LCD1602_delay(uint T) //延时函数
{
while(T–);
}

/********************************************************************

  • 名称 : LCD1602_write(uchar order,dat)
  • 功能 : 1602写如数据函数
  • 输入 : order为数据/命令切换变量 //0是命令 1是数据
  • : dat为数据/命令的发送数据
  • 输出 : 无
    ***/
    void LCD1602_write(uchar order,dat) //1602 一个字节 处理
    {
    LCD1602_e=0;
    LCD1602_rs=order;
    LCD1602_dat=dat;
    LCD1602_rw=0;
    LCD1602_e=1;
    LCD1602_delay(1);
    LCD1602_e=0;
    }
    /
  • 名称 : LCD1602_writebye(uchar *prointer)
  • 功能 : 1602写入数据函数 指针式
  • 输入 : 输入需要显示的内容
  • 输出 : 无
    ******/
    void LCD1602_writebyte(uchar prointer) //1602 字符串 处理
    {
    while(prointer!=‘\0’)
    {
    LCD1602_write(1,prointer);
    prointer++;
    }
    }
    /
  • 名称 : LCD1602_cls()
  • 功能 : 初始化1602液晶
  • 输入 : 无
  • 输出 : 无
    ***********************************************************************/
    void LCD1602_cls() //1602 初始化
    {
    LCD1602_write(0,0x01); //1602 清屏 指令
    LCD1602_delay(1500);
    LCD1602_write(0,0x38); // 功能设置 8位、5*7点阵
    LCD1602_delay(1500);
    LCD1602_write(0,0x0c); //设置 光标 不显示开关、不显示光标、字符不闪烁
    LCD1602_write(0,0x06);
    LCD1602_write(0,0xd0);
    LCD1602_delay(1500);
    }

#endif

/*****************************************************
功能:将模拟信号转换成数字信号
***************************************************/
sbit ADC0832_CS=P1^2;
sbit ADC0832_CLK=P1^0;
sbit ADC0832_DIO=P1^1;

unsigned int A_D()
{
unsigned char i,dat;
ADC0832_CS=1; //一个转换周期开始
ADC0832_CLK=0; //为第一个脉冲作准备
ADC0832_CS=0; //CS置0,片选有效

ADC0832_DIO=1; //DIO置1,规定的起始信号
ADC0832_CLK=1; //第一个脉冲
ADC0832_CLK=0; //第一个脉冲的下降沿,此前DIO必须是高电平
ADC0832_DIO=1; //DIO置1, 通道选择信号
ADC0832_CLK=1; //第二个脉冲,第2、3个脉冲下沉之前,DI必须跟别输入两位数据用于选择通道,这里选通道CH0
ADC0832_CLK=0; //第二个脉冲下降沿
ADC0832_DIO=0; //DI置0,选择通道0
ADC0832_CLK=1; //第三个脉冲
ADC0832_CLK=0; //第三个脉冲下降沿
ADC0832_DIO=1; //第三个脉冲下沉之后,输入端DIO失去作用,应置1
ADC0832_CLK=1; //第四个脉冲
for(i=0;i<8;i++) //高位在前
{
ADC0832_CLK=1; //第四个脉冲
ADC0832_CLK=0;
dat<<=1; //将下面储存的低位数据向右移
dat|=(unsigned char)ADC0832_DIO; //将输出数据DIO通过或运算储存在dat最低位
}
ADC0832_CS=1; //片选无效
return dat; //将读书的数据返回
}

#ifndef EEPROM52_H
#define EEPROM52_H
#include <intrins.h>

/*STC89C51扇区分布
第一扇区:1000H–11FF
第二扇区:1200H–13FF
第三扇区:1400H–15FF
第四扇区:1600H–17FF
第五扇区:1800H–19FF
第六扇区:1A00H–1BFF
第七扇区:1C00H–1DFF
第八扇区:1E00H–1FFF
*****************/

/*STC89C52扇区分布
第一扇区:2000H–21FF
第二扇区:2200H–23FF
第三扇区:2400H–25FF
第四扇区:2600H–27FF
第五扇区:2800H–29FF
第六扇区:2A00H–2BFF
第七扇区:2C00H–2DFF
第八扇区:2E00H–2FFF
*****************/

#define RdCommand 0x01 //定义ISP的操作命令
#define PrgCommand 0x02
#define EraseCommand 0x03
#define Error 1
#define Ok 0
#define WaitTime 0x01 //定义CPU的等待时间
sfr ISP_DATA=0xe2; //寄存器申明
sfr ISP_ADDRH=0xe3;
sfr ISP_ADDRL=0xe4;
sfr ISP_CMD=0xe5;
sfr ISP_TRIG=0xe6;
sfr ISP_CONTR=0xe7;

/* ================ 打开 ISP,IAP 功能 ================= /
void ISP_IAP_enable(void)
{
EA = 0; /
关中断 /
ISP_CONTR = ISP_CONTR & 0x18; /
0001,1000 /
ISP_CONTR = ISP_CONTR | WaitTime; /
写入硬件延时 /
ISP_CONTR = ISP_CONTR | 0x80; /
ISPEN=1 /
}
/
=============== 关闭 ISP,IAP 功能 ================== /
void ISP_IAP_disable(void)
{
ISP_CONTR = ISP_CONTR & 0x7f; /
ISPEN = 0 /
ISP_TRIG = 0x00;
EA = 1; /
开中断 /
}
/
================ 公用的触发代码 ==================== /
void ISPgoon(void)
{
ISP_IAP_enable(); /
打开 ISP,IAP 功能 /
ISP_TRIG = 0x46; /
触发ISP_IAP命令字节1 /
ISP_TRIG = 0xb9; /
触发ISP_IAP命令字节2 /
nop();
}
/
==================== 字节读 ======================== /
unsigned char byte_read(unsigned int byte_addr)
{
EA = 0;
ISP_ADDRH = (unsigned char)(byte_addr >> 8);/
地址赋值 /
ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);
ISP_CMD = ISP_CMD & 0xf8; /
清除低3位 /
ISP_CMD = ISP_CMD | RdCommand; /
写入读命令 /
ISPgoon(); /
触发执行 /
ISP_IAP_disable(); /
关闭ISP,IAP功能 /
EA = 1;
return (ISP_DATA); /
返回读到的数据 /
}
/
================== 扇区擦除 ======================== /
void SectorErase(unsigned int sector_addr)
{
unsigned int iSectorAddr;
iSectorAddr = (sector_addr & 0xfe00); /
取扇区地址 /
ISP_ADDRH = (unsigned char)(iSectorAddr >> 8);
ISP_ADDRL = 0x00;
ISP_CMD = ISP_CMD & 0xf8; /
清空低3位 /
ISP_CMD = ISP_CMD | EraseCommand; /
擦除命令3 /
ISPgoon(); /
触发执行 /
ISP_IAP_disable(); /
关闭ISP,IAP功能 /
}
/
==================== 字节写 ======================== /
void byte_write(unsigned int byte_addr, unsigned char original_data)
{
EA = 0;
// SectorErase(byte_addr);
ISP_ADDRH = (unsigned char)(byte_addr >> 8); /
取地址 /
ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);
ISP_CMD = ISP_CMD & 0xf8; /
清低3位 /
ISP_CMD = ISP_CMD | PrgCommand; /
写命令2 /
ISP_DATA = original_data; /
写入数据准备 /
ISPgoon(); /
触发执行 /
ISP_IAP_disable(); /
关闭IAP功能 */
EA =1;
}

#endif

致 谢

在这次毕业设计中,在几个月的毕业设计制作过程中,受到了老师的辛勤指导,在老师的耐心指导下,顺利的完成了本次毕业设计,在此由衷的向老师表示敬意,也同样非常感谢在毕业设计过程中给我提供帮助的同学和朋友,感谢我的父母和亲人对我的陪伴支持。
本次毕业设计的内容是基于单片机的可燃气体检测系统,从选题到构思到最后的实现,期间遇到了很多问题,在老师的指导下,一点点去查资料,去不断地尝试实验,期间学到了很多知识,难题逐个击破。不仅在专业知识上的学习更加深入,也学会了很多做人的道理和做事的方法。老师的理论知识和严谨的态度让我深受启发,在此要对老师致以衷心的感谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值