单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 108574|回复: 67
收起左侧

基于51单片机的DHT11温湿度检测控制系统设计论文

  [复制链接]
雨和你 发表于 2017-5-17 13:50 | 显示全部楼层 |阅读模式
从开始到最后都有详细的过程

摘  要

本次设计是采用MSC-51系列单片机中的AT89S51和DHT11构成的低成本的温湿度的检测控制系统。单片机AT89S51是一款低消耗、高性能的CMOS8位单片机,由于它强大的功能和低价位,因此在很多领域都是用它。DHT11温湿度传感器是一款含有已校准数字输出的温湿度复合传感器,传感器包括一个电阻式感湿原件和一个NTC测温元件,该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。设计主要包括硬件电路的设计和系统软件的设计。
硬件电路主要包括单片机、温湿度传感器、显示模块、报警器以及控制设备等5部分。其中由DHT11温湿度传感器及1602字符型液晶模块构成系统显示模块;测温湿度控制电路由温湿度传感器和预设温度值比较报警电路组成;用户根据需要预先输入预设值,当实际测量的温湿度不符合预设的温湿度标准时,发出报警信号(蜂鸣器蜂鸣),启动相应控制。
软件部分包括了主程序、显示子程序、测温湿度子程序。   
                            目 录

前  言

1.1本文研究的背景及意义

1.2研究现状

1.3本文研究的主要内容

第2章 设计任务分析及方案论证

2.1设计过程及其工艺要求设计

2.2设计总体方案及其论证

2.3器件选定

2.4 AT89S51单片机

2.5中断系统

2.6复位电路

2.7时钟电路

2.8显示部分

2.9本章小结

第3章 硬件设计

3.1主控制电路和测温时控制电路

3.2主要模块的电路

3.3硬件实施控制

3.4设备运行

3.5控制设备:

3.6 本章小结

第4章  软件设计

4.1系统流程图

4.2按键流程图

4.3 Protues运行结果

4.4 本章小结

结 论

参考文献

附  录


前  言1.1本文研究的背景及意义
粮库已经被广泛的运用,是存储粮食的一个重要方式。是粮食仓库的简称,是粮食仓储企业习惯称谓,属于全民所有制企业,是我国粮食企业的一个重要组成部分,由粮食部门统一管理,担负着国家粮食储备、地方粮食储备、粮食流通的主渠道作用,其主要任务是完成粮食的接受、保管和调运输送等粮食流通诸环节。在不同季节内,尤其是不利于存储食物的季节内进行的一种保护措施。
因此研究温湿度的控制非常有必要,它可以进一步优化储存控制方式,提升水平。
1.2研究现状
我国地大物博,各地的自然环境条件不同,所以在不利于存储粮食的自然环境中,具有可调节温湿度的可控粮库更能够创造适宜存储的条件,中国各地经济水平和发达水平有比较大的差异,所以研制出又具有实用价值并且采用最低的成本达到最好的效果是非常有必要的,既节约了人力亲自检查,又节约制造成本,不会对贫困地区造成经济负担,又避免了能源和经济浪费[1]。
本系统所要完成的任务是:

    ①人性化的设计。界限温度值及湿度值能够由用户根据不同被储存的粮食的存储需求输入并通过显示器显示,能够实时、准确的显示采样温度值与湿度值。

②通过采集温度及湿度值,准确的判断标准值与当前值之间的差异,看是否符合标准值,及时的启动报警装置(包括警报灯的提示功能以及蜂鸣等)进行报警,并采取相应控制温湿度的方案。

1.3本文研究的主要内容
一、首先我们必须了解温湿度控制对储存粮食的重要性,其次我们才能够对此作出更好的判断,以求更好的解决用户所需要的问题。
二、温湿度的监测和控制是我们研究的主要内容。数字化温湿度检测的方法为一旦环境中的温湿度发生变化时,湿度传温度感器和湿度传感器随着温湿度的变化而变化,然后将变化的电阻通过转换电路和转换信号检测为与之对应变化的电压,然后把模拟电压信号由A/D转换器转换为数字信号并送入到单片机中,对采集到的信号单片机进行滤波处理并通过查表得到实际测量的湿度值,之后通过单片机的各外部接口电路显示该温湿度值。
三、该系统通过按钮设定最适宜的温度和湿度,传感器向中央控制系统输送监控信号,超过预设值的话,蜂鸣器就会报警提醒,控制温、湿度的设备即可作出调整,回到正常范围内,系统正常运行。
四、根据各种不同粮食的适宜温度进行温室温度调节,若低于下限温度则采取升温措施,通常采取电热增温和火力增温等,电热增温比较方便。若高于上限温度则采取降温措施,通常通过水管降温和风扇降温,风扇降温比较方便;为满足粮库不同种类粮食对湿度的要求,可以在地上、台阶、盆壁洒水,还可以在空中悬挂湿布,以增加水分的蒸发,最好的办法是设置自动喷雾装置,自动调节湿度。如果湿度过大,容易导致植被过于潮湿,发生腐烂,可采用烘干技术,加快水分流失,保持被存储粮食的干燥。为满足对于不同粮食的储存方式和需求,我们可以随时对温、湿度进行调节,对于不利情况能够及时的作出显示,并能够采取相应的措施提醒用户进行调整,以达到最适宜的温湿度。


第2章 设计任务分析及方案论证
本章详细介绍了本次设计的主要任务,以及对于所要实现的内容加以分析,同时详细的介绍了主要元器件的选择,以及各自的特性。
2.1设计过程及其工艺要求设计
一个以单片机为核心的温湿度控制系统,需要实现的功能为:
   ①能够准确的显示当前的温度以及湿度。温度检测的范围0℃-60℃,测温精度:±2℃;湿度检测范围20%-100%RH,  测湿精度:±5%RH。
   ②能够自主调节当前需要温度以及湿度的预设温湿度值,在系统上面有调节按钮,可随时根据需要增加或者减少预设值。
   ③一旦发现超过了预设值,蜂鸣器蜂鸣报警,控制设备立即启动,立即调控温湿度。
   ④报警方式为三极管驱动的蜂鸣音报警。
   ⑤系统的显示方式均为四位显示,采用LCD显示。
2.2设计总体方案及其论证2.2.1设计总体方案及其论证
本设计要实现的功能是:实时显示当前环境的温湿度,并且允许用户设定温湿度标准值,当环境温湿度超过或低于标准值时,系统会以蜂鸣器鸣响的方式进行报警提示,并且控制设备自启动,待达到标准值时,蜂鸣器停止鸣响,控制设备停止运行,系统正常工作,工作指示灯亮。
   (1)温度监控:对温室温度进行测量和控制并反映在显示器上。

(2)湿度监控:对温室湿度进行测量和控制反映在显示器上。

(3)显    示:LCD就地显示此时此刻温湿度值,摆放在生产现场用于显示当前的温湿度。

依据功能设定,本系统主要分为以下三个模块:
              (1)温湿度采集模块
              (2)数据处理模块
              (3)用户交互模块
              其中温湿度采集模块使用的是DHT11数字温湿度传感器,它使用单总线方式,接口简单,而且无需另外校准。分辨率为8bit,完全能够满足日常环境温湿度的检测要求。
              数据处理模块使用的是AT89S51单片机,其完成温湿度数据的采集、运算和逻辑控制的功能。
              用户交互模块主要由按键、1602点阵液晶、蜂鸣器和控制器构成。其中按键用于用户设定温湿度准确值,1602用于数据显示,蜂鸣器用于提示用户,控制器用于调节控制不符合要求的温、湿度。按照系统的设计功能所要求的,温湿度监控系统原理图如下图2.2.1所示:(在附件中)


图2-2-1 温湿度监控系统原理图


单片机作为主控制器,主要负责处理由温湿度传感器送来数据,并把处理好的数据送向显示器模块,数据温湿度传感器主要用来采集周围的环境参数,并把所采集到得数据送向单片机,按键电路主要是用来完成单片机的复位操作和温湿度初始值的设定。蜂鸣器电路就是用三极管来实现的,用来判断周围的温度或者湿度是否超出设定数值,控制设备等候指令,当蜂鸣器响起,温、湿度不在标准范围内,控制设备自行启动,直到温、湿度正常,显示电路主要用来显示当前的温湿度[10]。
2.3器件选定
将单片机用作测控系统时,总要有被测信号输入通道,由计算机拾取必要的输入信息。对于测量系统而言,其核心任务是怎么样获得准确的被测信号;而对测控系统来说,不可缺少的环节是对条件的监测和对被控对象状态的测试,传感器是实现测量与控制的第一环节,是测控系统的关键部分,一切准确的测量和控制都将在传感器对于原始信号的准确可靠的转换和捕捉,工业生产过程的自动化测量和控制,基本主要依赖各种传感器来控制和检测生产过程中的各种量,使系统和设备在最佳状态正常运行,从而保证生产的高质量和高效率 [6]。
2.3.1测量部分:温湿度传感器
DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器,它应用专用的温湿度传感和数字模块采集技术,具有很高的稳定性和可靠性,DHT11传感器内含一个NTC测温和一个电阻式感湿元件,并与一个8位的高性能单片机相连接,在精确的湿度校验室中DHT11传感器进行过校准,以程序的形式校准系数储存在0TP内存中,检测信号的时候,在处理过程中传感器内部要调用这些校准系数,采用单线制的串行接口[13],使系统集成可以有较低的功耗,而且更加简单快速,信号传输距离超过20米,作为一个数字温湿度传感器DHT11具有响应快速、抗干扰强、性价比高等优点,它的性能指标如下:湿度测量范围为20%~90%RH;湿度测量精度为±5%RH;温度测量范围为0~50 ℃,温度测量精度为±2℃,工作电压3.0~5.5 V,相应时间<5S,DHT1l采用4针单排引脚封装, 传感器通电后,需要等待1s,这是因为要越过不稳定的状态,在此期间不需发送指令,电源引脚(VDD,GND)之间可增加一个100nF 的电容,用以去耦滤波[7]。

