空气质量监测仪设计——软件部分

空气质量监测仪设计——软件部分[20191230145520]
毕业设计说明书(论文)中文摘要
经济的不断发展带来了一系列环境问题。其中室内环境问题尤为突出,我们一生三分之二的时间都是在居室内度过的,所以室内环境的好坏对我们的身体健康非常重要。本文研究的室内空气质量监测仪是以室内空气中有毒有害气体的监测监控为背景,以一款超低功耗单片机STC12C5A60S2为控制核心,能够实现对室内温度,湿度,有毒有害气体的实时采集处理、显示、报警等功能。本仪器采用两节锂电池供电,具有良好的便携性和通用性,我们还使用了LCD1602液晶屏实时显示各项参数值,具有良好的人机对话界面。同时设计了声光报警系统,可以实现在参数超标时进行声光报警。室内智能空气品质监测仪体积小,功耗低,操作简单,适合应用于家庭和社区的医疗健康保健,能够实时知道室内空气的质量。 关健词 STC12C5A60S2, LCD显示,温湿度,有毒有害气体
毕业设计说明书(论文)外文摘要
Title The Design of Air Quality Monitor ——Software Part Abstract The continuous development of economy brings a series of environmental problems. The indoor environment problem is particularly prominent, two-thirds of our life is spent in the bedroom, so the stand or fall of indoor environment is very important for our health. In this paper, Indoor Air Quality Portable Intelligent Monitor which will be studied in this paper, is on the background of toxic and harmful gases, and based on a ultra-low power MCU STC12C5A60S2 as control core. It can process, display, and alarm the real-time acquisition indoor temperature, humidity, Toxic or harmful gases and so on. The instrument is powered by two lithium batteries with a good portability and versatility. What’s more, we also use the LCD1602 that can real-time display various parameter values, and has a good interactive interface. At the same time, sound and light alarm system is designed to achieve a timely manner when the parameter level exceeds the limit. With the features of small size, low power consumption, operating easily, Indoor Air Quality Portable Intelligent Monitor is suitable for family and community health care for its real-time acquisition of indoor air quality. Keywords STC12C5A60S2, LCD display, temperature and humidity, toxic or harmful gases
1 引言 1
1.1研究背景 1
2 课题研究意义 2
3 空气质量监测系统发展历程和研究现状 2
4 总体方案设计 3
4.1 空气质量监测仪的功能要求 3
4.2 系统框图 3
5 空气质量检测仪的硬件设计 4
5.1 STC12C5A60S2单片机简介 4
5.2 DHT11简介 7
5.3 LCD简介 9
6 软件设计 12
6.1 编程语言的选择 12
6.2 软件功能需求 12
6.3 软件模块设计 13
7 仿真调试 27
7.1 系统软件调试 27
7.2 功能调试 28
结 论 30
致 谢 31
参 考 文 献 32
附录1 完整代码 33
1 引言
1.1研究背景
如今,随着经济的快速发展,周围的空气越来越差,这对我们的健康非常有害。空气质量 的好坏与很多因素有关,在不同的空间和时间内空气中污染物的浓度是不同的,所以对空气质量的研究成为了一个难题。
空气中的污染物大体由以下几类组成:一是降尘、粉尘、烟尘等颗粒物,农村家庭用柴火做饭、建筑工地上扬起的沙尘和烟民吸烟都会产生这类污染物。二是二氧化硫、二氧化氮等化学污染物,北方取暖用的锅炉和有些工厂燃烧煤炭所产生的烟尘都是形成这些物质的罪魁祸首。现今,汽车的数量越来越多,这更加剧了这些物质的排放。当人们打开门窗的时候这些有毒有害物质就会进入室内。三是微生物污染物,这些污染物遍布空气各个角落,而且不易察觉,只要人呼吸就会将其带入体内,正常人每天呼吸大概有2万多次,如果这些微生物污染物漂浮在我们周围,那么我们的身体内部会挤满这些物质[1]。因此,空气重度污染对我们的健康是一种致命的伤害。
现在,越来越多的人开始重视室内的美观而用各种装饰材料,这些材料的质量没有专门机构进行评估,材料的质量一旦有问题将直接影响人们的健康。许多室内空气污染物在短期内就会给人体健康带来很大的风险,还有一些污染物在人体内的潜伏期很长,正常情况下在3-15年左右。例如很多装修产品会存在放射性物质,人们一旦接触,刚开始感觉不到任何异样,但是过个十几年被发现的时候已经没法挽救了。人们每天都会有一半的时间在室内度过,如果室内空气的质量有问题,这对人体的健康伤害是非常大的[2]。所以,对室内空气质量的监测迫在眉睫。
室内空气质量监测是刚兴起的一种行业,它主要对室内装饰装修、家具购买导致的室内环境污染超标进行实时监控,我们能够依据最终的检测值来判断室内空气质量是否达标,如果不达标则做出相应的保护措施。
空气质量监测系统是用传感器对有毒有害气体信息进行收集,利用传感器信息技术,并选用成熟的智能识别算法实现监测,当报警器接受到超出正常浓度的有害气体后,立即通过转换,产生声、光报警信号。
空气质量监测系统的软件部分采用C语言编写,C 语言内部带有很多可调用函数,并且调用方便。多种循环、条件、选择语句还可以控制程序的流向。各模块相互独立又可以随意调用,这对软件的编写提供了极大地方便。
本设计以宏晶科技公司的单片机为核心,采用空气质量传感器和温湿度传感器对异常状况进行多角度监测,如果某室内温湿度或有毒有害气体浓度超过上限值则单片机控制声光报警电路使异常灯点亮并且报警。
2 课题研究意义
单片机 是微型计算机的简称。中央处理器 (CPU)、一定容量的随机存储器 RAM、只读存储器ROM 、定时/计数器及多种I/O口等部件被集中在很小的一块芯片上所构成的微型计算机。由于半导体芯片技术和单片机自身的特殊结构,导致单片机具有优良的性能、集成度高、体积小、控制功能强、功耗低等特点[3]。
生活中很多领域都会涉及到单片机,它作为各种智能仪器的大脑,让冰冷的机器变得更加智能。军事上用的导航装置,飞机上各种仪表的控制,计算机的数据传输、工厂中自动化生产过程的实时监测和数据处理、高档轿车的安全保障和智能倒车系统等,这些都与单片机 有密切的关系[4, 5]。因此,单片机的发展和应用,对我国自动化行业来说是非常重要的。对于我们学测控专业的学生来说,更应该熟练并且灵活的掌握它,将它应用于精密仪器的设计中。
在研究该课题的过程中,用到了以前所学的各门专业课的知识,对于不懂的问题可以直接查找课本。在使用芯片以及写代码的过程中,通过浏览论坛、查找资料,加强了我收集资料、消化资料和综合资料的能力。总而言之,这次对本课题的研究增强了我解决实际工程技术问题的能力,这对我以后步入工作做了扎实的准备。
空气质量监测仪能实时监测室内空气质量,对于人们不易发觉的气体可以做早期预报,这样可以对人们健康的损失降到最低限度。室内空气检测仪方便携带,装修装饰公司可以用它来检验装修后室内的空气质量,采矿厂可以用它来检测矿井内有害气体浓度,做好相应的防护。本仪器还可以对室内、居住区、公共场所中空气中的氨气、硫化物、苯系蒸汽的现场定量定性检测。空气质量监测仪能对空气中有毒有害气体进行实时监测并且准确报警,对于保护人身安全具有重要意义,同时还具有可观的经济和社会效益。
3 空气质量监测系统发展历程和研究现状
随着科学技术的不断发展,空气质量监测技术也在不断进步,这主要是传感器的不断改善。
最近几年,由于环境问题,对有毒有害气体的监测成为了一个新热点。在以前,对气体浓度的检测都是依靠化学试剂进行反应,然后定性的分析,这种方法周期太长、花费过多,不适合普通家庭使用。近年来,用传感器检测气体浓度越来越流行,比如说压电类传感器,这类传感器的优势就是不必对样本做处理就能测定甲醛含量,但是它的缺陷在于当有水分子存在时会使晶体震动频率发生漂移,所以基本没有实用性[6]。因此,为了满足甲醛浓度可以被快速的检测出来,现在已经开发出了很多测定仪,这些仪器可直接被带到现场测定甲醛浓度,对它们的操纵也很方便,这些仪器比较适合室内和公共场所空气中甲醛浓度的现场测定,在对木质材料中甲醛含量的测量也很理想[7]。
在测试甲醛、苯、氨气等有害气体方面,国际上相对比较著名的是美国ESC公司制造的Z-300甲醛检测仪以及英国PPM公司制造的PPM-400甲醛检测仪[8]。
在监测有毒有害气体方面,这些仪器表现突出。但是准确测定甲醛、苯、氨和其他有毒有害气体的设备非常昂贵,并且它的测定周期还很长,需要频繁重新校准和专业人员操作,难以连续测定[9]。
空气质量监测仪设计的差异主要是在传感器和单片机芯片的选择上,外国产品具有更方便的操作界面,可实现的功能也相对更完善。
4 总体方案设计
4.1 空气质量监测仪的功能要求
1、本课题是以单片机为控制核心。
2、能够实现对室内温度,湿度,有毒有害气体的实时采集处理。
3、通过LCD显示各项参数的测量值以及上限值。
4、当有毒有害气体浓度超出安全范围时进行声光报警。
5、按键操作可进行测量值范围的调整。
4.2 系统框图
系统框图如图4.1所示。
图4.1 系统框图
本文研究的室内空气质量监测仪所使用的微处理器为STC12C5A60S2,温湿度传感器为DHT11,空气质量传感器为MQ135,显示屏用LCD1602。室内空气中有毒有害气体通过传感器采集,然后经过传感器内部电路会输出一个与气体浓度相对应的电压信号,该信号经过单片机将模拟信号转换为数字信号,然后在单片机内部进行数据处理以便进行显示。由于温湿度传感器输出的是数字量,所以可以直接与单片机相连。若检测到室内空气中有毒有害气体或温湿度超出设定范围时驱动报警电路发出声光报警信号。温湿度和气体浓度的上限可以通过独立键盘调整。
5 空气质量检测仪的硬件设计
5.1 STC12C5A60S2单片机简介
STC12C5A60S2/AD/PWM系列单片机是宏晶科技生产的单时钟/机器周期(1T)的单片机,与传统的8051相比,它在速度、功耗、抗干扰方面更加强大。它的指令代码也完全兼容传统的8051。在它内部还有MAX810专用复位电路,最重要的是它自身带有8路高速10位A/D转换器。在对电机的控制以及抗干扰方面的优势非常明显 [10]。
5.1.1 STC12C5A60S2芯片主要性能参数:
(1)工作电压:3.3V-5.5V;
(2)工作频率范围:0-35MHz;
(3)用户可应用程序空间类型有很多,最常用的为60K;
(4)看门狗;
(5)有一个专用复位电路MAX810集成在内部;
(6)时钟源有两个,由外部高精度晶体/时钟和内部R/C振荡器组成,用户在使用的过程中可选择使用它们其中的一个作为时钟,正常情况下内部R/C振荡器频率是11MHz~15.5MHz[11];
(7)16位定时器?有4个,定时器T0和T1(16位),这两个定时器与传统8051兼容。内部的独立波特率发生器可以用来做串行通讯的波特率发生器,加2路PCA模块可再实现2个16位定时器;
(8)内部具有10位高精度的ADC,有8路, 250K/S的转化率(每秒250000次);
5.1.2 STC12C5A60S2芯片引脚说明:
芯片引脚如图5.1所示。
VCC:供电电压。
GND:接地。
P0口: P0口可以作为输入/输出,也可以用来作为地址/数据复用线。当P0口作为输入/输出端口,P0是8位准双向口,内部有弱上拉电阻,没有必要接外部接上拉电阻。
P1.0/ADC0/CLKOUT2:此端口的第一功能是将P1.0用作标准I/O口使用。第二功能为ADC输入通道0。
P1.1/ADC1:此端口的第一功能是将P1.1用作标准I/O口使用。第二功能为ADC输入通道1。
P1.2/ADC2/ECI/RxD2:此端口的第一功能是作为标准I/O口使用,第二功能为ADC输入通道2,计数器的外部脉冲输入为其第三功能,第四功能为第二串口数据接收端。
P1.4/ADC4/CCP1/ :此端口的第一功能是作为标准I/O口使用,第二功能为ADC输入通道4,第三功能为SPI同步串行接口的从机选择信号端,低电平有效。
P1.6/ADC6/MOS0:此端口的第一功能是作为标准I/O口使用,第二功能为ADC输入通道6。
P3.1/RxD:此端口的第一功能是作为标准I/O口使用,第二功能为串口1数据接收端。
P3.2/ :此端口的第一功能是作为标准I/O口使用。第二功能为外部中断0,下降沿中断或低电平中断。
P3.3 / :此端口的第一功能是作为标准I/O口使用。第二功能为外部中断1,下降沿中断或低电平中断。
P3.4/T0/ /CLKOUT0:此端口的第一功能是作为标准I/O口使用,第二功能为定时/计数器0的外部输入,第三功能为定时器0下降沿中断。
P3.5/T1/ /CLKOUT1:此端口的第一功能是作为标准I/O口使用,第二功能为为定时/计数器1的外部输入,第三功能为定时器1下降沿中断。
图5.1 STC12C5A60S2芯片引脚
P3.6/ :此端口的第一功能是作为标准I/O口使用。第二功能为外部数据存储器写脉冲,低电平有效。
P3.7/ :此端口的第一功能是作为标准I/O口使用,第二功能为外部数据存储器读脉冲,低电平有效。
P4.1/T1/ /CLKOUT1:此端口的第一功能是作为标准I/O口使用。第二功能为定时器/计数器1的外部输入。第三功能为定时器1下降沿中断,低电平有效[12]。
5.2 DHT11简介
DHT11数字温湿度传感器内部自带有已校准的数字信号,它将温湿度传感技术和数字模块采集技术完美结合,这样保证了传感器有长期的可靠性与稳定的性能。
DHT11传感器由于是单线制串行接口,所以系统集成简单并且快捷。它具有极低的功耗、超小的体积、信号传输距离可达20米以上。就是因为这些优点使DHT11成为各种检测温湿度场合的最佳选择[13, 14]。
5.2.1 传感器性能说明
DHT11性能如表5-1所示。
表5-1 DHT11性能
5.2.2 串行接口(单线双向)
DATA是单片机和传感器之间通讯的桥梁,采用单总线数据传输格式,数据分整数部分和小数部分,详细过程在下面阐述。
完整传输一次数据需要40位,前8位为湿度整数部分,后8位为湿度小数部分,紧接着后面分别是8位温度整数部分、温度小数部分和校验和。以高位先出的方式进行传输。数据传输的正确与否用校验和来确定,如果数据传送正确则校验和等于前32位数据相加所得结果的末8位[15]。
单片机的初始状态为高电平,当被拉低时发送一次开始采集信号,传感器由下降沿跳转到到上升沿,接下来主机跳转到上升沿为了控制传感器的延时,等待主机再次跳变成下降沿的时候开始信号结束,此时传感器的上升沿跳转到下降沿作为响应信号发送给主机,最后传感器送出40位的数据,与此同时再触发下一次的信号采集。
通讯过程如图5.2所示。
图5.2 通讯过程图
在正常情况下主机是被拉高的,在工作的过程中会被拉低,为了能让传传感器能检测到主机的开始信号主机被拉低的时间必须大于18毫秒。开始信号被传感器接受到主机开始信号结束,传感器要发送的响应信号不能小于80微秒。接下来再延时30微妙左右后单片机开始读取传感器的响应信号。当检测出的结果表明总线是低电平时,就表明传感器发送了响应信号,为了做好发送数据的准备,这时要把总线再拉高80微秒。数据位是0或1取决于高电平的长度。传送完最后一位数据后,总线被拉高50微秒。数字0和1信号的表示方法如图5.3、5.4所示。
图5.3 数字0
图5.4 数字1信号
5.3 LCD简介
根据设计要求需要实时显示6个参数,包括室内空气中有毒有害气体的浓度值和上限值以及室内温湿度的测量值和上限值,故选用2行16个字符的LCD1602作为显示模块就可以满足显示要求。
5.3.1 LCD1602的基本参数及引脚功能
1602LCD主要技术参数[16]:
显示容量:16x2个字符芯片;
工作电压:4.5V—5.5V;
工作电流:2.0Ma(5V);
模块最佳工作电压:5.0V;
引脚功能说明[17]:
第1脚:VSS为地电源。
第2脚:VDD接+5V正电源。
第3脚:VL为1602的对比度调整端,接正电源则对比度最弱,接地则对比度最高,如果对比度过高则会产生“鬼影”现象,如果要调节合适的对比度可以使用一个10K的电位器进行调整。
第4脚:RS为寄存器选择,如果为高电平则为数据寄存器,如果为低电平则为指令寄存器。
第5脚:R/W为读写信号线,高电平为读操作,低电平为写操作。如果RS为低电平并且R/W也为低电平时则表示写入指令,如果RS为低电平但是R/W为高电平时则为读忙信号,如果RS为高电平但是R/W为低电平时则写入数据。
第6脚:E端为使能端。
第7~14脚:D0~D7为八位双向数据线。
第15脚:背光源正极。
第16脚:背光源负极。
5.3.2 LCD1602的指令说明及时序
1602液晶模块内部有11条指令用来控制它的工作方式,具体说明如表5-2所示。
指令1:清显示的指令代码为01H。
指令2:光标复位,如果设置光标复位则光标返回到地址00H。
指令3:光标模式和显示模式的设置
I/D:决定光标移动的方向,如果为高电平则右移,如果为低电平则左移。
S:液晶显示屏幕上所有的文字是否左移或者右移。高电平表示此功能有效,低电平表示此功能无效。
指令4:显示开关控制
D:液晶显示的开与关由此位控制,如果为高电平则开显示,如果为低电平则关显示。
C:光标的开与关由此位控制,如果为高电平则有光标,如果为低电平则无光标。B:光标是否闪烁由此位控制,如果为高电平则闪烁,如果为低电平则不闪烁。
指令5:光标或显示移位
S/C:如果为高电平则移动显示的文字,如果为低电平则移动光标。
指令6:功能设置命令
DL:如果为高电平则设定成4位总线,如果为低电平则设置成8位总线。
N:如果为低电平则单行显示,如果为高电平则双行显示。
F: 低电平为5x7的点阵字符,高电平为5x10的点阵字符。
指令7:设置字符发生存储器地址。
指令8:DDRAM地址设置。
指令9:读忙信号和光标地址
BF:是忙标志位,如果为高电平则忙,这时不能接收命令或者数据,如果为低电平则不忙,此时正常接收命令或数据。
指令10:写数据。
指令11:读数据。
表5-2 控制指令
序号 指令 RS R/W D7 D6 D5 D4 D3 D2 D1 D0
1 清显示 0 0 0 0 0 0 0 0 0 1
2 光标返回 0 0 0 0 0 0 0 0 1 *
3 置输入模式 0 0 0 0 0 0 0 1 I/D S
4 显示开/关控制 0 0 0 0 0 0 1 D C B
5 光标或字符移位 0 0 0 0 0 1 S/C R/L * *
6 置功能 0 0 0 0 1 DL N F * *
8 置数据存贮器地址 0 0 1 显示数据存贮器地址
9 读忙标志或地址 0 1 BF 计数器地址
10 写数到CGRAM或DDRAM 1 0 要写的数据内容
11 从CGRAM或DDRAM读数 1 1 读出的数据内容
5.3.3 1602LCD的RAM地址映射及标准字库表
输入显示字符的地址是显示字符的前提条件,通过指令确定特定的字符在屏幕的哪个位置显示[18]。图5.5是1602的内部显示地址。
从图5.5可知,第二行第一个字符的地址是40H,但是在此地址写入数据时不能直接将数据写入40H,应该在其地址前面加80H。
液晶模块的初始化里首先要根据设计所需设置其显示模式,如果没有做特定的设置,一般液晶模块显示光标都是向右移的[19]。
图5.5 1602LCD内部显示地址
6 软件设计
6.1 编程语言的选择
系统硬件电路被确定以后,接下来要用软件来实现相应的功能。对同一个硬件电路,如果烧进去不同的程序,它所能实现的功能也是不同的。
目前支持单片机的编程语言有好几种,其中应用比较广泛的是C语言和汇编语言,汇编语言编的实时性仅次于机器语言,它可以直接控制硬件的工作状态,但可移植性弱[21]。C语言在国内和国外都被广泛的使用,属于高级语言。C语言功能丰富,具有高级语言可移植性强和低级语言执行效率高的优点[22, 23]。结合本系统的设计要求和特点,这里选用了效率高、功能强大的C语言。
6.2 软件功能需求
室内空气质量监测系统的软件主要由温湿度传感器以及空气质量传感器采集模块、人机接口模块、声光报警模块、核心控制器模块构成,各模块功能概述如表6-1所示。
表6-1 功能概述
功能模块 功能描述
温湿传感器采集模块 对室内温湿度监测点进行实时监测
声光报警模块 如果有参数超限则进行声光报警
核心控制器模块 1.系统时序分配 2.人机接口控制 3.各模块协调工作 4.AD转换
人机接口模块 1.按键控制 2.动态信息显示
由软件设计实现的功能要求,可以采取以下措施:
1、程序模块化。软件设计中包含有主程序模块、DHT11传感器检测函数、MQ135传感器检测函数、显示模块、声光报警模块、按键函数。
2、软件设计采用C语言编程。
3、为了提高可靠性,进行软件抗干扰。
6.3 软件模块设计
6.3.1主程序模块
主程序运行流程图如图6.1所示。由主程序流程图可以看出,软件要实现的主要功能是温湿度传感器和空气质量传感器对数据采集,然后将数据传输到单片机中,单片机对采集的数据进行计算、分析,如果正常则在液晶上实时显示测量值,如果不正常则进行显示及声光报警。程序开始后,要对单片机中的AD进行初始化、1602液晶初始化,然后调用显示函数、关闭蜂鸣器和发光二级管。完成初始化后直接进入大循环,先对键盘进行扫描,然后传感器采集数据,经单片机进行模数转换后,进行当前参数的正确显示。
主程序代码如下:
/**********主函数******************/
void main()
{
init_ADC(); //A/D模块初始化
lcd_init(); //调用液晶初始化函数
display1(); //调用显示函数
speak=1;
led_r=1;
led_g=1;
led_y1=1;
led_y2=1;
while(1)
{
key(); //调用键盘扫描函数
if(flog4==0)
{
pro_value(); //处理读到的温湿度数据
pos_AD(); //处理读到的空气浓度数据
baojing(); //调用报警函数
delay_1ms(500);
}
}
}
图6.1 主程序流程图
6.3.2 DHT11传感器检测函数
本设计中要对室内空气的湿度温度进行实时监测,选用DHT11温湿度复合传感器,由于它直接输出数字量,所以可以将它的输出端直接连接到单片机P1.5端口。单片机实时读取温湿度传感器中的数据,并且对其进行处理,如果采集的值大于设定的阈值则进行声光报警并且显示,否则正常采集。流程如图6.2所示。
图6.2 DHT11的数据采集、判断流程图
具体代码如下:
/*****************温湿度传感器DHT11 读一个字节函数******************/
uchar read_byte()
{
uchar value,i;
for(i=0;i<8;i++) //一个字节有八位,所以用for循环
{
value=value<<1; //从字节高位开始读 ,所以需要移位操作
while(DHT==0);
delay30us();
if(DHT) //判断读到是“1”还是“0”
{
value=value|0x01; //如果是“1” 则value的值就要加1
while(DHT!=0) //等待这一位数据结束,因70us的高电平表示“1”
{
DHT=1;
}
}
}
return value; //返回读到的这一字节数据
}
/*****************温湿度传感器DHT11 读数据函数******************/
/******一个完整的数据一共是五个字节******************/
void read_value()
{
uchar i;
DHT=0;
delay_1ms(240);
DHT=1;
delay40us();
if(DHT==0)
{
while(DHT!=1);
DHT=1;
while(DHT==1);
for(i=0;i<5;i++)
{
read_data[i]=read_byte(); //将读到的五个字节数据放到数组read_data[5]中
}
}
}
/**********处理读到的温湿度数据******************/
void pro_value()
{
uint temp;
read_value();
temp=read_data[0]+read_data[1]+read_data[2]+read_data[3];
if(read_data[4]==temp) //检测读到的数据是否正确
{
shiZ=read_data[0]; //湿度整数部分
wenZ=read_data[2]-5; // 温度整数部分
}
tate[0]=wenZ/10; //将温湿度的整数部分的十位和个位分开
tate[1]=wenZ%10; //分开后的数据存放在数组tate[4]中以供lcd显示
tate[2]=shiZ/10;
tate[3]=shiZ%10;
write_1602com(yh+9);
for(a=0;a<2;a++)
{
write_1602dat(tate[a]+0x30);
}
write_1602com(yh+14);
for(a=2;a<4;a++)
{
write_1602dat(tate[a]+0x30);
}
}
6.3.3 MQ135传感器检测函数
MQ135的输出端连接到单片机的P1.6端口。由于MQ135内部没有模数转换器,所以需要单片机对其采集的数据进行模数转换,在单片机内部进行校正,将电压值转换为气体浓度值。如果超过阈值则进行声光报警并且显示,否则继续采集。流程图如图6.3所示。
图6.3 MQ135数据采集、判断流程图
具体代码如下:
/********** 模数转换初始换函数******************/
void init_ADC()
{
P1_ADC_EN=0x40;
ADC_DATA=0;
ADC_LOW2=0;
ADC_CONTR=ADC_SPEEDLL|ADC_POWER;
delay_1ms(20);
}
/********** 模数转换函数******************/
uint ADC(uchar num) //参数num用于指定是哪个模拟量转换
{
ADC_CONTR=ADC_POWER|ADC_SPEEDLL|num|ADC_START;
_nop_();_nop_();_nop_();_nop_();
while(!(ADC_CONTR&ADC_FLAG));
ADC_CONTR&=~ADC_FLAG;
ad_value=ADC_DATA*4+ADC_LOW2; //转换的结果是十位的,高八位放在ADC_DATA中,低两位放在ADC_LOW2中
return ad_value; // 将转换后的数字量返回
}
/********** 模数转换后数据处理函数******************/
void pos_AD()
{
AN_value=ADC(6); // 将采集到的气体的浓度值经AD转换,接着把转换后的数字量结果赋给AN_value
delay_1ms(5);
/***对转换后的数字量进行矫正***/
if(AN_value>850)
{
AN_value=850;
}
NH4_value=(850-AN_value)*0.9765625;
y_data[0]=NH4_value/1000; //将气体浓度值的个位、十位、 百位、 千位分开显示
y_data[1]=(NH4_value%1000)/100;
y_data[2]=(NH4_value%100)/10;
y_data[3]=NH4_value%10;
write_1602com(yh+2);
for(a=0;a<4;a++)
{
write_1602dat(y_data[a]+0x30);
}
}
6.3.4 显示模块
1602液晶显示器和CPU的通信方式为并口通信,液晶的RS(寄存器选择端)、RW(读写端)和EN(使能端)由单片机的P2.6、P2.5和P2.4端口控制。单片机的P0口用来给1602传输数据,并且进行显示。
在系统上电后,LCD进行初始化,首先按照资料中的时序给定显示字符的地址,然后传送数据到相应位置。上电后液晶显示屏显示3个参数的测量值和上限值。
代码如下:
//****液晶写入指令函数****//
void write_1602com(uchar com)
{
rs=0; //数据/指令选择置为指令
rw=0;
P0=com; //送入数据
delay_1ms(12);
en=1; //拉高使能端,为制造有效的下降沿做准备
delay_1ms(12);
en=0; //使能端由高变低,产生下降沿,液晶执行命令
}
//***液晶写入数据函数****//
void write_1602dat(uchar dat)
{
rs=1; //数据/指令选择置为数据
rw=0;
P0=dat; //送入数据
delay_1ms(12);
en=1; //使能端置高电平,为制造下降沿做准备
delay_1ms(12);
en=0; //en由高变低,产生下降沿,液晶执行命令
}
//***液晶初始化函数****//
void lcd_init()
{
write_1602com(0x38); //设置液晶工作模式, 16*2行显示,5*7点阵,8位数据
write_1602com(0x0c); //开显示不显示光标
write_1602com(0x06); //整屏不移动,光标自动右移
write_1602com(0x01); //清显示
write_1602com(yh+0); //日历显示固定符号从第一行第1个位置之后开始显示
for(a=0;a<16;a++)
{
write_1602dat(tab1[a]); //向液晶屏写显示的固定符号部分
}
write_1602com(er+0); //时间显示固定符号写入位置,从第2个位置后开始显示
for(a=0;a<14;a++)
{
write_1602dat(tab2[a]);//写显示时间固定符号,两个冒号
}
}
6.3.5 声光报警模块
本系统的报警器是由蜂鸣器、3个绿色、3个红色、还有2个黄色发光二级管组成。当温湿度和有毒有害气体没超标时3个绿灯亮。温度超标时,绿灯灭,黄灯亮,并且蜂鸣器响。湿度超标时绿灯灭,黄灯亮,并且蜂鸣器响。有毒有害气体超标时,绿灯灭,3个红灯亮,并且蜂鸣器响。分别对温度、湿度、气体浓度值设定上限,并且将其存放在3个变量中,空气质量传感器采集到的数据经AD转换,在单片机内部进行处理,如果大于报警阈值则进行声光报警,小于阈值则执行显示程序。
具体代码如下:
void baojing()
{
if((NH4_value>set_Q)||(shiZ>set_H)||(wenZ>set_T))//判断是否超限
{
speak=0;
if((NH4_value>set_Q))
{
led_g=1;
led_r=0;
}
else
{
led_g=0;
led_r=1;
}
if((shiZ>set_H))
{
led_y1=0;
}
else
{
led_y1=1;
}
if(wenZ>set_T)
{
led_y2=0;
}
else
{
led_y2=1;
}
}
else
{
speak=1;
led_g=0;
led_r=1;
led_y2=1;
led_y1=1;
}
6.3.6 按键模块
本设计中按键主要用来调整各参数的上限值,并且还可以手动的进行切换。由于按键实现的功能很少以及为了节约单片机引脚数量所以决定用3个独立式按键即可,其中设定键用于选择是对温湿度还是气体浓度上限值的调整,根据设定键按下的次数决定调整的对象,当第一次按下则可以对气体浓度的上限值进行调整。第二次按下可以对温度的上限值进行调整。第三次按下可以调整湿度的上限值。第四次按下退出。上下键可以调整上限值的大小,当按上键时,上限值加1,按下键时,上限值减1。
具体代码如下:
void key()
{
if(set_key==0)
{
delay_1ms(5);
if(set_key==0) //按下消抖
{
flog4=flog4+1;
if(flog4>3)
{
flog4=0;
}
while(set_key==0); //松开消抖
}
}
if(flog4==1) //设定键第一次被按下
{
if(add_key==0)
{
delay_1ms(5);
if(add_key==0)
{
set_Q=set_Q+1; //气体浓度上限值加1
while(add_key==0);
if(set_Q>5000)
{
set_Q=5000;
}
}
}
if(cut_key==0)
{
delay_1ms(5);
if(cut_key==0)
{
set_Q=set_Q-1;
while(cut_key==0);
if(set_Q<=0)
{
set_Q=0;
}
}
}
display1();
}
if(flog4==2) //设定键第二次被按下
{
if(add_key==0)
{
delay_1ms(5);
if(add_key==0)
{
set_T=set_T+1; //温度的上限加1
while(add_key==0);
if(set_T>99)
{
set_T=99;
}
}
}
if(cut_key==0)
{
delay_1ms(5);
if(cut_key==0)
{
set_T=set_T-1;
while(cut_key==0);
if(set_T<=0)
{
set_T=0;
}
}
}
display1();
}
if(flog4==3)
{
if(add_key==0)
{
delay_1ms(5);
if(add_key==0)
{
set_H=set_H+1;
while(add_key==0);
if(set_H>99)
{
set_H=99;
}
}
}
if(cut_key==0)
{
delay_1ms(5);
if(cut_key==0)
{
set_H=set_H-1;
while(cut_key==0);
if(set_H<=0)
{
set_H=0;
}
}
}
display1();
}
}
7 仿真调试
7.1系统软件调试
程序编写完成之后,利用Keil C51仿真软件进行仿真运行调试,最后软件调试结果为0警告、0错误,可见程序是可行的。其调试界面如图7.1所示。
图7.1 软件调试
在使用仿真软件进行具体的调试过程中,遇到了很多问题。首先是在新建工程时芯片的选择,因为Keil内部没有STC12C5A60S2型号芯片,不知道该选用哪款合适,通过网上查找资料,了解到可以选用STC89C52芯片代替,但是必须在程序中说明STC12C5A60S2中寄存器的地址,所以本设计选择了STC89C52芯片,通过查找芯片资料,在程序的开头对寄存器地址做了说明。在对程序第一次调试的过程中遇到了很多问题,例如目标工程没有生成、变量没有定义、注释符错误等都影响到了调试结果,经过对代码一句句的修改,一次次的编译,最终将程序中的错误全部剔除。程序写好后,通过Keil C51的调试窗口输入各个寄存器和变量的名称可以看到寄存器和变量的变化是否与要求的一致,在调试过程中在错误的地方不断地调整修改,最后使系统实现预定功能[24]。
程序的正确性可以用单步运行和断点运行调试,但是延时模块的定时精度和CPU的实时响应等问题运用单步和断点运行时不能检测到的,所以必须进行连续调试。这些工作全部完成后,经过反复运行调试多次,必要时作适当的修正。
7.2功能调试
为了检验程序的正确性,我们焊接了实物。检查焊接质量没问题,无短路、虚焊等故障后将电源开关打开,如果程序正确则液晶屏上应该在第一行上从左到右显示温度、湿度和有毒有害气体的浓度值。第二行分别显示它们的上限。当将热水袋放到温湿度传感器上时,液晶屏上的温度值会增加,当高过设定的上限时,蜂鸣器响、绿灯灭、黄灯亮。过按设定键和上下键可以调整上限值。当室内湿度上升时,液晶屏上湿度值也会上升,当高过设定值则蜂鸣器响、绿灯灭、黄灯亮。通过按设定键和上下键可以调整上限值。当将打火机(打火机内部气体为丁烷,也是室内有毒有害气体之一)靠近空气质量传感器时,液晶屏上的气体浓度值会变。当高过设定的上限时,蜂鸣器响、绿灯灭、红灯亮。同理,也可以用三个独立键盘改变其上限。设定键第一次按下,可以调整气体浓度的上限,第二次按下可以调整温度上限,第三次按下可以调整湿度上限,第四次按下恢复正常。
在设计的过程中遇到了很多问题。比如第一次将程序烧入单片机中,然后将开关打开,液晶的第一行和第二行什么都不显示。当时以为是液晶对比度太低或太高,所以就用螺丝刀旋转液晶的电位器,可是旋转到底还是没有字符显示。接着又开始在软件中找问题,发现在为第一行分配地址时没有在其前面加80H,所以决定在程序的宏定义处定义一个变量yh为80H作为第一行起始地址,后面要显示字符的地址只要以yh为基础再加上它在第一行的位置即可。改完以后,通过运行,第一行显示正常,但是第二行还是没有任何显示,看过程序后发现犯了和第一行一样的错误,所以又在宏定义中定义了一个变量er为80H+40H作为第二行起始地址,修改完毕经过编译没有问题,然后将程序下载到单片机中运行,第二行显示正常。当我按独立建想要对各测量值进行上限调整时又出现了问题,调整上限值时经常会出现偏差,例如前几次按下加键后液晶上的上限值就会每次加1,但是后面几次按下就会出现加2或4的情况,减键也是一样,通过反复查看程序以及看单片机视频发现了其中的错误,在程序编写中没有进行消抖处理,所以我在软件中通过延时再判断指令对每个按键进行了消抖处理,程序修改完毕编译成功后,将其下到单片机中并且重新启动后按键恢复正常。在对其功能调试的过程中还有很多错误,经过一步步的验证,最后都得到了解决。
结 论
本系统同时用到了传感器技术,自动监测技术,和微控制器技术,研发了一套对室内空气质量进行实时监控的自动监测系统。系统硬件的设计非常简单但是很合理,系统的软件采用的是模块化的程序设计方法,软件中各模块是相互独立的,这样保证了系统的可靠性和可扩展性,具有较高的性价比。本监测仪显示界面非常简洁明了,只要打开电源,操作者就可以实时看到所处位置的温度、湿度、以及有毒有害气体浓度,如果室内有毒有害浓度超标,会进行声光报警,这样可以提醒操作者采取相应措施。键盘设置各参数上限值,这样可以为不同的用户提供一定的选择,根据场合的不同,各参数的上限值也不同。该系统已运行测试,运行结果表明该系统具有响应速度快,操作简单,工作可靠等优点。
本设计由于时间和知识的局限,仍存在许多不足。在今后的发展中,该系统可设计为多机控制模式,可同时监控多个室内空气质量,通过远程通信的方式将检测结果送给计算机进行综合处理,还可以加外围设备,当某个室内空气质量不合格,可以驱动相应设备来调节室内空气,使其达到正常状态。或者可利用家庭网络与其室内其他家电相联系,这样可以将家庭中原来孤立、各不相关的设备统一起来,室内空气质量一旦不合格,各种设备都会提醒主人做好相应保护措施。
本设计在精度方面还不能满足要求,所以今后可以应引入模糊算法,专家系统等技术以进一步提高系统的精度。
致 谢
为期两个多月的毕业设计终于完成了,对我个人而言,凝聚了许多努力和汗水,也经受住了严峻的考验。和普通的课程设计不同,由于毕业设计的综合性,几乎用到所学的全部知识,而且是我第一次接触传感器的使用,对我来说这是一个全新的任务。由于基础过于薄弱,专业知识有限,浮躁的心理让我一开始举步维艰,满脑子想的就是放弃。在心理最为脆弱的时候,叶老师耐心地开导我,给我鼓励和信心,毕业设计才得以步入正轨。
万事开头难,刚开始接触到这个课题,我就不知道从哪下手,因为空气中的物质实在是太多了,根本找不到特定的传感器可以使用。所以我就经常跑图书馆,向老师请教关于这方面的知识。功夫不负有心人,最后我了解到淘宝有专门卖空气质量传感器的,然后我将此传感器的资料要过来开始研究,由于此传感器输出模拟量,而我刚开始准备的单片机是51系列,此单片机内部不含有AD转换器,所以我认为需要再加一个A/D转换器,但是到后来从老师那里了解到STC12C5A60S2单片机自身是带AD转换器的,这样就可以免去硬件的设计。它和51系列单片机在很多方面都很相似,所以很容易上手。搜集到所有的硬件以后我就开始学习编程,叶老师向我介绍了郭天祥的《10天学会单片机》,我用了两周时间将它消化。此视频上讲的键盘扫描和LCD的读写、显示对我非常有帮助,我在自己的程序中也引用了他的编程思路。
从研究课题,搜集材料,到正式投入设计,我花费了很多时间和精力。对于这次全新的设计,叶老师给了我很大的自由空间,可以充分发挥自己的创造思维。但是,对于很多新的尝试,通过编程都没没能实现,每当这个时候烦躁焦虑接踵而来,让我迷失了方向。又是叶老师在最繁忙的时候,对我的设计加以开导,让我茅塞顿开,使设计得以延续直至顺利完成。所以,在这次毕业设计中,我很感谢的叶小婷老师。同时我也很感谢我的合作伙伴陆傲,没有他对电路图缜密的设计,我的软件业很难实现。
最后也要谢谢系里的领导和代课老师,他们在我大学最迷茫的时候不断的鼓励我,在他们的引导下,我对自己所学的专业有了更深的了解,使得我在学习中不再那么枯燥。
参 考 文 献
1. 粱红玉.环境监测.武汉理工大学出版社,2003
2. 周中平、赵寿堂、朱立.室内空气污染监测与控制.北京:化学工业出版社,2002
3. 毛谦敏主编.单片机原理及应用系统设计.国防工业出版社.2005.08
4. 刘大茂编著.智能仪器(单片机应用系统设计).机械工业出版社.1998
5. 孙传友等编著.测控系统原理与设计.北京航空航天大学出版社.2002.9
6. 宋文绪,杨帆.传感器与检测技术.高等教育出版社.2009.11
7. 吕俊芳.传感器接口与检测仪器电路.北京航空航天大学出版.1994.5
8. 张琳娜.刘武发.传感检测技术及应用.中国计量出版社.1999:26-29
9. 何希才,虹敏.传感器应用接口电路.机械工业出版社.1997,112
10. 张阳,吴晔,滕勤等编著.单片机原理及嵌入式系统开发.电子工业出版社.2011
11. V.Yu.Teplov,A.V.Anisimov.Thermostatting System Using a Single-Chip Microcomputer and Thermoelectric Modules Based on the Peltier Effect[J] ,2002
12. 张齐..单片机应用系统----基于C语言编程.北京:电子工业出版社,2004
13. Milos D.Ercegovac ,Tomas-Lang,Jaime H.Moreno.Introduction To digital System.JohnWiley Son,1989
14. 张冬林,李鑫,戴梅.基于DHT11的低成本蚕室温湿度自动控制系统设计[J].现代农业科技,2010,(18):14-15
15. 王静.通用库房温湿度测控系统[D] .中国海洋大学,2009
16. 何立民.单片机与嵌入式系统应用.北京航空航天出版社,2003
17. 杨恢先等编著.单片机原理及应用.国防工业出版社.2003.3
18. Stephen G Kochan 著.Programming in ANSI C.Hagden Books Indianapolis:Indiana,U.S.A,1994
19. 李建忠.单片机原理及应用.西安:西安电子科技大学出版社,2002
20. 王柏盛,李万庆,贺洪江.C程序设计.高等教育出版社.2005.1
21. 姜桂洪,谷亚鹏,刘秋香,王军.C程序设计教程.清华大学出版社.2008.2
22. 赵文博,刘文涛,张伟.单片机语言C51程序设计.人民邮电出版社.2006.3
23. Zhang G X,Fan Y M,Gao X,et al.A Confocal Probe based on Time Difference Measurement[J] .2004,Annals of the CIRP,53 (1),417-420
24. 魏东.KeilC51总线外设操作问题的深入分析.单片机与嵌入式系统应用.2006.2
附录1:完整代码
/*头文件*/
#include
#include
/*AD寄存器定义*/ //由于keil中没有此单片机,所以头文件必须自己设置
sfr ADC_CONTR=0xBC;
sfr ADC_DATA=0xBD;
sfr ADC_LOW2=0xBE;
sfr P1_ADC_EN=0x9D;
sfr P4=0xC0;
/*****************宏定义******************/
#define uint unsigned int
#define uchar unsigned char
#define yh 0x80 //LCD第一行的初始位置
#define er 0x80+0x40 //LCD第二行初始位置
#define ADC_POWER 0x80
#define ADC_FLAG 0x10
#define ADC_START 0x08
#define ADC_SPEEDHH 0x00
#define ADC_SPEEDH 0x20
#define ADC_SPEEDL 0x40
#define ADC_SPEEDLL 0x60
uint ad_value,NH4_value;
float AN_value;
/***********位操作端口定义**************/
sbit set_key=P1^2; //“设置”键 K1
sbit add_key=P1^3; //“加”键 K2
sbit cut_key=P1^4; //“减”键 K3
sbit speak=P3^7; // 蜂鸣器
sbit led_g=P2^0; // 继电器
sbit led_r=P2^1; // 继电器
sbit led_y1=P2^2; // 继电器
sbit led_y2=P2^3; // 继电器
sbit rs=P2^6;
sbit en=P2^4;
sbit rw=P2^5;
sbit DHT=P1^5; //温湿度传感器数据线
uchar flog4;
uchar a;
unsigned char shiZ,wenZ,check;
uchar code tab1[]={"Q: -T: -H: "}; //测量值显示的固定字符
uchar code tab2[]={"set: - - "};//报警值显示的固定字符
uchar y_data[4]={0,0,0,0};
uchar Set_data[8]={0,0,0,0,0,0,0,0};
uchar tate[4];
uchar read_data[5];
uint set_Q=50;//气体报警值
uint set_T=40;//温度报警值
uint set_H=60;//湿度报警值
void delay30us() //误差 -0.070167824074us
{
unsigned char a;
for(a=164;a>0;a--);
}
void delay40us() //误差 -0.033275462963us
{
unsigned char a,b;
for(b=1;b>0;b--)
for(a=218;a>0;a--);
}
void delay_1ms(uint xms)//延时函数,有参函数
{
uint x,y;
for(x=xms;x>0;x--)
for(y=124;y>0;y--);
}
void data_pro() //数据处理函数
{
Set_data[0]=set_Q/1000; //千位
Set_data[1]=(set_Q%1000)/100;//百位
Set_data[2]=(set_Q%100)/10;//十
Set_data[3]=set_Q%10;//个
Set_data[4]=set_T/10;
Set_data[5]=set_T%10;
Set_data[6]=set_H/10;
Set_data[7]=set_H%10;
}
//****液晶写入指令函数****//
void write_1602com(uchar com)
{
rs=0;//数据/指令选择置为指令
rw=0;//写
P0=com;//送入数据
delay_1ms(12);
en=1;//拉高使能端,为制造有效的下降沿做准备
delay_1ms(12);
en=0;//en由高变低,产生下降沿,液晶执行命令
}
//***液晶写入数据函数****//
void write_1602dat(uchar dat)
{
rs=1;//数据/指令选择置为数据
rw=0;//写
P0=dat;//送入数据
delay_1ms(12);
en=1; //en置高电平,为制造下降沿做准备
delay_1ms(12);
en=0; //en由高变低,产生下降沿,液晶执行命令
}
//***液晶初始化函数****//
void lcd_init()
{
write_1602com(0x38);//设置液晶工作模式,意思:16*2行显示,5*7点阵,8位数据
write_1602com(0x0c);//开显示,不显示光标
write_1602com(0x06);//整屏不移动,光标自动右移
write_1602com(0x01);//清显示
write_1602com(yh+0);//日历显示固定符号从第一行第1个位置之后开始显示
for(a=0;a<16;a++)
{
write_1602dat(tab1[a]);//向液晶屏写显示的固定符号部分
}
write_1602com(er+0);//时间显示固定符号写入位置,从第2个位置后开始显示
for(a=0;a<14;a++)
{
write_1602dat(tab2[a]);//写显示时间固定符号,两个冒号
}
}
/********** 模数转换初始换函数******************/
void init_ADC()
{
P1_ADC_EN=0x40;
ADC_DATA=0;
ADC_LOW2=0;
ADC_CONTR=ADC_SPEEDLL|ADC_POWER;//按位或
delay_1ms(20);
}
/********** 模数转换函数******************/
uint ADC(uchar num) //参数num用于指定是哪个模拟量转换
{
ADC_CONTR=ADC_POWER|ADC_SPEEDLL|num|ADC_START;
_nop_();_nop_();_nop_();_nop_();
while(!(ADC_CONTR&ADC_FLAG));
ADC_CONTR&=~ADC_FLAG;
ad_value=ADC_DATA*4+ADC_LOW2; //转换的结果是十位的 高八位放在ADC_DATA中 低两位放在ADC_LOW2
return ad_value; // 将转换后的数字量返回
}
/********** 模数转换后数据处理函数******************/
void pos_AD()
{
AN_value=ADC(6); //通过模数转换得到的电压值,把转换后的数字量结果赋给AN_value
delay_1ms(5);
// /***对转换后的数字量进行矫正***/
if(AN_value>850)
{
AN_value=850;
}
NH4_value=(850-AN_value)*0.9765625;
y_data[0]=NH4_value/1000; //将气体浓度值的个位 十位 百位 千位 分开 用于显示
y_data[1]=(NH4_value%1000)/100;
y_data[2]=(NH4_value%100)/10;
y_data[3]=NH4_value%10;
write_1602com(yh+2);
for(a=0;a<4;a++)
{
write_1602dat(y_data[a]+0x30);
}
}
/*****************温湿度传感器DHT11 读一个字节函数******************/
uchar read_byte()
{
uchar value,i;
for(i=0;i<8;i++) //一个字节有八位 所以用for循环
{
value=value<<1; //从字节高位开始读 需要移位
while(DHT==0);
delay30us();
if(DHT) //判断读到是“1”还是“0”
{
value=value|0x01; //如果是“1” value的值就要加一
while(DHT!=0) //等待这一位数据结束 因为70us的高电平表示“1”
{ //
DHT=1;
}
}
}
return value; //返回读到的这一字节数据
}
/*****************温湿度传感器DHT11 读数据函数******************/
/**一个完整的数据一共是五个字节******************/
void read_value()
{
uchar i;
DHT=0;
delay_1ms(240);
DHT=1;
delay40us();
if(DHT==0)
{
while(DHT!=1);
DHT=1;
while(DHT==1);
for(i=0;i<5;i++)
{
read_data[i]=read_byte();//将读到的五个字节数据放到数组read_data[5]中
}
}
}
/**********处理读到的温湿度数据******************/
void pro_value()
{
uint temp;
read_value();
temp=read_data[0]+read_data[1]+read_data[2]+read_data[3];
if(read_data[4]==temp) //检测读到的数据是否正确
{
shiZ=read_data[0]; //湿度整数部分
wenZ=read_data[2]-5; // 温度整数部分
}
tate[0]=wenZ/10; //将温湿度的整数部分的十位和个位分开
tate[1]=wenZ%10; //分开后的数据存放在数组tate[4]中 以供lcd显示
tate[2]=shiZ/10;
tate[3]=shiZ%10;
write_1602com(yh+9);
for(a=0;a<2;a++)
{
write_1602dat(tate[a]+0x30);
}
write_1602com(yh+14);
for(a=2;a<4;a++)
{
write_1602dat(tate[a]+0x30);
}
}
void baojing()
{
if((NH4_value>set_Q)||(shiZ>set_H)||(wenZ>set_T))
{
speak=0;
if((NH4_value>set_Q))
{
led_g=1;
led_r=0;
}
else
{
led_g=0;
led_r=1;
}
if((shiZ>set_H))
{
led_y1=0;
}
else
{
led_y1=1;
}
if(wenZ>set_T)
{
led_y2=0;
}
else
{
led_y2=1;
}
}
else
{
speak=1;
led_g=0;
led_r=1;
led_y2=1;
led_y1=1;
}
}
/**********显示函数******************/
void display1() //报警值显示
{
data_pro(); 数据处理函数
write_1602com(er+4);
for(a=0;a<4;a++)
{
write_1602dat(Set_data[a]+0x30);
}
write_1602com(er+9);
for(a=4;a<6;a++)
{
write_1602dat(Set_data[a]+0x30);
}
write_1602com(er+12);
for(a=6;a<8;a++)
{
write_1602dat(Set_data[a]+0x30);
}
}
void key() //键盘扫描
{
if(set_key==0)
{
delay_1ms(5);
if(set_key==0) //消抖
{
flog4=flog4+1;
if(flog4>3)
{
flog4=0;
}
while(set_key==0);
}
}
if(flog4==1)
{
if(add_key==0)
{
delay_1ms(5);
if(add_key==0)
{
set_Q=set_Q+1;
while(add_key==0);
if(set_Q>5000)
{
set_Q=5000;
}
}
}
if(cut_key==0)
{
delay_1ms(5);
if(cut_key==0)
{
set_Q=set_Q-1;
while(cut_key==0);
if(set_Q<=0)
{
set_Q=0;
}
}
}
display1();
}
if(flog4==2)
{
if(add_key==0)
{
delay_1ms(5);
if(add_key==0)
{
set_T=set_T+1;
while(add_key==0);
if(set_T>99)
{
set_T=99;
}
}
}
if(cut_key==0)
{
delay_1ms(5);
if(cut_key==0)
{
set_T=set_T-1;
while(cut_key==0);
if(set_T<=0)
{
set_T=0;
}
}
}
display1();
}
if(flog4==3)
{
if(add_key==0)
{
delay_1ms(5);
if(add_key==0)
{
set_H=set_H+1;
while(add_key==0);
if(set_H>99)
{
set_H=99;
}
}
}
if(cut_key==0)
{
delay_1ms(5);
if(cut_key==0)
{
set_H=set_H-1;
while(cut_key==0);
if(set_H<=0)
{
set_H=0;
}
}
}
display1();
}
}
/**********主函数******************/
void main()
{
init_ADC();AD初始化
lcd_init(); //调用液晶屏初始化子函数
display1();显示函数
speak=1;
led_r=1;
led_g=1;
led_y1=1;
led_y2=1;
while(1)
{
key();键盘扫描
if(flog4==0)
{
pro_value();
pos_AD();
baojing();
delay_1ms(500);
}
}
}
 *查看完整论文请+Q: 351916072 
关键字:
目 录

版权保护: 本文由 hbsrm.com编辑,转载请保留链接: www.hbsrm.com/jxgc/jdgc/2010.html

好棒文