为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

湿度传感器设计

2018-05-11 5页 doc 279KB 14阅读

用户头像 个人认证

飞哥

暂无简介

举报
湿度传感器设计摘要生活上,合适的空气湿度有益于人们的身体健康;工业上,芯片的封装,设备的维护以及工厂的装配等,都需要在合适的湿度下进行。该课题对空气的湿度进行研究,采用单片机和湿度模块组成的湿度控制系统,对环境的湿度进行数据采集、处理。系统通过测量当前环境的绝对湿度,及时、精确地了解空气湿度的变化,并将当时绝对湿度值与预设的上下限值进行比较,如果不在合适的空气湿度范围内,系统会自动发出报警。关键词:单片机;湿度传感器;DHT11湿度传感器AbstractLife,moderateairhumidityisbeneficialtopeople...
湿度传感器设计
摘要生活上,合适的空气湿度有益于人们的身体健康;工业上,芯片的封装,设备的维护以及工厂的装配等,都需要在合适的湿度下进行。该课对空气的湿度进行研究,采用单片机和湿度模块组成的湿度控制系统,对环境的湿度进行数据采集、处理。系统通过测量当前环境的绝对湿度,及时、精确地了解空气湿度的变化,并将当时绝对湿度值与预设的上下限值进行比较,如果不在合适的空气湿度范围内,系统会自动发出报警。关键词:单片机;湿度传感器;DHT11湿度传感器AbstractLife,moderateairhumidityisbeneficialtopeople'shealth;industrial,chippackaging,equipmentmaintenanceandfactoryassembly,undertheappropriatehumidity.Thesubjectofairhumidityresearch,usesthemonolithicintegratedcircuitandthehumiditymodulesofhumiditycontrolsystem,theenvironmenthumiditydataacquisitionandprocessing.Thesystemisadoptedtomeasuretheabsolutehumidityoftheenvironment,timely,accuratelyunderstandingchangesinthehumidityoftheair,andthentheabsolutehumidityvaluewithapresetupperandlowerlimitvaluesarecompared,ifnotintherangeofsuitableairhumidity,thesystemwillalarmautomatically.Keywords:singlechipmicrocomputer;humiditysensor;DHT11humiditysensor 目录1绪论 51.1目的及意义 51.2发展状况 52系统的整体设计 52.1设计内容 52.2系统完成的技术指标 62.3系统构成与框图 62.4系统设计 73硬件设计 73.1STC89C52简介 73.2DHT11湿度检测模块 93.2.1湿度检测模块选择思路 93.2.2DHT11湿度模块 93.3液晶显示模块 103.4报警模块 113.5按键输入模块 123.6电路的排版连线设计 124软件设计 134.1总程序流程图 134.1.1温湿度DHT11程序 144.1.2LCD1602液晶程序 154.2程序设计 154.3串口通信 154.4上位机的程序设计 164.4.1面向对象的编程 164.4.2上位机图形窗口 164.4.3上位机流程 174.4.4主要程序代码 175系统调试 175.1硬件调试 175.2软件调试 17参考文献 18附录 19附录一程序 19附录二上位机程序 34附录三串口通信程序 38附录四元器件清单 41附录五硬件原理图 42附录六仿真图 43附录七PCB版图 44附录八上位机图形窗口 45 1绪论1.1目的及意义在工农业生产和日常生活中,对湿度的测量及控制始终占据着重要地位。在现代农业大棚种植或是室内畜牧业、气象、环保、国防、科研、航天以及现代生活的各个方面,经常需要对环境湿度进行测量及控制。本设计就在此基础上,设计一种基于STC89C52单片机控制的智能湿度检测系统。1.2发展状况进入21世纪后,特别在我国加入WTO后,国内产品面临巨大挑战。各行业特别是传统产业都急切需要应用电子技术、自动控制技术进行改造和提升。例如纺织行业,温湿度是影响纺织品质量的重要因素,但纺织企业对温湿度的测控手段仍很粗糙,十分落后,绝大多数仍在使用干湿球湿度计,采用人工观测,人工调节阀门、风机的方法,其控制效果可想而知。制药行业里也基本如此。而在食品行业里,则基本上凭经验,很少有人使用湿度传感器。值得一提的是,随着农业向产业化发展,许多农民意识到必需摆脱落后的传统耕作、养殖方式,采用现代科学技术来应付进口农产品的挑战,并打进国外市场。各地建立了越来越多的新型温室大棚,种植反季节蔬菜,花卉;养殖业对环境的测控也日感迫切。但目前,在湿度测试领域大部分湿敏元件性能还只能使用在通常温度环境下。在需要特殊环境下测湿的应用场合大部分国内包括许多国外湿度传感器都会“皱起眉头”!例如在上面提到纺织印染行业,食品行业,耐高温材料行业等,都需要在高温情况下测量湿度。一般情况下,印染行业在纱锭烘干中,温度能达到120摄氏度或更高温度;在食品行业中,食物的烘烤温度能达到80-200摄氏度左右;耐高温材料,如陶瓷过滤器的烘干等能达到200摄氏度以上。在这些情况下,普通的湿度传感器是很难测量的。2系统的整体设计2.1设计内容本次设计分为两个内容:硬件部分、软件部分。硬件以单片机为核心,配以湿度模块电路、键盘电路、数模转换电路、显示电路和报警电路。主要实现以下功能:(1)通过湿度模块电路对环境的湿度进行数据采集;(2)通过单片机对采集的数据进行处理;(3)当环境湿度低于或者高于设置湿度时启动报警。湿度检测系统是一个智能化的系统,它的软件主要实现功能:(1)单片机能够控制湿度模块对空气的湿度进行采样;(2)把采集的数据通过单片机处理,再以十进制的形式显示出来;(3)按键和显示电路可对设置的报警上下限值进行更改,并通过显示电路显示出来。2.2系统完成的技术指标(1)实时显示绝对湿度,系统的精度为10mg/L;(2)采用3位数码管进行湿度显示;(3)显示报警上限值为180mg/L,下限值为90mg/L;(4)湿度超过上下限湿度时进行报警;(5)数码管采用动态显示方式。2.3系统构成与框图本次设计的系统框图见图1.1所示。图1.1系统框图单片机控制湿度模块AM1001对环境的湿度进行检测并通过单片机处理用数码管显示出来,键盘电路可设置报警的上下限值,当环境湿度高于上限或者低于下限报警值时,启动报警电路,即蜂鸣器响。2.4系统设计(1)设计之前,查找资料。先对湿度的概念进行了解,并了解一些湿度传感器的工作原理。空气湿度是指空气潮湿的程度,可用相对湿度(RH)表示。相对湿度是指空气实际所含水蒸气密度和同温下饱和水蒸气密度的百分比值。人体在室内感觉舒适的最佳相对湿度是,49%~5l%,相对湿度过低或过高,对人体都不适甚至有害。  绝对湿度是一定体积的空气中含有的水蒸气的质量,一般其单位是克/立方米。绝对湿度的最大限度是饱和状态下的最高湿度。绝对湿度只有与温度一起才有意义,因为空气中能够含有的湿度的量随温度而变化,在不同的温度中绝对湿度也不同,因为随着温度的变化空气的体积也要发生变化。但绝对湿度越靠近最高湿度,它随温度的变化就越小。(2)分析系统的主要性能;(3)对整个电路的流程进行分析;(4)硬件的准备以及焊接;(5)用c语言进行软件的编写并仿真;(6)将硬件和软件进行系统仿真直至完成设计。3硬件设计3.1STC89C52简介图1.2STC89C52本次设计所使用的单片机如图1.2所示。STC89C52是一个低电压,高性能CMOS8位单片机,片内含8kbytes的可反复擦写的Flash只读程序存储器和256bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器和Flash存储单元,功能强大的STC89C52单片机可为您提供许多较复杂系统控制应用场合。STC89C52有40个引脚,32个外部双向输入/输出(I/O)端口,同时内含2个外中断口,3个16位可编程定时计数器,2个全双工串行通信口,2个读写口线。STC89C52有PDIP、PQFP/TQFP及PLCC等三种封装形式,以适应不同产品的需求。主要功能特性 (1)兼容MCS51指令系统 (2)8k可反复擦写(>1000次)FlashROM (3)32个双向I/O口(4)256x8bit内部RAM (5)3个16位可编程定时/计数器中断(6)时钟频率0-24MHz (7)2个串行中断 (8)可编程UART串行通道 (9)2个外部中断源 (10)共8个中断源 (11)2个读写中断口线 (12)3级加密位 (13)低功耗空闲和掉电模式(14)软件设置睡眠和唤醒功能引脚简介:(1)VCC(40脚),接+5V电源正端GND(20脚),接+5V电源地端(2)XTAL1(19脚),接外部晶振的一个引脚。在单片机内部,它是一个反相放大器的输入端。当采用外部振荡器时,此引脚应接地。XTAL2(18脚),接外部晶振的另一个引脚。在片内接至反相放大器的输出端和内部时钟电路的输入端。当采用外部振荡器时,此脚接外部振荡器的输出端。(3)控制信号线RESET(9脚):复位信号输入端,复位/掉电时内部RAM的备用电源输入端。ALE(30脚):地址锁存允许/编程脉冲输入,用ALE锁存从P0口输出的低8位地址。在对片内EPROM编程时,编程脉冲由此输入。PSEN(29脚):外部程序存储器读选通信号,低电平有效。EA(31脚):访问外部存储器允许/编程电压输入。EA为高电平时,访问内部存储器;低电平时,访问外部存储器。3.2DHT11湿度检测模块图1.3DHT11湿度模块检测模块如图1.3所示。3.2.1湿度检测模块选择思路要对当前环境湿度进行检测,并且需要和单片机结合,最好便是用传感器来检测环境湿度,通过单片机进行数据处理后显示出来。传感器的选择需要精度高,而且便于单片机控制。3.2.2DHT11湿度模块本次设计使用DHT11湿度传感器。DHT11湿度模块,是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。每个DHT11传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式储存在OTP内存中,传感器内部在检测信号的处理过程中要调用这些校准系数。单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,信号传输距离可达20米以上,使其成为各类应用甚至最为苛刻的应用场合的最佳选则。引脚说明:(1)Pin1:(VDD),电源引脚,供电电压为3-5.5V。(2)Pin2:(DATA),串行数据,单总线。(3)Pin3:(NC),空脚,悬浮。(4)Pin4(VDD),接地端,电源负极。3.3液晶显示模块图1.4液晶模块本系统显示采用了工业字符型液晶模块1602,如图1.4所示。可显示2行16个字符,能方便显示英文字母大小写、阿拉伯数字、常用符号等。通过自定义还可显示简单的汉字。本液晶模块的电路的连接图如图3-3所示,第1脚和第2脚分别接到了电路的GND和VCC,这2个脚是液晶工作的电源输入脚。第3脚通过一个10K的电位器连接到地端,可通过调节该电位器来调节液晶的对比度。第4脚是液晶的寄存器控制脚,接到了单片机的P12脚上。第5脚是液晶的读写控制脚,接到了单片机的P13脚上。第6脚是液晶的使能脚,接到了单片机的P14脚上。第7脚到第14脚是液晶的数据/地址8位总线,接到了单片机的P0口上。最后第15脚和第16脚是液晶的背光电源脚,直接连接系统VCC和GND。1602LCD主要技术:(1)显示容量:16×2个字符(2)芯片工作电压:4.5—5.5V(3)工作电流:2.0mA(5.0V)(4)模块最佳工作电压:5.0V(5)字符尺寸:2.95×4.35(W×H)mm引脚说明:(1)VSS:接地(2)VDD:接5V正电源(3)VL:VL为液晶显示器对比度调整的端口,对比度的强弱由接电源的不同决定,对比度的调整可以通过一个10k的电位器(4)RS:RS是寄存器选择(5)R/W:R/W的读和写信号线,高水平低的读操作,写操作(6)E:使能端E,当E端由1至0时,液晶模块中的命令开始被运行(7)至(14)D0-D7:位双向数据线(15)BLA:背光源正极(16)BLK:背光源负极3.4报警模块图1.5蜂鸣器模块蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计算机、打印机、复印机、报警器、电子玩具、汽车电子设备、电话机、定时器等电子产品中作发声器件。报警电路的是电路器件简单,易于控制。所以报警模块选择单片机设计中最常使用的有源蜂鸣器。本设计利用单片机的I/O控制三极管的开关状态,进而达到控制蜂鸣器的报警。由于蜂鸣器工作时,需要的电流比较大,单片机的IO口输出的电流又比较小,所以这里利用三极管的开关管功能来控制蜂鸣器发音,本设计选用的三极管型号是PNP三极管S8550,而且本设计选用的蜂鸣器属于有源蜂鸣器,即在蜂鸣器内部已经内置了震荡电路,单片机无需连续发出高低电平来驱动它,而只要输出高(或低)电平即可,这大大简化了单片机程序的设计。由于选用的是PNP型而单片机上电IO口默认是高电平的,所以上电时蜂鸣器是不会发出鸣叫的。3.5按键输入模块图1.6按键输入模块在单片机应用中键盘用得最多的形式是独立键盘及矩阵键盘。它们各有自己的特点,其中独立键盘硬件电路简单,而且在程序设计上也不复杂,一般用在对硬件电路要求不高的简单电路中;矩阵键盘与独立键盘有很大区别,首先在硬件电路上它要比独立键盘复杂得多,而且在程序算法上比它要烦琐,但它在节省端口资源上有优势得多,因此它更适合于多按键电路。本设计中由于采用的按键数量较少,只有3个按键,分别是“设置”、“减”、“加”,故采用了独立键盘的方式。3.6电路的排版连线设计电路元器件的排版和连线影响到电路的美观和功能的实现,本设计采用protel软件进行排版设计。制作流程:(1)将生成的pcb图打印;(2)按照打印的图纸在板子上进行刻录联系;(3)将刻录的连线部分用锡进行覆盖;(4)用蚀铜液把多余的铜腐蚀掉;(5)打孔,焊接。4软件设计4.1总程序流程图图1.7程序流程图程序流程图实现步骤:本系统的软件流程图如图1.8所示,最开始先进行液晶的初始化,包括液晶功能初始化和液晶显示内容初始化,接着就开始进行温湿度的检测,然后判断读取到的温湿度是否在报警的范围之内,如果超出范围,则蜂鸣器鸣叫,且对应的指示灯亮。检测完温湿度数据后,就判断是否有按键被按下(第一个),有的话,则进入了报警范围设置界面,否则进行一段时间的延时后,就进入下一个循环,从新检测温湿度数据。4.1.1温湿度DHT11程序图1.8温湿度DHT11程序流程图该软件部分的实现步骤为:(1)DHT11发出读取命令,读取湿度和温度数据以及校验和;(2)检测数据是否出错;(3)若数据出错,则丢弃当前数据;若数据符合,则数据被采用,进行下一个程序。4.1.2LCD1602液晶程序图1.9LCD1602液晶程序该程序的实现步骤为:(1)液晶进行初始化后,对行列坐标进行定位;(2)显示一个字符;(3)数据是否显示完成,若否,则重新显示字符;若是,则进行下一个程序。4.2程序设计利用C51语言进行编程可以把程序进行模块化编写,然后在主函数里进行调用即可,这样分工明确,框架清晰,给人一目了然的感觉。程序详见附录一。4.3串口通信串口程序如附录三所示。单片机要与计算机通信,必须通过MAX232(或其他)芯片。这是因为计算机串口上的电平执行的是RS-232标准,它定义的高低电平和单片机的TTL逻辑电平不兼容。而MAX232芯片加上几个电解电容,能完成电压的加倍和反相,实现TTL电平和RS-232电平的转换。单片机的串行口TXD与MAX232的一组电平转换器的TTL输入端(管脚12)相连,经过MAX232转换后,RS-232标准输出端(管脚14)输出的信号进入计算机串口的RXD。同样计算机串口的TXD与MAX232的RS-232标准输入端(管脚13)相连,经过电平转换后,由TTL输出端(管脚11)输出到单片机的RXD上DHT11的供电电压为3-5.5V。传感器上电后,要等待1s以越过不稳定状态在此期间无需发送任何指令。电源引脚(VDD,GND)之间可增加一个100nF的电容,用以去耦滤波。DATA用于微处理器与DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间4ms左右,数据分小数部分和整数部分,具体格式在下面说明,当前小数部分用于以后扩展,现读出为零.操作流程如下:一次完整的数据传输40bit,高位先出。数据格式:8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据+8bit校验和用户MCU发送一次开始信号后,DHT11从低功耗模式转换到高速模式,等待主机开始信号结束后,DHT11发送响应信号,送出40bit的数据,并触发一次信号采集,用户可选择读取部分数据.从模式下,DHT11接收到开始信号触发一次温湿度采集,如果没有接收到主机发送开始信号,DHT11不会主动进行温湿度采集.采集数据后转换到低速模式。4.4上位机的程序设计4.4.1面向对象的编程面向对象(ObjectOriented,OO)是软件开发方法。面向对象的概念和应用已超越了程序设计和软件开发,扩展到如数据库系统、交互式界面、应用结构、应用平台、分布式系统、网络管理结构、CAD技术、人工智能等领域。面向对象是一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物。4.4.2上位机图形窗口上位机是一台可以发出特定操控命令的计算机,通过操作预先设定好的命令,将命令传递给下位机,通过下位机来控制设备完成各项操作。图形窗口见附录六。4.4.3上位机流程图2.0主线程流程图4.4.4主要程序代码程序代码详见附录二5系统调试5.1硬件调试(1)在焊接之前对各元器件的好坏进行测试,用万用表进行测量。(2)检测电路焊接的正确性,是否存在漏焊等。(3)用万用表的电阻档测量各焊点是否存在虚焊。5.2软件调试软件采用keilc51软件进行编写程序并进行仿真运行,如图2.2所示。图2.1软件编译图(1)在软件中编辑程序。(2)编辑结束后对软件的正确性进行仿真。(3)直至出现以上的结果即没有错误,没有警告。参考文献[1]董慧敏.温湿度控制系统设计[J].实验科学与技术,2008,(05):24~27 [2]PIC单片机与单片机入门[J].电子制作,2005,(10):10~15[3]刘守义.单片机技术基础[M].西安电子科技大学出版社,2007.[4]牛余朋,牛傲其.51单片机C语言的编程技巧[J].电子制作,2007.[5]王东峰.单片机C语言应用100例[M].电子工业出版社,2009.(04):22~27 [6]周韧研,商斌.VisualC++串口通信开发入门与编程实践,2009.(05):33~37[7]李江全,张荣华,李伟等.VisualStudio串口通信与测控应用编程实践.[8]李朝青.PC机及单片机数据通信技术.附录附录一程序#include<reg51.h> #include<intrins.h>typedefunsignedcharuchar;typedefunsignedintuint;sfrISP_DATA=0xe2; //数据寄存器sfrISP_ADDRH=0xe3; //地址寄存器高八位sfrISP_ADDRL=0xe4; //地址寄存器低八位sfrISP_CMD=0xe5; //命令寄存器sfrISP_TRIG=0xe6; //命令触发寄存器sfrISP_CONTR=0xe7; //命令寄存器sbitLCD_RS=P1^2; //LCD1602液晶的RS管脚sbitLCD_RW=P1^3; //LCD1602液晶的RW管脚sbitLCD_EN=P1^4; //LCD1602液晶的EN管脚sbitDHT11_D=P1^0; //温湿度传感器DHT11数据接入sbitLED_HL=P3^6; //湿度过低报警指示灯sbitLED_HH=P3^7; //湿度过高报警指示灯sbitBuzzer_D=P1^1; //蜂鸣器sbitKey_Set=P1^5; //设置按键的管脚sbitKey_Down=P1^6; //减按键的管脚sbitKey_Up=P1^7; //加按键的管脚ucharSHIDU; //保存湿度ucharT;//保存温度ucharAlarm_HL; //湿度下限报警值ucharAlarm_HH; //湿度上限报警值/***************************关闭ISP&IAP****************************/voidISP_Disable(){ ISP_CONTR=0x00; ISP_CMD=0x00; ISP_TRIG=0x00;}/**************************************************从单片机内部EEPROM读一个字节,从0x2000地址开始***************************************************/ucharEEPROM_Read(uintadd){ EA=0; ISP_CONTR=0x81; ISP_CMD=0x01; ISP_ADDRH=(uchar)(add>>8); ISP_ADDRL=(uchar)(add&0xff); //对STC89C52系列来说,每次要写入0x46,再写入0xB9,ISP/IAP才会生效 ISP_TRIG=0x46; ISP_TRIG=0xB9; _nop_(); ISP_Disable(); EA=1; returnISP_DATA;}/**************************************************往单片机内部EEPROM写一个字节,从0x2000地址开始***************************************************/voidEEPROM_Write(uintadd,ucharch){ EA=0; ISP_CONTR=0x81; ISP_CMD=0x02; ISP_ADDRH=(uchar)(add>>8); ISP_ADDRL=(uchar)(add&0xff); ISP_DATA=ch; ISP_TRIG=0x46; ISP_TRIG=0xB9; _nop_(); ISP_Disable(); EA=1;}/*********************************************************擦除单片机内部EEPROM的一个扇区写8个扇区中随便一个的地址,便擦除该扇区,写入前要先擦除**********************************************************/voidSector_Erase(uintadd) { EA=0; ISP_CONTR=0x81; ISP_CMD=0x03; ISP_ADDRH=(uchar)(add>>8); ISP_ADDRL=(uchar)(add&0xff); ISP_TRIG=0x46; ISP_TRIG=0xB9; _nop_(); ISP_Disable(); EA=1;}/****************************毫秒级延时函数*****************************/voidDelay_Ms(uinttime){ uinti,j; for(i=0;i<time;i++) { for(j=0;j<112;j++); }}/*******************************************LCD1602液晶写指令函数********************************************/voidLcd_Write_Cmd(ucharcmd){LCD_RS=0;LCD_RW=0;LCD_EN=0;P0=cmd; Delay_Ms(2);LCD_EN=1; Delay_Ms(2);LCD_EN=0; }/*******************************************LCD1602液晶写数据函数********************************************/voidLcd_Write_Data(uchardat){LCD_RS=1;LCD_RW=0;LCD_EN=0; P0=dat; Delay_Ms(2);LCD_EN=1; Delay_Ms(2);LCD_EN=0;}/*****************************LCD1602液晶初始化函数******************************/voidLcd_Init(){Lcd_Write_Cmd(0x38);//16*2显示,5*7点阵,8位数据口Lcd_Write_Cmd(0x0C);//开显示,不显示光标Lcd_Write_Cmd(0x06);//地址加1,当写入数据后光标右移Lcd_Write_Cmd(0x01);//清屏}/***************************************LCD1602液晶输出字符串函数****************************************/voidLcd_Show_String(uchar*str){while(*str!='\0') //判断当前字符是否为空字符{ Lcd_Write_Data(*str++); }}/***********************************LCD1602液晶输出数字************************************/voidLcd_Show_Num(ucharnum){ Lcd_Write_Data(num/10+48); //十位 Lcd_Write_Data(num%10+48); //个位}/*******************************************LCD1602液晶显示内容的初始化********************************************/voidLcd_Show_Init(){ Lcd_Write_Cmd(0x80); Lcd_Show_String("DHT11SYSTEM"); //第1行的显示内容 Lcd_Write_Cmd(0xC0); Lcd_Show_String("SHIDU=%RH");//第2行的显示内容 }/********************************10us级延时程序*********************************/voidDelay_10us(){ _nop_(); //执行一条指令,延时1微秒 _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();}/***************************************读取DHT11单总线上的一个字节****************************************/ucharRead_Dht_Byte(){ ucharj; uchardat=0; for(j=0;j<8;j++) { while(!DHT11_D); //等待低电平结束 Delay_10us(); //延时等待30us Delay_10us(); Delay_10us(); if(DHT11_D) //判断数据线是高电平还是低电平 { dat=dat|0x01; while(DHT11_D); } else { dat=dat|0x00; } dat=dat<<1;//循环左移一位 }returndat; }/*******************************************************读取DHT11的一帧数据,湿度高、湿度低、校验码********************************************************/voidRead_Dht_Data(){ ucharShidu_H; //湿度高检测值 ucharShidu_L; //湿度低检测值 ucharTem_H; //温度高检测值 ucharTem_L; //温度低检测值ucharcheck; //校验字节 DHT11_D=0; //主机拉低20ms Delay_Ms(20); DHT11_D=1; //DATA总线由上拉电阻拉高主机延时40us Delay_10us(); //延时等待30us Delay_10us(); Delay_10us(); while(!DHT11_D); //等待DHT的低电平结束 while(DHT11_D); //等待DHT的高电平结束 //进入数据接收状态 Shidu_H=Read_Dht_Byte(); //湿度高8位 Shidu_L=Read_Dht_Byte(); //湿度低8位,总为0 Tem_H=Read_Dht_Byte(); //温度高8位 Tem_L=Read_Dht_Byte(); //温度低8位,总为0 check=Read_Dht_Byte(); //8位校验码,其值等于读出的四个字节相加之和的低8位 DHT11_D=1; //拉高总线 if(check==Shidu_H+Shidu_L+Tem_H+Tem_L) //如果收到的数据无误 { SHIDU=Shidu_H; //将湿度的检测结果赋值给全局变量SHIDU }}/****************************************报警判断*****************************************/voidAlarm_Judge(){ uchari; if(SHIDU>Alarm_HH) //湿度过高,低电平显示 { LED_HH=0; LED_HL=1; } elseif(SHIDU<Alarm_HL) //湿度过低,低电平显示 { LED_HL=0; LED_HH=1; } else //湿度正常,都为高电平 { LED_HH=1; LED_HL=1; } if((!LED_HH)||(!LED_HL)) //蜂鸣器判断,只要至少1个报警灯亮,蜂鸣器就报警 { for(i=0;i<3;i++) { Buzzer_D=0; Delay_Ms(100); Buzzer_D=1; Delay_Ms(100); } }}/************************************************按键扫描,用于设置湿度报警范围*************************************************/voidKey_Scan(){ if(!Key_Set) //判断设置按键是否被按下 { /*将液晶显示改为设置页面的*/ Lcd_Write_Cmd(0x80); Lcd_Show_String("AlarmSet");//第一行显示内容 Lcd_Write_Cmd(0xC0); Lcd_Show_String("-");//第二行显示内容 Lcd_Write_Cmd(0xC0+5); //在液晶上填充湿度的下限值 Lcd_Show_Num(Alarm_HL); Lcd_Write_Cmd(0xC0+8); //在液晶上填充湿度的上限值 Lcd_Show_Num(Alarm_HH); Lcd_Write_Cmd(0xC0+6); //光标定位到第2行第7列 Lcd_Write_Cmd(0x0F); //光标闪烁 Delay_Ms(10); //去除按键按下的抖动 while(!Key_Set); //等待按键释放 Delay_Ms(10); //去除按键松开的抖动 /*设置湿度的下限值*/ while(Key_Set) //“设置键”没有被按下,则一直处于湿度下限的设置 { if(!Key_Down) //判断“减按键“是否被按下 { if(Alarm_HL>0) //当湿度下限值大于0时,自减 { Alarm_HL--; } Lcd_Write_Cmd(0xC0+5); //重新刷新显示更改后的湿度下限值 Lcd_Show_Num(Alarm_HL); Lcd_Write_Cmd(0xC0+6); //重新定位闪烁的光标位置 Delay_Ms(350); } if(!Key_Up) //判断“加按键“是否被按下 { if(Alarm_HL<99) //当湿度下限值小于99时,自加 { Alarm_HL++; } Lcd_Write_Cmd(0xC0+5); //重新刷新显示更改后的湿度下限值 Lcd_Show_Num(Alarm_HL); Lcd_Write_Cmd(0xC0+6); //重新定位闪烁的光标位置 Delay_Ms(350); //延时 } } Lcd_Write_Cmd(0xC0+9); //定位到湿度上限的位置闪烁 Delay_Ms(10); //去除按键按下的抖动 while(!Key_Set); //等待按键释放 Delay_Ms(10); //去除按键松开的抖动 /*设置湿度的上限值*/ while(Key_Set) //“设置键”没有被按下,则一直处于湿度上限的设置 { if(!Key_Down) //判断“减按键”是否被按下 { if(Alarm_HH>0) //当湿度上限值大于0时,自减 { Alarm_HH--; } Lcd_Write_Cmd(0xC0+8); //重新刷新显示更改后的湿度上限值 Lcd_Show_Num(Alarm_HH); Lcd_Write_Cmd(0xC0+9); //重新定位闪烁的光标位置 Delay_Ms(350); } if(!Key_Up) //判断“加按键“是否被按下 { if(Alarm_HH<99) //当湿度上限值小于99时,自加 { Alarm_HH++; } Lcd_Write_Cmd(0xC0+8); //重新刷新显示更改后的湿度上限值 Lcd_Show_Num(Alarm_HH); Lcd_Write_Cmd(0xC0+9); //重新定位闪烁的光标位置 Delay_Ms(350); //延时 } } Lcd_Write_Cmd(0x0C); //取消光标闪烁 Lcd_Show_Init(); //液晶显示为检测界面的 Delay_Ms(10); //去除按键按下的抖动 while(!Key_Set); //等待按键释放 Delay_Ms(10); //去除按键松开的抖动 Sector_Erase(0x2000); //存储之前必须先擦除 EEPROM_Write(0x2000,Alarm_HL); //把湿度下限存入到EEPROM的0x2000这个地址 EEPROM_Write(0x2001,Alarm_HH); //把湿度上限存入到EEPROM的0x2001这个地址 } }/**************************主函数***************************/intmain(){ uchari; Lcd_Init(); //LCD1602初始化 Lcd_Show_Init(); //LCD1602显示的初始化 Alarm_HL=EEPROM_Read(0x2000); //从EEPROM的0x2002这个地址读取湿度的报警下限 Alarm_HH=EEPROM_Read(0x2001); //从EEPROM的0x2003这个地址读取湿度的报警上限 while(1) { Read_Dht_Data(); //检测湿度数据 Lcd_Write_Cmd(0xC0+8); //定位到要显示湿度的地方 Lcd_Show_Num(SHIDU); //显示湿度值 Alarm_Judge(); //判断并根据需要报警 for(i=0;i<25;i++) { Key_Scan(); //按键扫描 Delay_Ms(20); //延时 } } return0;}附录二上位机程序BOOLCommCommunicateThread::ConnectComm(intnPort){// BYTEbSet; DCBdcb; BOOLfRetVal; COMMTIMEOUTSCommTimeOuts; CStringszCom; szCom.Format(_T("\\\\.\\COM%d"),nPort); COMFile=CreateFile(szCom.GetBuffer(50),GENERIC_READ|GENERIC_WRITE,//可读、可写 FILE_SHARE_READ|FILE_SHARE_WRITE,//不共享FILE_SHARE_READ,FILE_SHARE_WRITE,FILE_SHARE_DELETE NULL,//无安全描 OPEN_EXISTING,//打开已存在文件 /*FILE_ATTRIBUTE_NORMAL|*/FILE_FLAG_OVERLAPPED,//文件属性 NULL//一个有效的句柄,已存在的设备句柄AvalidhandletoatemplatefilewiththeGENERIC_READaccessright ); intnError=GetLastError(); if(INVALID_HANDLE_VALUE==COMFile/*COMFileTemp*/){ charchError[256];memset(chError,0,256); intnBuffLen=256; if(GetErrorString((PBYTE)chError,&nBuffLen,GetLastError())){ AfxMessageBox(chError); } return(FALSE); } //设置缓冲区,输入/输出大小(字节数) SetupComm(/*COMFileTemp*/COMFile,4096,4096); //指定监视事件_收到字符放入缓冲区 SetCommMask(/*COMFileTemp*/COMFile,EV_RXCHAR); CommTimeOuts.ReadIntervalTimeout=0xFFFFFFFF; CommTimeOuts.ReadTotalTimeoutMultiplier=0; CommTimeOuts.ReadTotalTimeoutConstant=1000; CommTimeOuts.WriteTotalTimeoutMultiplier=2*CBR_9600/9600; CommTimeOuts.WriteTotalTimeoutConstant=0; //给定串口读与操作限时 SetCommTimeouts(/*COMFileTemp*/COMFile,&CommTimeOuts); //设置串口参数:波特率=9600;停止位1个;无校验;8位 dcb.DCBlength=sizeof(DCB); GetCommState(/*COMFileTemp*/COMFile,&dcb); dcb.BaudRate=CBR_9600; dcb.StopBits=ONESTOPBIT; dcb.Parity=NOPARITY; dcb.ByteSize=8; dcb.fBinary=TRUE;//二进制通信,非字符通信 dcb.fOutxDsrFlow=0; dcb.fDtrControl=DTR_CONTROL_ENABLE; dcb.fOutxCtsFlow=0; dcb.fRtsControl=RTS_CONTROL_ENABLE; dcb.fInX=dcb.fOutX=1; dcb.XonChar=0X11; dcb.XoffChar=0X13; dcb.XonLim=100; dcb.XoffLim=100; dcb.fParity=TRUE; //根据设备控制块配置通信设备 fRetVal=SetCommState(/*COMFileTemp*/COMFile,&dcb); if(!fRetVal)returnFALSE; //刷清缓冲区 PurgeComm(/*COMFileTemp*/COMFile,PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR); //指定串口执行扩展功能 EscapeCommFunction(/*COMFileTemp*/COMFile,SETDTR);// //设置串口“收到字符放入缓冲区”事件// if(!SetCommMask(COMFile,EV_RXCHAR))return(FALSE); returnTRUE;}BOOLCommCommunicateThread::CloseComm(intnPort){ //禁止串行端口所有事件 SetCommMask(COMFile,0); //清除数据终端就绪信号 EscapeCommFunction(COMFile,CLRDTR); //丢弃通信资源的输出或输入缓冲区字符并终止在通信资源上挂起的读、写操//场作 PurgeComm(COMFile,PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR); CloseHandle(COMFile); COMFile=NULL;// CloseHandle(osRead.hEvent);// memset(&osRead,0,sizeof(osRead));;// CloseHandle(osWrite.hEvent);// memset(&osWrite,0,sizeof(osWrite));// CloseHandle(ShareEvent.hEvent);// memset(&ShareEvent,0,sizeof(ShareEvent)); returnTRUE;}intCommCommunicateThread::WriteCommBlock(PBYTEpOutData,intnDataLen){ if(NULL==pOutData||nDataLen<1) returnFALSE; //while(nDataLen>0){ DWORDnLen=0; if(!WriteFile(COMFile,(LPCVOID)pOutData,nDataLen,&nLen,&/*ShareEvent*/osWrite)){ if(WAIT_OBJECT_0==WaitForSingleObject(osWrite.hEvent,0xFFFFFF)) ResetEvent(osWrite.hEvent); else ResetEvent(osWrite.hEvent); DWORDnError=GetLastError(); if(997!=nError){//997异步没完成 charchError[256];memset(chError,0,256); intnBuffLen=256; if(GetErrorString((PBYTE)chError,&nBuffLen,nError)){ AfxMessageBox(chError); } } } //} returnTRUE;}附录三串口通信程序/**************************************************               往串口发送一个字节的数据 ***************************************************/ void Send_Byte(uchar dat) { SBUF = dat; while(!TI); TI   = 0; } /*************************************************            将测得的湿度送往串口显示 **************************************************/ void Send_Data(uchar dat) { Send_Byte(dat/10+48);      // 十位 Send_Byte(dat%10+48);  // 个位 Send_Byte('\n'); } /********************************************                   串口初始化 *********************************************/ void Com_Init() { TMOD =&
/
本文档为【湿度传感器设计】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索