1.012.jpg

图2-3-1典型的应用电路

电源引脚
四条引角中有两条是电源引脚,有两条是输出数据的引脚,你只需要给他供上额定电压,然后再他的输出引脚采集信号就可以了,输出信号如果是模拟量的话,通过A/D芯片,将模拟量转换为数字信号,然后传送给单片机。DHT11是数字传感器,所以不需要进行模数的转换。
1.013.jpg

图2-3-1  DHT11实物图

(1)DHT11温湿度传感器产品参数:
相对湿度
分 辨 率:16Bit
重 复 性:±1%RH
精    度:25°C  ±5%RH
互 换 性:可完全互换
响应时间:1/e(63%)25°C   6s
          1m/s 空气 6s
迟    滞:<±0.3%RH
长期稳定性:<±0.5%RH/yr

温度
分 辨 率:16Bit
重 复 性:±0.2°C
量程范围:25°C  ±2°C
响应时间:1/e(63%)  10s

电气特征
供    电:DC 3.5-5.5V
供电电流:测量0.3mA  待机60μA
采样周期:次  大于2秒

引脚说明
(1)VDD  供电3.5-5.5V
(2)DATA 串行数据,单总线
(3)NC 空脚
(4)GND 接地,电源负极
2.3.2串行接口(单线双向)
DATA 用于微处理器与 DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间4ms左右,数据分小数部分和整数部分,具体格式在下面说明,当前小数部分用于以后扩展,现读出为零.操作流程如下:一次完整的数据传输为40bit,高位先出。
数据格式:8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据+8bit校验和。
数据传送正确时校验和数据等于“8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据”所得结果的末8位。
用户MCU发送一次开始信号后,DHT11从低功耗模式转换到高速模式,等待主机开始信号结束后,DHT11发送响应信号,送出40bit的数据,并触发一次信号采集,用户可选择读取部分数据.如果没有接收到主机发送开始信号,DHT11不会主动进行温湿度采集.采集数据后转换到低速模式。
    总线空闲状态为高电平的时候主机把总线拉低等待DHT11响应, DHT11能检测到起始信号,主机必须把总线拉低,至少大于18ms。DHT11一旦接收到主机的开始信号,接着就等待开始信号的结束,然后发送80us的低电平响应信号,要读取DHT11的响应信号,必须等待开始信号的结束,并延时等待20-40us后才能够接受,主机发送开始信号后,这时候就可输出高电平或切换到输入模式,接着总线由上拉电阻拉高。
DHT11发送响应信号的时候总线为低电平 ,DHT11把总线拉高80us之前,必须等到响应信号发送,准备发送数据时,每一bit数据都以50us低电平时隙开始,数据位是0或1是由高电平的长或短来决定。假如响应信号的读取为高电平,但是DHT11无响应响应,这时候说明路线可能连接不正常,当最后一bit数据传送结束后,DHT11把总线拉低50us,接着总线由上拉电阻拉高进入空闲状态。
2.3.3电气特性
VDD=5V,T = 25℃
图2-3-3电气特性(注:采样周期间隔不得低于1秒钟)

参数

条件

min

typ

max

单位

供电

DC

3

5

5.5

V

供电电流

测量

0.5


2.5

Ma

平均

0.2


1

Ma

待机

100


150

Ua

采样周期

1




               

2.3.4性能说明

  

表2-3-4 性能说明

参数

条件

Min

Typ

Max

单位

分辨率


8

±

Bit

1

1

1

%RH

精度

25℃


±4


%RH

重复性



±1


%RH

温度

0-50℃



±5

%RH

温度


量程范围

0℃

30


90

%RH

50℃

20


80

%RH

25℃

20


90

%RH

长期稳定性

典型值


±1


%RH/yr

迟滞



±1


互换性

可完全互换

分辨率


8

8

8

Bit

1

1

1

重复性


±1


响应时间

1/e(63%)

6


30

S

量程范围


0


50

精度


±1


±2

2.3.5引脚说明

表2.3.5 DHT11引脚说明

pin

名称

注释

1

VDD

供电3-5.5V

2

DATA

串行数据,单总线

3

NC

空脚,悬空

4

GND

接地,电源负极


注意 引脚2在接单片机时,同时要在数据线接一上拉电阻,接到电源上[4]。
2.3.6应用信息
电阻式温、湿度传感器暴露在化学物质中会受到干扰,导致灵敏度下降,当处于极限状态时,传感器可以通过程序处理,回复到初试的校准状态,在不符合规范的范围内使用传感器,不仅会导致几乎3%的临时漂移信号,而且会加速产品的老化,转为正常的使用范围后,会渐渐恢复校准状态;温度是影响气体相对湿度的关键,因此测量时最好让湿度传感器工作温度相同[5]。
2.3.7 封装信息
1.014.jpg 1.015.jpg 1.016.jpg

图2-3-6 DHT11的封装信息

2.4 AT89S51单片机2.4.1单片机介绍
AT89S51是美国ATMEL公司生产的低功耗、高性能CMOS 的8位单片机,片内含4K的可编程的Flash只读程序存储器,器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准8051指令系统及引脚。它集Flash程序存储器既可在线编程(ISP),也可用传统方法进行编程及通用8位微处理器于单片机芯片中,低价位AT89S51单片机可为您提供许多高性价比的应用场合,可灵活应用于各种控制的领域【8】。AT89S51提供以下的功能标准:4K字节闪烁存储器,128字节随机存取数据存储器,2个16位定时/计数器,32个I/O口, 1个串行通信口,1个5向量两级中断结构,另外,AT89S51还可以进行0HZ的静态逻辑操作,并支持两种软件的节电模式,闲散方式停止中央处理器的工作,可允许随机存取数据存储器、定时/计数器、串行通信口及中断系统继续工作。掉电方式保存随机存取数据存储器中的内容,但震荡器停止工作并禁止其它所有部件的工作直到下一个复位,在AT89C51上新增加的功能使AT89S51性能有了较大提升,它的价格甚至更低,它的工作频率可达33MHz,比AT89C51的工作频率更高,ISP在线编程功能的优越性在于它不必要将芯片从工作状态下分离,特别是在改写存储器内的程序,这是一个相当方便简单的功能,它不需要像AT89C51那样外接看门狗计时器单元电路,由于它内部具有双工UART串行通道内部集成看门狗计时器,它具有全新的加密算法,大大加强的程序的保密性,有效的保护知识产权不被侵犯,它完全兼容51全部字系列产品[8]。
1.017.jpg

图2-5-1  AT89S51引脚图

2.4.2引脚说明:
VCC:电源电压输入端。
GND:电源地

P0口:P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。当P1口的管脚第一次写1时,被定义为高阻输入。P0能够用于外部程序数据存储器,它可以被定义为数据/地址的低八位。在FIASH编程时,P0 口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。P0口在访问外部存储器时,P0口既是一个真正的双向数据总线口,又是输出8位地址口。它包括一个输出锁存器,两个三态缓冲器,一个输出驱动电路和一个输出控制电路

P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。P1口管脚写入”1”后,被内部上拉为高电平,可用作输入。P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在FLASH编程和校验时,P1口作为第八位地址接收。专门为用户使用的I/O口,是准双向口,P1口为8位准双向口,每一位均可单独定义为输入或输出口。在编程校验期间,用做输入低位字节地址。P1口可以驱动4个TTL负载。
P2口:P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。并因此作为输入时,P2口的管脚被外部拉低,将输出电流。这是由于内部上拉的缘故。P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。P2口在FLASH编程和校验时接收高八位地址信号和控制信号。
P3口:P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL门电流。当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。作为输入,由于外部下拉为低电平,P3口将输出电流,这是由于上拉的缘故。P2口也是双向口。它是供系统扩展时输出高8位地址。如果没有系统扩展时,也可以作为用户的I/O口使用。P2口作为外部数据存储器或程序存储器的地址总线的高8位输出口AB8-AB15,P0口由ALE选通作为地址总线的低8位输出口AB0-AB7。外部的程序存储器由PSEN信号选通,数据存储器则由WR和RD读写信号选通,因为2=64k,所以AT89S51最大可外接64kB的程序存储器和数据存储器。P3口除了作为普通I/O口,还有第二功能:





表2-5-2 P3口的第二功能

端口引脚

功能特性

P3.0

串行输入口(RXD)

P3.1

串行输出口(TXD)

P3.2

外中断0(INTO)

P3.3

外中断1(INT1)

P3.4

定时/计数器0的外部输入口(T0)

P3.5

定时/计数器1的外部输入口(T1)

P3.6

外部数据存储器写选通(WR)

P3.7

外部数据存储器读选通(RD)

    RST:复位输入端,高电平有效。当振荡器复位器件时,要保持RST脚两个机器周期的高电平时间。
ALE/PROG:地址锁存允许/编程脉冲信号端。当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的低位字节。在FLASH编程期间,此引脚用于输入编程脉冲。在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。因此它可用作对外部输出的脉冲或用于定时目的。然而要注意的是:每当用作外部数据存储器时,将跳过一个ALE脉冲。如想禁止ALE的输出可在SFR8EH地址上置0。此时,ALE只有在执行MOVX,MOVC指令是ALE才起作用。另外,该引脚被略微拉高。如果微处理器在外部执行状态ALE禁止,置位无效。
PSEN:外部程序存储器的选通信号,低电平有效。在由外部程序存储器取指期间,每个机器周期两次/PSEN有效。但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现。
EA/VPP:外部程序存储器访问允许。注意加密方式1时,EA将内部锁定为RESET;当EA端保持高电平时,此间内部程序存储器。在FLASH编程期间,此引脚也用于施加12V编程电源(VPP)。
XTAL1:片内振荡器反相放大器和时钟发生器的输入端。
XTAL2:片内振荡器反相放大器的输出端。

现在已经对四个8位双向并行I/O口有了初步的了解。根据以上的内容可知只有P1口是标准的I/O口,所以我们选用P1口作为数据端口,P1口可逐位分别定义各口线为输入或输出线[7]。

2.4.3单片机最小系统
所谓单片机的最小系统是指使单片机能运行程序、正常工作的最简单电路系统,是保证单片正常启动、开始工作的必须电路,缺一不可。单片机最小系统一般由单片机、程序存储器、时钟电路和复位电路组成。对于AT89S51单片机,由于片内有4K的程序存储器,所以其最小系统除了单片机本身外,只需外接时钟电路与复位电路即可。
2.4.4主要性能特点和优越性
(1)4k Bytes Flash片内程序存储器;
(2)128 bytes的随机存取数据存储器(RAM);
(3)32个外部双向输入/输出(I/O)口;
(4)5个中断优先级、2层中断嵌套中断;
(5)6个中断源;
(6)2个16位可编程定时器/计数器;
(7)2个全双工串行通信口;
(8)看门狗(WDT)电路;
(9)片内振荡器和时钟电路;
(10)与MCS-51兼容;
(11)全静态工作:0Hz-33MHz;
(12)三级程序存储器保密锁定;
(13)可编程串行通道;
(14)低功耗的闲置和掉电模式。
2.5中断系统2.5.1中断

    程序执行过程中,允许外部或内部事件通过硬件打断程序的执行,使其转向为处理内部事件的中断服务程序中去;完成中断服务的程序后,CPU继续原来被打断的程序,这样的过程称为中断过程。

2.5.2产生中断

能产生中断的外部和内部事件。AT89S51有5个中断源:

(1)INT0:外部中断0请求,低电平有效。通过P3.2引脚输入。
(2)INT1:外部中断1请求,低电平有效。通过P3.3引脚输入。
(3)T0:定时器/计数器0溢出中断请求。
(4)TI:定时器/计数器1溢出中断请求。
(5)TXD/RXD:串行口中断请求。当串行口完成一帧数据的发送或接收时,便请求中断。每一个中断源都对应一个中断请求标志位,它们设置在特殊功能寄存器TCON和SCON中。当这些中断源请求中断时,相应的标志分别有TCON和SCON中的相应位来锁存。
2.5.3中断系统有以下4个特殊功能寄存器
(1)定时器控制寄存器TCON(用6位);
(2)串行口控制寄存器SCON(用2位);
(3)中断允许寄存器IE;
(4)中断优先级寄存器IP。
    其中,TCON和SCON只有一部分用于中断控制。通过对以上各特殊功能寄存器的各位进行置位或复位等操作,可实现各种中断控制功能。
2.6复位电路

    复位是单片机的初始化操作。其主要功能是把PC初始化为000H,使单片机从0000H单元开始执行程序。除了进入系统的正常初始化之外,当由于程序运行出错或操作错误使系统处于死锁状态时,为摆脱困境,也需按复位键重新启动。

除PC之外,复位操作还对其他一些寄存器有影响,它们的复位状态如下图所示.
表2-8 复位操作对寄存器的影响
寄存器
复位状态
  寄存器
复位状态
PC
0000H
TCON
00H
ACC
00H
TL0
00H
PSW
00H
THO
00H
SP
07H
TL1
00H
DPTR
0000H
TH1
00H
P0-P3
FFH
SCON
00H
IP
XX000000B
SBUF
不定
IE
0X000000B
PCON
OXXXOOOOB
TMOD
OOH





    为确保微机系统中电路稳定可靠工作,复位电路是必不可少的一部分,一般微机电路正常工作需要供电电源为5V±5%,即4.75~5.25V。由于微机电路是时序数字电路,它需要稳定的时钟信号,因此在电源上电时,只有当VCC超过4.75V低于5.25V以及晶体振荡器稳定工作时,复位信号才被撤除,微机电路开始正常工作。单片机的复位分为上电自动复位、按键手动复位两种和看门狗强制复位三种等。上电复位通常利用电容的充放电来实现,按键复位则可分为按键脉冲复位和按键电平复位两种,看门狗复位则通过外接看门狗电路或软件看门狗程序实现。常见的有上电复位和按键复位电路。
2.7时钟电路
时钟电路可以简单定义如下:1.就是产生象时钟一样准确的振荡电路;2.任何工作都按时间顺序。用于产生这个时间的电路就是时钟电路。时钟电路一般由晶体震荡器、晶震控制芯片和电容组成。时钟电路应用十分广泛,如电脑的时钟电路、电子表的时钟电路以及MP3、MP4的时钟电路。
时钟电路用于产生单片机的基本时钟信号,是用来配合外部晶体实现振荡的电路,这样可以为单片机提供运行时钟,如果运行时钟为0 的话,单片机就不工作,当然超出单片机的工作频率的时钟也会导致单片机不工作。时钟电路是微型计算机的心脏,它控制着计算机的工作节奏,CPU就是通过复杂的时序电路完成不同的指令功能的。MCS-51的时钟信号可以由两种方式:一种是内部方式,利用芯片内部的振荡电路,产生时钟信号:另一种为外部方式,时钟信号由外部引入。如果没有时钟电路来产生时钟驱动单片机,单片机是无法工作的[12]。AT89S51的时钟信号可由内部振荡器产生,也可由外部电路直接提供。
内部振荡器的输入和输出脚分别为XTAL1和XATL2,由XTAL2给单片机内部电路提供时钟信号。当时钟信号由外部电路提供时,外部时钟引入XTAL2,而XTAL1脚接地。
2.8显示部分:LCD
显示部分是LCD1602液晶显示,
1.018.jpg

图2-8 正常工作LCD1602显示

2.8.1 LCD1602液晶简介
LCD1602分为带背光和不带背光两种,基控制器大部分为HD44780,带背光的               比不带背光的厚,是否带背光在应用中并无差别,两者尺寸差别如图2-9所示。
1.019.jpg

图2-8-1 LCD1602规格

字符型液晶显示模块是一种专门用于显示字母、数字、符号等点阵式LCD,目前常用16*1,16*2,20*2和40*2行等的模块
2.8.2 LCD1602主要技术参数
表2-8-2 1602的主要技术参数
工作电压:
4.5—5.5V
容量
16×2个字符
最佳工作电压
5.0V
工作电流
2.0mA
字符尺寸
2.95×4.35(W×H)mm


2.8.3引脚功能说明
1602液晶模块的读写操作,屏幕和光标的操作都是通过指令编程来实现的。

表2-8-3 引脚接口说明表

LCD1602采用标准的14脚(无背光)或16脚(带背光)接口,各引脚接口说明如表编号

符号

引脚说明

1

VDD

正极

2

VSS

3

VL

液晶显示偏压

4

RS

寄存器选择

5

R/W

读/写选择

6

EN

使能信号

7

D0

数据

8

D1

数据

9

D2

数据

10

D3

数据

11

D4

数据

12

D5

数据

13

D6

数据

14

D7

数据

15

BLA

背光源正极

16

BLK

背光源负极




1.020.jpg

图2-8-3  LCD1602的管脚图


1.021.jpg

图2-8-3 1602字符型液晶显示器实物图

2.8.4  LCD1602的RAM地址映射及标准字库表
液晶显示模块是一个比较慢的显示器件,因此在执行指令之前要首先确认模块的忙标志处于低电平,表示空闲,不然此指令失效,输入显示字符地址后会显示字符,图是1602的内部显示地址。

1.022.jpg

图2-8-4 1602LCD内部显示地址
2.8.5指令说明
LCD1602液晶模块内部的控制器控制指令:
  • 清屏指令
指令功能
                       指令编码


执行时间/ms

清屏
RS
R/W
DB7
DB6
DB5
DB4
DB3
DB2

DB1

DB0

1.64

  0
0
0
0
0
0
0
0

0

1

功能:
①清除液晶显示器,即将DDRAM的内容全部填入“空白”的ASCII码20H;
②光标归位,即将光标撤回液晶显示屏的左上方;
③将地址计数器(AC)的值设为0.
  • 光标归位指令
指令功能
                       指令编码


执行时间/ms

光标归位
RS
R/W
DB7
DB6
DB5
DB4
DB3
DB2

DB1

DB0

1.64

  0
0
0
0
0
0
0
0

1

X


功能:
①把光标撤回到显示器的左上方;
②把地址计数器(AC)的值设置为0;
③保持DDRAM的内容不变
(3)进入模式设置指令
指令功能
                       指令编码


执行时间/us

进入模式设置
RS
R/W
DB7
DB6
DB5
DB4
DB3
DB2

DB1

DB0

40

  0
0
0
0
0
0
0
I

I/D

S

功能:
设定每次定入1位数据后光标的以为方向,并且设定每次写入的一个字符是否移动。参数设定的情况如下所示:
位名         设置
I/D          0=写入新数据后光标左移      1=写入新数据后光标右移
S            0=写入新数据后显示屏不移动  1=写入新数据后显示屏整体右移一个字符
(4)显示开关指令控制

指令功能

                       指令编码


执行时间/us

显示开关控制

RS

R/W

DB7

DB6

DB5

DB4

DB3

DB2

DB1

DB0

40

  0

0

0

0

0

0

1

D

C

B

功能:
控制显示器开/关、光标显示/关闭以及光标是否闪烁,参数设定的情况如下:
位名         设置
D             0=显示功能关    1=显示功能开
C             0=无光标        1=有光标
B             0=光标闪烁      1=光标不闪烁
  • 设定显示屏或光标移动方向指令

指令功能

                       指令编码


执行时间/us

设定显示屏或光标移动方向

RS

R/W

DB7

DB6

DB5

DB4

DB3

DB2

DB1

DB0

40

  0

0

0

0

0

1

S/C

R/L

X

X

功能:使光标移位或使整个显示屏幕移位。参数设定的情况如下:
S/C        R/L       设定情况
0           0        光标左移1格,且AC值减1
0           1        光标右移1格,且AC值加1
1           0        显示器上字符全部左移1格,但光标不动
1           1        显示器上字符全部右移1格,但光标不动
(6)功能设定指令

指令功能

                       指令编码


执行时间/us

功能设定

RS

R/W

DB7

DB6

DB5

DB4

DB3

DB2

DB1

DB0

40

  0

0

0

0

1

DL

N

F

X

X

功能:设定数据总线为数、显示的行数及字型。
参数设定的情况如下:
位名             设置
DL               0=数据总线为4位       1=数据总线为8位
N                0=显示1行             1=显示2行
F                0=5×7点阵/每字符      1=5×10点阵/每字符
(7)设定CGRAM地址指令

指令功能

                       指令编码


执行时间/us

设定CGRAM地址

RS

R/W

DB7

DB6

DB5

DB4

DB3

DB2

DB1

DB0

40

  0

0

0

1

       CRGAM的地址(6位)

功能:设定下一个要存入数据的CGRAM的地址。
DB5 DB4 DB3为字符号,也就是将来要显示该字符时要用到的字符地址(000-111)(能定义8个字符)
DB2 DB1 DB0为行号。(000-111)(八行)
  • 设定DDRAM地址指令


指令功能

                       指令编码


执行时间/us

设定DDRAM地址

RS

R/W

DB7

DB6

DB5

DB4

DB3

DB2

DB1

DB0

40

  0

0

  1

DDRAM的地址(7位)

功能:设定下一个要存入数据的DDRAM的地址
(9)读取忙信号或AC地址指令

指令功能

                       指令编码


执行时间/us

读取忙碌信号或AC地址

RS

R/W

DB7

DB6

DB5

DB4

DB3

DB2

DB1

DB0

40

  0

1

FB

              AC内容(7位)

功能:
①读取忙碌信号BF的内容,BF=1表示液晶显示器忙,暂时无法接受单片机送来的数据或指令;当BF=0时,液晶显示器一接受单片机送来的数据或指令
(10)数据写入DDRAM或CGRAM指令一览

指令功能

                       指令编码


执行时间/us

数据写入到DDRAM或CGRAM

RS

R/W

DB7

DB6

DB5

DB4

DB3

DB2

DB1

DB0

40

1

0

要写入的数据D7-D0

功能:
①将字符码写入DDRAM,以使液晶显示屏显示出相对应的字符
②将使用着自己设计的图形存入CGRAM
     DB7 DB6 DB5可为任何数据,一般取“000”
  DB4 DB3 DB2 DB1 DB0对应于每行5点的字模数据
  • 从CGRAM或DDRAM读出数据的指令一览

指令功能

                       指令编码


执行时间/us

从CGRAM或DDRAM读出数据

RS

R/W

DB7

DB6

DB5

DB4

DB3

DB2

DB1

DB0

40

  1

1

           要读出的数据D7-D0

功能:读取DDRAM或CGRAMD中的内容
基本操作时序:
读状态    输入:RS=L,RW=H,E=H      输出:DB0-DB7=状态字
写指令    输入:RS=L,RW=L,E=下降沿脉冲  DB0-DB7=指令码  输出:无
读数据    输入:RS=H,RW=H E=H        输出:DB0-DB7=数据
写数据    输入:RS=H,RW=L,E=下降沿脉冲  DB0-DB7=数据    输出:无
2.8.6显示设置
DDRAM是显示数据RAM,用来寄存带显示的字符代码,共80个字节。


显示位置

1

2

    3

4

5

6

7

.......

40

DDRAM

地址

第一行

00H

01H

02H

03H

04H

05H

06H

......

27H

第二行

40H

41H

42H

43H

44H

45H

46H

......

67H

表2-8-6 地址和屏幕的对应关系

    想要在LCD1602屏幕的第一行第一列显示一个“A”字,就要向DDRAM的00H地址写入“A”字的代码就行了。具体的写入是要按LCD模块的指令格式来进行的。在1602中用到16个即可。

第二行也一样用到前16个地址。

表2-8-6 对应关系

00H

01H

02H

03H

04H

05H

06H

07H

08H

09H

0AH

0BH

0CH

0DH

0EH

0FH

40H

41H

42H

43H

44H

45H

46H

47H

48H

49H

4AH

4BH

4CH

4DH

4EH

4FH

               

在PC上我们只要打开文本文件就能在屏幕上看到对应的字符是因为在操作系统里和BIOS里都固化有字符字模。字模代表了是在点阵屏幕上点亮和熄灭的信息数据。例如“A”字的字模:

  01110          ○■■■○

  10001          ■○○○■

  10001          ■○○○■

10001          ■○○○■

11111          ■■■■■

10001          ■○○○■

10001          ■○○○■

上图左边的数据就是字模数据,右边就是将左边数据用“○”代表0,用“■”代表1。

想要在LCD1602屏幕的第一行第一列显示一个“A”字,就要向DDRAM的00H地址写入“A”字的代码41H即可。在LCD模块上也固化了字模存储器,这就是CGROM和CGRAM HD44780内置了192个常用字符的字模,存于字符产生器CFROM Character Generator ROM中,另外还有8个允许用户自定义的字符产生RAM,称为CGRAM Character Generator RAM。

2.9本章小结
本章节主要有两部分,第一部分主要介绍了温湿度实时监测和控制的意义,第二部分主要介绍了设计的总体思路,以及元器件的选择,并加以详细的解释。

              第3章 硬件设计

    单片机是整个系统的控制中枢,它指挥外围器件协调工作,从而完成特定的功能,硬件实现上采用模块化设计,每一模块只实现一个特定功能,最后再将各个模块搭接在一起,这种设计方法可以降低系统设计的复杂性,本系统主要硬件设计包括电源电路、蜂鸣器电路、晶振电路,LCD显示电路以及温湿度传感器电路[11]。

3.1主控制电路和测温时控制电路

    本次硬件的核心就是AT89S511,其他的外围电路都是围绕它所设计的。数字温湿度传感器的DHT11的DATA口连接单片机AT89S51的P3.0口。显示电路就是把LCD1602和单片机的P1口分别相连,当温度或湿度高于预设值的时候蜂鸣器蜂鸣报警,代表控制系统的指示灯常亮,增加单片机的输出能力,增加单片机的输出电流,故使用电阻排来完成[14]。本系统采用的是上电复位,充电之后,RST被拉至高电平,单片机进入工作状态。

     AT89S51中有一个用于构成内部振荡器的高增益反相放大器,引脚XTAL1和XTAL2分别是放大器的输入端和输出端。这个放大器与作为反馈元件的片外石英晶体或者陶瓷谐振器构成自激振荡器,他们与电容C1,C2接在放大器的反馈电路中构成并联震荡电路,虽然电容没有一个严格的要求,但是电容的大小会轻微影响振荡频率的高低、温度稳定性以及振荡器工作的稳定性。



1.023.jpg

图3-1 系统电路原理图

3.2主要模块的电路3.2.1系统的蜂鸣器电路
微型计算机控制系统中,为了安全起见,对于一些重要的参数或系统,都设定有紧急状态报警系统,以便于提醒操作人员注意,或者采取紧急措施,本设计采用把计算机采集的数据进行数据处理、标度变换、数字滤波之后,与该参数上下限与设定值进行比较,不符合标准值则进行报警,否则就作为采样的正常值,进行显示[12]。
本设计采用峰鸣音报警电路。如图所示。蜂鸣器额定电流≤30Ma,而对于AT89S51单片机,P3口的灌电流为15mA,由此可见,仅靠单片机的P3口电流是不能驱动蜂鸣器的,必须使用晶体管放大电路,为了使单片机的功率更小,所以使用PNP型晶体管,当外部环境的温度或者湿度超过预设值的时候,基级变为低电平,蜂鸣器导通鸣叫[11]。
1.024.jpg

图3-2-1  蜂鸣器实物图


1.025.jpg

图3-2-1  蜂鸣器电路


3.2.2晶振电路
    单片机系统都有晶振,在单片机系统中晶振的作用非常大,全称叫做晶体振荡器,它结合单片机内部电路产生所需时钟频率,单片机晶振提供的时钟频率越高,那么单片机的运行速度就会越快,单片机的一切指令执行都是建立在单片机晶振所提供的时钟频率。在通常的工作条件下,普通的晶振频率的绝对精度可以达到百万分之五十,高级晶振精度更高,有些晶振还可以由外加的电压在一定范围内调整频率,称为压榨振荡器,在共振的状态下晶振用一种能把电能和机械能相互转化的晶体工作,以提供稳定,精确的单频振荡。
    单片机晶振的作用是为系统提供及本周的时钟信号,通常一个系统共用一个晶振,以便于各部分保持同步,有些通讯系统的基频和射频使用不同的晶振,而是通过电子调整频率的方法保持同步。晶振通常与锁相环电路配合使用,以提供系统所需的时钟频率,可以用于同一个晶振项链的不同锁相环来提供的。单片机AT89S51的晶振电路采用无源晶振,微调电容取22uf。

1.026.jpg

图3-2-2晶振电路

3.2.3 温湿度设置(按键)电路
1.027.jpg

图3-2-3 按键电路

3.2.4显示电路
    在日常生活中,我们对液晶显示器并不陌生,它已作为很多电子产品的通过器件,比方在计算器、万用表、电子表及很多家用电子产品中都可以看到,显示的主要是数字、专用符号和图形。

    显示模块选用1602字符型液晶模块,它是目前工控系统中使用最广泛的液晶屏之一,由于它显示的质量高,电路图如图3.4所示,1602字符型液晶模块是点阵型液晶,驱动方便,经过编程后显示内容多样化[2]。


1.028.jpg

图3-2-4 显示电路

3.2.5传感器电路
    DHT11是数字型温湿度传感器,可直接以数字方式传输所采集的当前环境温湿度,DHT11采用的是单总线通信,因此只需将单片机的一个I/O端口与DHT11的通信接口连接就可以实现数据的采集和传送,相对于其他电路来说比较简单。如图3.4所示:
1.029.jpg

图3-2-5 传感器电路


3.2.6复位电路
    本次设计采用的是上电复位,当RST引脚上出现了两个周期以上的高电平就会触发内部复位,这里的EA端与复位电路无关,由于数据都放在了内部存储器,所以连接EA只是直接拉高引脚。
1.030.jpg

图3-2-6 复位电路

3.2.7电源指示灯电路
1.031.jpg

图3-2-7  电源指示灯电路

3.3硬件实施控制3.3.1温湿度设置
温湿度上下限控制设置如图所示。
1.032.jpg

(1)湿度上限设置界面      

1.033.jpg       

(2)湿度下限设置界面

1.034.jpg

(3)温度度下限设置界面               

1.035.jpg

(4)温度度上限设置界面

    图4-1-1 温湿度上下限设置


3.3.2工作指示灯和电源
1.036.jpg
代表控制设备启动的灯泡(加热、降温;加湿、除湿)
1.037.jpg







3.3.3功能按键
1.038.jpg
3.4设备运行
    本次设计主要是能够实时显示出当前确切的温湿度,并且在高于预设值的时候能够发出蜂鸣。一旦接通电源,工作指示灯常亮,蜂鸣器首先蜂鸣,表示系统正常运行。接着LCD初始化,采用八位的数据端口,两行显示,其中第一行显示的湿度预设值,根据键盘我们可以加减数值,第二行显示的是实时的温湿度值,在程序设计中,分别定义温湿度参数,根据数据转换过来的数值,判断是否超过了预设值,本次设计温度初试值设定为32℃,湿度初始设定为34%,等待传送的数值连续20次都超过预设值的话,蜂鸣器便会蜂鸣警报,1602显示当前的温湿度值,温湿度不在标准范围内,温度和湿度的控制措施灯亮,表示对温度和湿度不在范围内采取相应措施。采取措施后,传输数据正常,再次循环判断,如果没有超过预设值,蜂鸣器不会蜂鸣,1602正常显示,不会启动控制措施,也同样再次循环。
    按键说明:左起第一个是功能键,按一次进入报警温度设置此时出现H 40,进行上限温度设置,此时设置H高温报警温度并闪烁显示;按第二次,进行下限温度设置此时出现L 03,此时设置L低温报警温度并闪烁显示;再按一次即第三次,则恢复正常的温度显示界面。第二个按键是增加键,可以对上限温度或下限温度进行增大调整第三个按键是减小键,可以对下限温度或下限温度进行减小调整;湿度同理。这样便可设置好温、湿度的上、下限。
3.5控制设备:
采用设备:
(1)风扇或者排湿器:负责系统的降温工作。
风扇可以是USB借口的或者与电源相连接的,根据本设计需要,由于在粮库内使用,所以用电源连接的风扇较为适合。小风扇材料的选择主要注意它的耐性和稳定性,要选择不变形的塑料材质,苯乙烯聚合物是一种热塑性树脂,无色、无味,而且有光泽的透明固体,具有耐化学腐蚀性、耐水性和优良的电绝缘性和高频点介性。
排潮器根据功率大小还有性价比来进行选择,做了市场调查以后,根据粮库环境,选择了ZD-8138C 空气排湿机,完全满足粮库储存粮食的要求。其中内部压缩机采用世界名牌高效涡漩式压缩机,质量可靠、高效节能;风机采用工业通风专业的外转子风机,具有使用寿命长、噪音低、出风量大的有点;保护功能系统完善,电源缺相、错相;压缩机过流、高低压力、延时保护、风机过载、电加热过热、风机压差保护。主要性能参数指标如下。
表3-5 排潮器的主要性能参数

除湿量

5.75公斤/小时( 138升/天)

电源

220V~50Hz

环境温度

5~58℃

循环风量

1725m3

运转噪音

50dB

压缩机保护

三分钟延时

适用面积(3m/高)

100 ~150

(2)加热设备:负责系统的加热工作。
加热设备:本设计采用的是电加热设备,不锈钢加热器在耐高温不锈钢无缝管内均匀地分布高温电阻丝,在空隙部分致密地填入导热性能和绝缘性能均良好的结晶氧化镁粉,这种结构不但先进,热效率高,而且发热均匀,当高温电阻丝中有电流通过时,产生的热通过结晶氧化镁粉向金属管表面扩散,再传递到被加热件或空气中去,达到加热的目的。针对目前市场的需求,主要不锈钢加热器有304和316l不同材质,供客户选择。目前使用比较多的有直型加热管、u型加热管、w型加热管、螺旋式加热器、法兰式加热管、异型加热器、易燃易爆加热管、重油加热器等系列产品。为了降低成本,耐用环保,我们采用的是直型加热管。
(3)喷雾设备:负责系统的加湿工作。
自动洒水器:1. 材料为工程塑料和不锈钢,强度高,耐化学物质(化肥、农药等)腐蚀。2. 整体压铸成型,结构强度高。3. 整个内芯可从喷头顶部旋出(外壳与管道间的连接不动),清洗修方便。4. 1806和1812型有两个接口(底部和侧壁)供用户选择。我们选择1812型。5. 接口尺寸:1/2¨阴螺纹;射程:90m-120m。把洒水器内注满水,如若是大型功耗的洒水器,每100平方米只需放置一个即可,若是中小型工号的洒水器,每100平方米放置2-3个即可。本设计采用的是大型功耗洒水器,全面喷洒形,喷洒面积90-120平方米,流量Q=130-150L/H。美中不足的是需要人力检测容器内剩余水的多少,需要人在一天内观察一次。
(4)排潮设备:负责系统的去湿工作。

烘干节能排潮系统:包括烘干排潮室,沿所述烘干排潮室纵向间隔垂直设置的隔板将其自后至前分为多个加热单元[3];所述每个隔板均自烘干排潮室顶壁向下延伸至中部;在位于隔板下方的烘干排潮室内沿纵向设置有多条输送链条;在所述每个加热单元地板下方分别开设有气体通道,所述气体通道的进、出气口分别位于本加热单元的地板表面;相邻两单元的进、出气口通过管道、抽风机相连通,位于最右端加热单元的出气口延伸出烘干排潮室之外。本实用新型优点在于从后向前分若干区,每个区从地下管道抽后区风送往前区,上吹下吸,依次进行,热能反复利用,大大降低了热能消耗,同时排向大气的热量大为减少,起到了很好的节能、环保效果。

  本系统控制设备采用的加湿设备、除湿设备、加温设备、降温设备作为控制器,加湿设备、除湿设备、加温设备、降温设备分别控制湿度与温度,使得粮库的温湿度得到合理控制。
(1)当温度高于预设的标准范围内,蜂鸣响起,并根据报警信号和当前温度显示,小型风扇、排潮器自行启动,当达到标准范围内,温度恢复正常,蜂鸣停止,小型风扇、排潮器自动关闭,工作指示灯亮,设备正常运行;
(2)当温度低于预设的标准范围内,蜂鸣响起,根据报警信号和当前温度显示,电加热设备自行启动,当温度归于正常值时,蜂鸣停止,电加热设备关闭,工作指示灯亮,设备正常运行;
(3)当湿度高于预设的标准范围内,蜂鸣响起并根据报警信号和当前湿度值系统自动启动烘干节能排潮系统,达到去湿效果,当湿度降低到正常范围内时,蜂鸣停止,烘干节能排潮系统关闭,工作指示灯亮,设备正常运行;
(4)当湿度低于预设的标准范围内,蜂鸣响起并根据报警信号和当前湿度值系统启动自动洒水器,达到加湿效果后,满足粮库工作的湿度范围内,工作指示灯亮,设备正常运行。
(5)如若温湿度同时不在标准范围内,两个功能性设备同时启动。

3.6 本章小结
本章节主要介绍了硬件设计的总思路及其各部分电路的主要设计方法,详细的给出了各个模块(蜂鸣器,晶振电路,显示电路,按键电路,传感器电路,复位电路,电源指示灯电路)的电路设计。初步连接构造硬件,并且设计了控制部分,较细致的介绍了硬件运行。

第4章  软件设计

软件设计是本次设计中不可缺少的环节,贯穿了整个毕业设计,是本次设计能够完成的最重要的环节之一。
4.1系统流程图
根据温湿度监控系统功能,系统软件流程图如图4-1所示:











图4-1系统软件流程图



4.2按键流程图
按键检测过程中,流程如下图4-2所示:


1.057.jpg


                        图4-2 按键检测的流程图

4.3 Protues运行结果
1.058.jpg
4.4 本章小结
本章主要给出了系统流程图,了解了系统流程更好的做出硬件。通过Proteus软件或Protel99SE绘制仿真图、流程图。


结  论

本文设计的是粮库的温湿度监测报警、控制系统。由高性价比单片机对数字温湿度传感器控制,通过温、湿度传感器,实现对温湿度数据采集,并对数据处理、LCD1602显示屏显示即时温、湿度值。当温湿度数据超出设定温、湿度值时,由单片机驱动报警装置,实现现场报警功能,控制系统自行启动,调节不在范围内的温、湿度,使其恢复正常。
首先,介绍了设计的核心组成部分单片机AT89S51的的基本构成和原理,简要的说明了单片机的最小系统,中断系统,复位电路和时钟电路。然后介绍了显示部分LCD1602的各个引脚和指令说明,为下面的编程做准备。
其次,介绍了本次设计的传感器:DHT11温湿度传感器。然后给出了主要模块电路的结构,在硬件连接以后,初步的硬件运行结果,以实物图的形式进行了说明。介绍了控制温、湿度的设备,在根据不同环境下的应用和选择。
最后,说明了用到的软件,给出了总体的原理图和流程图和Proteus运行结果,以便更好的理解。
最后程序检查正常,焊接成品,硬件运行正常,满足了初步设计要求,达到了粮库温、湿度控制的目的。在设计中还有不足的部分,在现场控制时,保证传感器不受条件因素的影响是很重要的,由于研究时间和条件的限制,粮库温、湿度还有许多地方需要深入研究。


参考文献
[1] 孙宏宇.牛舍环境及供料自动控制系统的研究[D].吉林农业大学,2008:24
[2] 汤武辉.Proteus仿真软件与单片机实验教学[N].长江大学学报(自然版),2010,(3):33-36.
[3] 王剑,朱涛,李冬.protel 99se电路仿真在电子实验教学中的应用[J].2010,(5):38-40.
[4] 王国防.基于nRF24E1的数据采集及无线传输系统的研究[D].河北科技大学,2009:8-10.
[5] 张冬林,李鑫,戴梅.基于DHT11的低成本蚕室温湿度自动控制系统设计[J].现代农业科技,2010,(18):11.
[6] 徐春河.浅谈AT89S51[J].制造业自动化,2010,(12):6.
[7] 薛玲,孙曼,张志会,夏莉丽,魏希文.基于单片机AT89S51的温湿度控制仪[J].2010, (7):12-14.
[8] 吴汉清.常用的典型单片机资料[J].无线电,2007,(11):50-57.
[9] 叶健斌.基于单片机嵌入式系统的GPS应用[J].电子质量,2008,(7):16-24.
[10] 王静.通用库房温湿度测控系统[D].中国海洋大学,2009:5.
[11] 刘宝元,张玉虹,姜旭,段存丽.基于单片机的温湿度监控系统设计[J].国外电子测量技术,2009,(12):30-33,35.
[12] 陈汝全.实用微机与单片机控制技术[M].电子科技大学出版社.2005:16-17.
[13] 张广军,黄俊钦.温度传感器现场动态校准方法与实验研究[J] 北京航空航天大学学报 1997:7-9.
[14] 李建民.单片机在温度控制系统中的应用[M].江汉大学学报,1996:72-78.
[15] Vizimuller, P.Basic knowledge of transducers[J].World Cement.2000
[16] Tulone, S. Madden.Quorum systems for wireless sensor networks[J].2007

致  谢

四年的大学生活接近尾声,我的毕业设计也顺利的完成了,这里首先向我的指导老师赵静老师表示最诚挚的感谢,同时也感谢那些帮助过我的同学们。
在本次的毕业设计中赵老师给我提供了极大的帮助,首先在一开始的选题中我便遇到了难题,由于当时选题的时候过于疏忽大意,没有认真的加以分析,所以走了很多弯路,赵老师便告诉我,最重要的就是找对方向找准目标,选择一个自己擅长和喜欢的方向不仅能够促使我们积极的完成设计,而且对于自己来说也是充满着兴趣,这样做出来的东西会更加完美和轻松,其次,在毕业设计的过程中,赵老师不厌其烦的为我们讲解了毕业设计中可能出现的问题,并为我们提供了完整的毕业设计模板参考,无论我遇到什么样的问题,她总能很耐心的为我们讲解,同时她每个周一要求见面一次,督促我们抓紧时间完成毕业设计,每次见面她都要求我详解上周所做的东西以及自己下周要做的东西,有问题或者不合理的地方她便为我指出来,加以指导。赵老师认真负责的态度让我倍受感激。同时在此也感谢其他同学,解决了许多我在毕业设计中遇到的问题,特别是刚开始软件的学习中,都给予了我很大的帮助。在此向所有毕业设计的过程中给予我帮助的老师们和同学们最诚挚的谢意。


单片机源程序如下:
  1. #include

  2. #include "key_contrl.h"
  3. #include "lcd1602.h"


  4. #define LCM_Data P1
  5. #define Busy 0x80 //用于检测LCM状态字中的Busy标识

  6. extern int temp_value, humi_value;
  7. extern int flag;
  8. extern int temp;

  9. sbit red=P2^6;
  10. sbit blue=P2^7;

  11. sbit LCM_RW= P2^4; //定义引脚
  12. sbit LCM_RS= P2^5;
  13. sbit LCM_E= P2^3;


  14. sbit beep = P0^6; //beep = 0时候发声


  15. extern int temph,templ,disp_mode,huih,huil;
  16. extern char tel,teh,hh,hl;

  17. //写数据

  18. void alarm()
  19. {
  20.               beep=0;

  21.               Delay5Ms();
  22.               Delay5Ms();
  23.               beep=1;

  24.               Delay5Ms();
  25.               Delay5Ms();

  26. }


  27. void WriteDataLCM(unsigned char WDLCM)
  28. {
  29. ReadStatusLCM(); //检测忙
  30. LCM_Data = WDLCM;
  31. LCM_RS = 1;
  32. LCM_RW = 0;
  33. LCM_E = 0; //若晶振速度太高可以在这后加小的延时
  34. LCM_E = 0; //延时
  35. LCM_E = 1;
  36. }
  37. //写指令
  38. void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测
  39. {
  40. if (BuysC) ReadStatusLCM(); //根据需要检测忙
  41. LCM_Data = WCLCM;
  42. LCM_RS = 0;
  43. LCM_RW = 0;
  44. LCM_E = 0;
  45. LCM_E = 0;
  46. LCM_E = 1;
  47. }
  48. //读数据
  49. unsigned char ReadDataLCM(void)
  50. {
  51. LCM_RS = 1;
  52. LCM_RW = 1;
  53. LCM_E = 0;
  54. LCM_E = 0;
  55. LCM_E = 1;
  56. return(LCM_Data);
  57. }
  58. //读状态
  59. unsigned char ReadStatusLCM(void)
  60. {
  61. LCM_Data = 0xFF;
  62. LCM_RS = 0;
  63. LCM_RW = 1;
  64. LCM_E = 0;
  65. LCM_E = 0;
  66. LCM_E = 1;
  67. while (LCM_Data & Busy); //检测忙信号
  68. return(LCM_Data);
  69. }
  70. void LCMInit(void) //LCM初始化
  71. {
  72. LCM_Data = 0;
  73. WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
  74. Delay5Ms();
  75. WriteCommandLCM(0x38,0);
  76. Delay5Ms();
  77. WriteCommandLCM(0x38,0);
  78. Delay5Ms();
  79. WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
  80. WriteCommandLCM(0x08,1); //关闭显示
  81. WriteCommandLCM(0x01,1); //显示清屏
  82. WriteCommandLCM(0x06,1); // 显示光标移动设置
  83. WriteCommandLCM(0x0C,1); // 显示开及光标设置
  84. }
  85. //按指定位置显示一个字符
  86. void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
  87. {
  88. Y &= 0x1;
  89. X &= 0xF; //限制X不能大于15,Y不能大于1
  90. if (Y) X |= 0x40; //当要显示第二行时地址码 0x40;
  91. X |= 0x80; // 算出指令码
  92. WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码
  93. WriteDataLCM(DData);
  94. }
  95. //按指定位置显示一串字符
  96. void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
  97. {
  98. unsigned char ListLength;
  99. ListLength = 0;
  100. Y &= 0x1;
  101. X &= 0xF; //限制X不能大于15,Y不能大于1
  102. while (DData[ListLength]>0x20) //若到达字串尾则退出
  103. {
  104. if (X <= 0xF) //X坐标应小于0xF
  105. {
  106. DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
  107. ListLength++;
  108. X++;
  109. }
  110. }
  111. }
  112. //5ms延时
  113. void Delay5Ms(void)
  114. {
  115. unsigned int TempCyc = 5552;
  116. while(TempCyc--);
  117. }
  118. /*void Delay_xMs(unsigned int x)
  119. {
  120.     unsigned int i,j;
  121.     for( i =0;i < x;i++ )
  122.     {
  123.         for( j =0;j<500;j++ );
  124.     }
  125. }
  126. */
  127. void display_temp(void)
  128. {
  129.               DisplayOneChar(0,0,' ');
  130.               DisplayOneChar(1,0,' ');
  131.               DisplayOneChar(2,0,'T');
  132.               DisplayOneChar(3,0,'e');
  133.               DisplayOneChar(4,0,'m');
  134.               DisplayOneChar(5,0,'p');
  135.               DisplayOneChar(6,0,':');
  136.               DisplayOneChar(10,0,'C');
  137.               DisplayOneChar(9,0,0xdf);
  138.               DisplayOneChar(7,0,temp_value/100+0x30);
  139.               DisplayOneChar(8,0,(temp_value/10)-(temp_value/100)*10+0x30);
  140.               DisplayOneChar(11,0,' ');
  141.               DisplayOneChar(12,0,' ');
  142.               DisplayOneChar(13,0,' ');
  143.               DisplayOneChar(14,0,' ');
  144.               DisplayOneChar(15,0,' ');


  145.               DisplayOneChar(0,1,' ');
  146.               DisplayOneChar(1,1,' ');
  147.               DisplayOneChar(2,1,'H');
  148.               DisplayOneChar(3,1,'u');
  149.               DisplayOneChar(4,1,'m');
  150.               DisplayOneChar(5,1,'i');
  151.               DisplayOneChar(6,1,'d');
  152.               DisplayOneChar(7,1,'i');
  153.               DisplayOneChar(8,1,'t');
  154.                             DisplayOneChar(9,1,'y');
  155.               DisplayOneChar(10,1,':');
  156.               DisplayOneChar(11,1,humi_value/100+0x30);
  157.               DisplayOneChar(12,1,(humi_value/10)-(humi_value/100)*10+0x30);
  158.               DisplayOneChar(13,1,'%');

  159.               DisplayOneChar(14,1,' ');
  160.               DisplayOneChar(15,1,' ');
  161. }            

  162. void display_temp1(void)
  163. {

  164.               DisplayOneChar(0,0,' ');
  165.               DisplayOneChar(1,0,'T');
  166.               DisplayOneChar(2,0,'h');
  167.               DisplayOneChar(3,0,':');
  168.               if(flag&teh)
  169.               {
  170.               DisplayOneChar(4,0,0x20);
  171.               DisplayOneChar(5,0,0x20);
  172.               }
  173.               else
  174.               {
  175.               DisplayOneChar(4,0,temph/10+0x30);
  176.               DisplayOneChar(5,0,temph%10+0x30);
  177.               }

  178.               DisplayOneChar(6,0,0xdf);
  179.               DisplayOneChar(7,0,'C');



  180.               DisplayOneChar(8,0,' ');
  181.               DisplayOneChar(9,0,'T');
  182.               DisplayOneChar(10,0,'h');
  183.               DisplayOneChar(11,0,':');
  184.               if(flag&tel)
  185.               {
  186.               DisplayOneChar(12,0,0x20);
  187.               DisplayOneChar(13,0,0x20);
  188.               }
  189.               else
  190.               {
  191.               DisplayOneChar(12,0,templ/10+0x30);
  192.               DisplayOneChar(13,0,templ%10+0x30);
  193.               }
  194.               DisplayOneChar(14,0,0xdf);
  195.               DisplayOneChar(15,0,'C');



  196.                             DisplayOneChar(0,1,' ');
  197.               DisplayOneChar(1,1,'H');
  198.               DisplayOneChar(2,1,'h');
  199.               DisplayOneChar(3,1,':');
  200.                             if(flag&hh)
  201.               {
  202.               DisplayOneChar(4,1,0x20);
  203.               DisplayOneChar(5,1,0x20);
  204.               }
  205.               else
  206.               {
  207.               DisplayOneChar(4,1,huih/10+0x30);
  208.               DisplayOneChar(5,1,huih%10+0x30);
  209.               }
  210.               DisplayOneChar(6,1,'%');
  211.               DisplayOneChar(7,1,' ');



  212.               DisplayOneChar(8,1,' ');
  213.               DisplayOneChar(9,1,'H');
  214.               DisplayOneChar(10,1,'l');
  215.               DisplayOneChar(11,1,':');
  216.                             if(flag&hl)
  217.               {
  218.               DisplayOneChar(12,1,0x20);
  219.               DisplayOneChar(13,1,0x20);
  220.               }
  221.               else
  222.               {

  223.               DisplayOneChar(12,1,huil/10+0x30);
  224.               DisplayOneChar(13,1,huil%10+0x30);
  225.               }
  226.               DisplayOneChar(14,1,'%');
  227.               DisplayOneChar(15,1,' ');
  228. }            


  229. void displayfun1()
  230. {
  231.               display_temp();

  232. }

  233. void displayfun2()
  234. {
  235.               display_temp1();            
  236. }


  237. void display()
  238. {

  239.                             if((((temp_value/10)%100)<templ)||(((humi_value 10)%100)<huil))
  240.                             {beep=0;red=0;}                //温度低于下限值,报警
  241.                             else if(((temp_value/10)%100)>=temph || ((humi_value/10)%100)>=huih)
  242.                                           {beep=0;blue=0;}      //温度高于或等于上限值,报警
  243.                             else {beep=1;red=1;blue=1;}

  244. //                            if(((humi_value/10)%100)<huil){beep=0;led=0;} 温度低于下限值,报警
  245. //                            else if(((humi_value/10)%100)>=huih)beep=0;      //温度高于或等于上限值,报警
  246. //                            else {beep=1;led=1;}


  247.               if(!disp_mode)
  248.                             displayfun1(); //显示正常
  249.               else
  250.                             displayfun2(); //设置界面

  251. }
  252. #include "dht11.h"
  253. #include


  254. //请根据自己的dht11 接的IO 口来改动位定义


  255. sbit dht11 = P3^0;
  256. //防止在与硬件通信时发生死循环的计数范围

  257. #define NUMBER 20
  258. #define SIZE 5

  259. static unsigned char status;

  260. //存放五字节数据的数组
  261. static unsigned char value_array[SIZE];

  262. /*可在其他的文件引用温湿度值,实际是温度的整数的10 倍
  263. 如dht11 读回的温度是26,则temp_value = 260, 湿度同理*/
  264. int temp_value, humi_value;


  265. static unsigned char ReadValue(void);



  266. void Delay_1ms(unsigned int ms)
  267. {
  268.               unsigned int x, y;
  269.               for(x = ms; x > 0; x--)
  270.               {
  271.                             for(y = 124; y > 0; y--);
  272.               }
  273. }
  274. static void DHT11_Delay_10us(void)
  275. {
  276.               unsigned char i;
  277.               i--;
  278.               i--;
  279.               i--;
  280.               i--;
  281.               i--;
  282.               i--;
  283. }
  284. /*读一个字节的数据*/
  285. static unsigned char DHT11_ReadValue(void)
  286. {
  287.               unsigned char count, value = 0, i;
  288.               status = OK; //设定标志为正常状态
  289.               for(i = 8; i > 0; i--)
  290.               {
  291.                             //高位在先
  292.                             value <<= 1;
  293.                             count = 0;
  294.                             //每一位数据前会有一个50us 的低电平时间.等待50us 低电平结束
  295.                             while(dht11 == 0 && count++ < NUMBER);
  296.                             if(count >= NUMBER)
  297.                                           {
  298.                                           status = ERROR; //设定错误标志
  299.                                           return 0; //函数执行过程发生错误就退出函数
  300.                                           }
  301.                             //26-28us 的高电平表示该位是0,为70us 高电平表该位1
  302.                             DHT11_Delay_10us();
  303.                             DHT11_Delay_10us();
  304.                             DHT11_Delay_10us();
  305.                             //延时30us 后检测数据线是否还是高电平
  306.                             if(dht11 != 0)
  307.                             {
  308.                             //进入这里表示该位是1
  309.                                           value++;
  310.                             //等待剩余(约40us)的高电平结束
  311.                                           while(dht11 != 0 && count++ < NUMBER)
  312.                                           {
  313.                                                         dht11 = 1;
  314.                                           }
  315.                                           if(count >= NUMBER)
  316.                                           {
  317.                                                         status = ERROR; //设定错误标志
  318.                                                         return 0;
  319.                                           }
  320.                             }
  321.               }
  322.               return (value);
  323. }
  324. //读温度和湿度函数,读一次的数据,共五字节,读出成功函数返回OK, 错误返回ERROR
  325. unsigned char DHT11_ReadTempAndHumi(void)
  326. {
  327.               unsigned char i = 0, check_value = 0,count = 0;
  328.               EA = 0;
  329.               dht11 = 0; //拉低数据线大于18ms 发送开始信号
  330.               Delay_1ms(20); //需大于18 毫秒
  331.               dht11 = 1; //释放数据线,用于检测低电平的应答信号
  332.               //延时20-40us,等待一段时间后检测应答信号,应答信号是从机拉低数据线80us
  333.               DHT11_Delay_10us();
  334.               DHT11_Delay_10us();
  335.               DHT11_Delay_10us();
  336.               DHT11_Delay_10us();
  337.               if(dht11 != 0) //检测应答信号,应答信号是低电平
  338.               {
  339.                             //没应答信号
  340.                             EA = 1;
  341.                             return ERROR;
  342.               }
  343.               else
  344.               {
  345.                             //有应答信号
  346.                             while(dht11 == 0 && count++ < NUMBER); //等待应答信号结束
  347.                             if(count >= NUMBER) //检测计数器是否超过了设定的范围
  348.                             {
  349.                                           dht11 = 1;
  350. ……………………

  351. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

完整论文下载(word格式 可编辑):
基于51单片机的温湿度检测控制系统 .doc (1.1 MB, 下载次数: 661)

评分

参与人数 7黑币 +80 收起 理由
wangjian5201314 + 5 很给力!
spartacus + 5 共享资料的黑币奖励!
嘻嘻LI + 5 赞一个!
xinghang + 5 共享资料的黑币奖励!
51@11 + 5 很给力!
雷猴嘛 + 5 好贴啊,楼主好人啊,我刚好要做一个温湿控.
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

雷猴嘛 发表于 2017-5-23 15:47 | 显示全部楼层
楼主做的很完整很全面,赞一个,但是我黑币不够,下载不了,我想要那个完整程序
回复

使用道具 举报

雷猴嘛 发表于 2017-5-24 13:29 | 显示全部楼层
楼主,能不能lcd1602,dht,key_contrl的头文件给我,谢了
回复

使用道具 举报

13625542024 发表于 2017-6-21 22:22 | 显示全部楼层
我也要做个温湿度系统 不太会
回复

使用道具 举报

51@11 发表于 2017-6-24 14:56 | 显示全部楼层
我也在做
回复

使用道具 举报

xinghang 发表于 2017-7-1 16:34 | 显示全部楼层
做的很好,需要完整程序
回复

使用道具 举报

孤独求败 发表于 2017-8-23 12:52 | 显示全部楼层
没黑币,,下不了
回复

使用道具 举报

lbj521712 发表于 2017-10-23 16:34 | 显示全部楼层
回帖现在还有黑币吗
回复

使用道具 举报

xueliang 发表于 2017-11-1 22:59 | 显示全部楼层
楼主,能不能lcd1602,dht,key_contrl的头文件给我,谢了
回复

使用道具 举报

xueliang 发表于 2017-11-1 23:00 | 显示全部楼层
给一下头文件,楼主
回复

使用道具 举报

法克你母亲 发表于 2017-12-6 17:24 | 显示全部楼层
楼主,从能不能lcd1602,dht,key_contrl的头文件给我,谢了
回复

使用道具 举报

412038914 发表于 2017-12-8 20:29 | 显示全部楼层
咱啊~~~!!!
回复

使用道具 举报

412038914 发表于 2017-12-8 20:29 | 显示全部楼层
赞!!!
回复

使用道具 举报

houyang 发表于 2017-12-22 09:52 | 显示全部楼层
挺好的就是没有做出来
回复

使用道具 举报

sunrise99 发表于 2017-12-25 23:26 | 显示全部楼层
赞一个
回复

使用道具 举报

danpianji10 发表于 2018-1-1 20:56 | 显示全部楼层
赞一个
回复

使用道具 举报

f541378915 发表于 2018-1-10 11:11 | 显示全部楼层

...
回复

使用道具 举报

150605200 发表于 2018-1-10 21:35 | 显示全部楼层
楼主有proteus文件吗,求
回复

使用道具 举报

棉质橘猫 发表于 2018-2-1 11:03 | 显示全部楼层
请问为什么既有分块电路又有整体在一起的电路图呢,是整体的电路图是最终结果吗
回复

使用道具 举报

36704803 发表于 2018-2-1 21:15 | 显示全部楼层
请问为什么既有分块电路又有整体在一起的电路图呢,是整体的电路图是最终结果吗
回复

使用道具 举报

hhhhii 发表于 2018-3-2 16:12 | 显示全部楼层
有没有大佬分享一下程序啊啊啊啊啊
回复

使用道具 举报

xiaosong1234 发表于 2018-3-7 20:10 | 显示全部楼层
毕业设计用到了  求黑币啊  或者源代码啊给大佬!
回复

使用道具 举报

xiaosong1234 发表于 2018-3-8 10:38 | 显示全部楼层
l楼主你好  在main函数里面的delay_LCM 和 Scan_Key 这两个函数在整个工程中都没有找到啊 能指点一下吗
回复

使用道具 举报

玩世不恭YY 发表于 2018-4-9 15:54 | 显示全部楼层
做的不错,就是现在我积分不够  哈哈 再接再厉
回复

使用道具 举报

wenye647958 发表于 2018-5-1 14:25 | 显示全部楼层
真棒,正需要
回复

使用道具 举报

向上 发表于 2018-5-2 09:04 | 显示全部楼层
写的很好!
回复

使用道具 举报

快过快过 发表于 2018-5-2 17:02 | 显示全部楼层
我啥时候才能像楼主一样聪明呢,求程序呀
回复

使用道具 举报

吖吖love 发表于 2018-5-2 19:37 | 显示全部楼层
没有黑币,下不了,伤心
回复

使用道具 举报

uoiuouo 发表于 2018-5-2 21:58 | 显示全部楼层
在main函数里面的delay_LCM 和 Scan_Key 这两个函数在整个工程中都没有找到啊 能指点一下吗
回复

使用道具 举报

jw159 发表于 2018-5-4 09:34 | 显示全部楼层
是挺尴尬啊,我也没有黑币啦,急需
回复

使用道具 举报

Armxmr 发表于 2018-5-5 20:32 | 显示全部楼层
厉害厉害厉害
回复

使用道具 举报

向上 发表于 2018-5-7 09:23 | 显示全部楼层
楼主写的很好,不知道能不下不
回复

使用道具 举报

linwenqiang 发表于 2018-5-7 10:22 | 显示全部楼层
楼主做的真的不错,我想要这份代码学习下
回复

使用道具 举报

chb333 发表于 2018-5-7 13:26 | 显示全部楼层
你程序怎么不对呢
回复

使用道具 举报

headache 发表于 2018-5-9 16:55 | 显示全部楼层
这里所有的都仅供参考,这个仿真图和程序完全不匹配。我也不知道这东西怎么能跑的起来,浪费我黑币
回复

使用道具 举报

夜空之巅 发表于 2018-5-13 09:38 | 显示全部楼层
大哥你这头文件是哪个都分不清啊,能穿个压缩包行吗
回复

使用道具 举报

#静水流深# 发表于 2018-5-14 13:02 | 显示全部楼层
吖吖love 发表于 2018-5-2 19:37
没有黑币,下不了,伤心

一样。。。
回复

使用道具 举报

sunnyzhu 发表于 2018-5-22 20:38 | 显示全部楼层

楼主,能不能lcd1602,dht,key_contrl的头文件给我,谢谢
回复

使用道具 举报

meng51 发表于 2018-5-29 11:08 | 显示全部楼层
赞一个,很厉害。
回复

使用道具 举报

王陈 发表于 2018-5-31 11:12 | 显示全部楼层
赞,很给力!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|单片机论坛 |51黑电子论坛单片机 联系QQ:125739409;技术交流QQ群582644647

Powered by 单片机教程网

快速回复 返回顶部 返回列表