找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3632|回复: 0
收起左侧

基于单片机的大型粮仓温湿度检测系统设计论文下载

[复制链接]
ID:328014 发表于 2018-6-30 04:56 | 显示全部楼层 |阅读模式
大型粮仓温湿度检测系统的设计
毕业设计(论文)开题报告
题目
大型粮仓检测系统的设计
目的及意义(含国内外的研究现状分析):
目的:
粮食储藏是国家为防备战争,灾荒或其它突发性事变而采取的有效措施,因此粮食的储藏有重要意义。影响粮食安全储存的主要参数是粮食的温度和湿度。这两者之间又是相互关联的。粮食在正常储藏过程中,含水量一般在12%以下是安全的,不会发生温度突变,一旦粮库进水,结露是粮食的含水量达到20%以上时,由于粮粒受潮胚芽萌发,新陈代谢加快而产生呼吸热是局部粮食温度突然升高,必然引起粮食霉变,可能造成无法挽回的损失因此设计出一种经济适用的粮仓温湿度智能检测系统是非常有必要的。单片机自诞生以来给全世界人类的生活和工作起到了剧烈的作用,利用单片机进行温湿度检测、处理和显示具有实时性好、成本低、稳定性高等优点。通过该系统的设计,这样他们的就业面会更加宽广,也可以满足当今社会对单片机开发人才的大量需求.。
基本内容和技术方案:
设计内容:
1:设计相应的信号采集电路,执行电路等硬件电路。
2:实现各环境要素的自动检测。
3:通过单片机汇编语言编制数据采集,分析采集,显示,修改。参数设计,控制等程序功能模块
设计方案:
1采用模拟温湿度传感器,转换结果需要运算放大器传给单片机,它控制虽然简单但电路复杂,不容易实现对多点温湿度监控,容易出现误差,导致测量结果不准确。
2进行传感器的硬件电路的设计。
3数码管显示,及报警电路的设计。
3.进度安排:
第1-2周:毕业实习,下达毕业设计任务书,查阅相关文献资料,明确研究内容,了解研究所需元件的规格及其价格;
第3周:确定方案,完成开题报告;
第4-6周:完成系统硬件电路的设计。
第7-10周:系统各组成部分的选型;
第11-12周:系统软件框图设计。
第13-15周:完成并修改毕业论文。
第15周: 准备论文答辩。
4.指导教师意见:
指导教师签名:                年    月    日

目  录

摘  要1
Abstract 7
1.绪论 8
1.1选题背景 8
1.2设计目标 8
1.2.1基本功能 8
1.2.2主要技术参数 8
2 设计方案 9
2.1 系统的总体框图 9
2.2温湿度传感器的选择  9
2.3信号采集通道的选择 10
2.4 本章小结10
3 主要芯片简介11
3.1 DHT11数字传感器 11
3.1.1 主要特性11
3.1.2 应用领域11
3.1.3 接口说明11
3.1.4 电源引脚11
3.1.5 封装信息11
3.1.6 DHT11引脚图 12
3.1.7 注意事项12
3.2 ADC0832与单片机89C5113
3.2.1 A/D转换 13
3.2.2 单片机89c51 15
3.3 本章小结22
4 硬件设计23
4.1 显示与报警的设计23
4.1.1 显示电路23
4.1.2 报警电路24
4.2 本章小结25
5 软件设计26
5.1标度变换的实现 26
5.2 主程序流程图26
5.3 T0中断流程图27
5.4 报警子程序流程图28
5.5 温湿度采样子程序流程图29
6 结论30
6.1 总结30
6.2 改进思路30
6.2.1软件方面 30
6.2.2硬件方面 30
参考文献33
附录A 33
附录 B   汇编程序34
附录C  proteus仿真总电路图......................................................
致  谢44


本毕业设计是应用单片机作为控制器设计的温湿度检测系统,由要由温度、湿度采集、AD转换、单片机控制、数码管显示、USB连接器六部分组成 。

本设计是以89C51单片机为控制中心,这种控制芯片具有4KB的快擦写可编程/擦除只读存储器EEPROM、256KB片内RAM、3个16位定时计数器、5个中断源,无需进行系统扩展既可满足任务要求,能较大幅度提高系统的性价比。而温湿度传感器我采用的是DHT11数字温湿传感器,它性价比比较高。DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。

另外该系统除了能显示温湿度以外, 还能设置温湿度报警阀值。

关键词:温湿度;89C51单片机;DHT11传感器;温湿度报警阀

Abstract


The graduation project is based on the single chip design temperature and humidity monitoring system, mainly by temperature, humidity acquisition, AD conversion, microprocessor control, digital display, usb connector composed of six parts.

The design of the control center using 89c51 microcontroller, the chip has 4KB of flash programmable / erasable read only memory EEPROM, 256 KB on-chip RAM, 3 16-bit timer counters, six interrupt sources, both without the need for system expansion to meet mission requirements, can greatly improve the system's cost. The temperature and humidity sensor I use is dht11, he cost effective. DHT11 digital temperature and humidity sensor is a calibrated digital signal output with the temperature and humidity combined sensor. Its application-specific digital modules acquisition and temperature and humidity sensor technology, to ensure that products with high reliability and excellent long-term stability. Sensor includes a resistive element and a sense of wet NTC temperature components and with a high-performance 8-bit microcontroller connected. So the product has excellent quality, fast response, anti-interference ability, high cost performance advantages.

In addition the system in addition to showing the outside temperature and humidity, but also set the temperature and humidity alarm threshold.


Keywords:Temperature and humidity; 89C51 microcontroller;dht11 Sensor



1.绪论                                                                                                                                                                                                                                                                                                                                                                           

1.1 研究背景

由古至今,粮仓粮食的存储是否得当对国家的经济能否正常合理的运行有很大的影响。但是在以前的经济和科技水平有限,所以我国粮食的存储的环境很差,管理落后。粮库管理的重点之一就是要合理布置测温点,经常检查温度变化,以便及时发现粮食的发热点,减少粮食的损失。然而,粮堆的热传递又是那样的缓慢,使人感知极差,需要管理人员经常进入闷热、呛人的仓房内观察温、湿度,不断进行翻仓、通风,这种繁重的体力劳动,不仅对人体有极大地伤害,而且不科学、不及时。所以,粮食虫蛀、霉变的情况时有发生。

1.2设计目标

1.2.1基本功能

1.检测温度、湿度

2.显示温度、湿度

3.过限报警

1.2.2主要技术参数

1.温度检测的范围: -30℃±55℃

2.测量精度: 2℃

3.湿度检测的范围: 20%-90%RH

4.检测精度:5%RH

5.显示方式: 温度:四位显示  湿度:四位显示;

  报警方式: 三极管驱动的蜂鸣音报警


2 设计方案

温湿度监测系统要满足以下条件:温湿度监测系统能完成数据采集和处理、显示、串行通信、输出控制信号等多种功能。由数据采集、数据调理、单片机、数据显示等4个大的部分组成。该测控系统具有实时采集(检测粮库内的温湿度)、实时显示(对监测到的进行显示)、实时警报(根据监测的结果,超出预设定的值的进行蜂鸣警告)的功能。

传感器是实现测量首要环节,是监测系统的关键部件,如果没有传感器对原始被测信号进行准确可靠的捕捉和转换,一切准确的测量和控制都将无法实现。工业生产过程的自动化测量和控制,几乎主要依靠各种传感器来检测和控制生产过程中的各种参量,使设备和系统正常运行在最佳状态,从而保证生产的高效率和高质量。

2.1 系统的总体框图

系统的总体设计框图如图3-1所示。

图3-1  系统总体框图

本设计由信号采集、信号分析和信号处理三个部分组成的。

(一) 信号采集  由dht11温湿度传感器和多路模式选择开关组成;

(二) 信号分析  由A/D转换器和单片机80c51组成;

(三) 信号处理  由串行口LCD显示器和报警系统等组成。

2.2温湿度传感器的选择

     DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高

的可靠性与卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测 温元件,并与一个高性能8位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。每个DHT11传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式储存在OTP内存中,传感器内部在检测信号的处理过程中要调用这些校准系数。单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,信号传输距离可达20米以上,使其成为各类应用甚至最为苛刻的应用场合的最佳选则。产品为4针单排引脚封装。连接方便,特殊封装形式可根据用户需求而提供。

2.3信号采集通道的选择

在本设计系统中,温度输入信号为4路的模拟信号,这就需要多通道结构采用多路分时的模拟量输入通道。这种结构的模拟量通道特点为:对ADC、S/H要求高。处理速度慢。硬件简单,成本低。软件比较复杂。如图2-1所示。

图2-1多路分时的模拟量输入通道



2.4 本章小结

在本章中,主要讲了温湿度传感器的硬件选择和信号采集通道的选择。这些选择是在实用性和价格低廉方面考虑的,如果条件允许可以选择性能更加强大的传感器和一个专门的多路选择的的模块。在下一章中,介绍系统的总体设计所用到主要芯片。


3 主要芯片简介

3.1 DHT11数字传感器

数字温湿度传感DHT11是由广州奥松有限公司生产的一款温湿度一体化的数字传感器。

3.1.1 主要特性

DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC              测温元件,并与一个高性能8位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。每个DHT11传感器都在极为精确的 湿度校验室中进行校准。校准系数以程序的形式储存在OTP内存中,传感器内部在检测信号的处理过程中要调用这些校准系数。单线制串行接口,使系统集 成变得简易快捷。超小的体积、极低的功耗,信号传输距离可达20米以上,使其成为各类应用甚至最为苛刻的应用场合的最佳选则。产品为4针单排引脚 封装。连接方便,特殊封装形式可根据用户需求而提供。

3.1.2 应用领域

该DHT11可以用于暖通空调、测试及检测设备、汽车、数据记录器、消费品、自动控制、湿度调节器及医疗等应用领域。

3.1.3 接口说明

建议连接线长度短于20米时用5K上拉电阻,大于20米时根据实际情况使用合适的上拉电阻。

图3-2  dht11应用电路

3.1.4 电源引脚

DHT11的供电电压为3-5.5V。传感器上电后,要等待1s以越过不稳定状态在此期间无需发送任何指令。电源引脚(VDD,GND)之间可增加一个100nF的电容,用以去耦滤波。

3.1.5 封装信息

图3-3  dht11封装图

3.1.6 DHT11引脚图



图3-4  引脚图

3.1.7 注意事项

温度影响 气体的相对湿度,在很大程度上依赖于温度。因此在测量湿温时,应尽可能保证湿度传感器在同一温度下工作。如果与释放热量的电子元件共用一个印刷线 路板,在安装时应尽可能将DHT11远离电子元件,并安装在热源下方,同时保持 外壳的良好通风。为降低热传导,DHT11与印刷电路板其它部分的铜镀层应尽可 能最小,并在两者之间留出一道缝隙。光线长时间暴露在太阳光下或强烈的紫外线辐射中,会使性能降低。配线注意事项DATA信号线材质量会影响通讯距离和通讯质量,推荐使用高质量屏蔽线。



3.2 ADC0832与单片机89C51

3.2.1 A/D转换

3.2.1.1 A/D转换器的特点

ADC0832 是美国国家半导体公司生产的一种8 位分辨率、双通道A/D转换
芯片。由于它体积小,兼容性强,性价比高而深受单片机爱好者及企业欢迎,
其目前已经有很高的普及率。学习并使用ADC0832 可是使我们了解A/D转换器
的原理,有助于我们单片机技术水平的提高。

ADC0832 具有以下特点:
8位分辨率;
双通道A/D转换;
输入输出电平与TTL/CMOS相兼容;
5V电源供电时输入电压在0~5V之间;
工作频率为250KHZ,转换时间为32μS;
一般功耗仅为15mW;
8P、14P—DIP(双列直插)、PICC 多种封装;
商用级芯片温宽为0°C to +70°C,工业级芯片温宽为−40°C to +85°C;

3.2.1.2 ADC0832元件说明

ADC0832 为 8 位分辨率 A/D 转换芯片,其最高分辨可达 256 级,可以适应一般的模拟量转换要求。其内部电源输入与参考电压的复用,使得芯片的模拟 电压输入在 0~5V 之间。芯片转换时间仅为 32μS,据有双数据输出可作为数据 校验,以减少数据误差,转换速度快且稳定性能强。独立的芯片使能输入,使 多器件挂接和处理器控制变的更加方便。通过 DI 数据输入端,可以轻易的实现 通道功能的选择。

3.2.1.3 芯片顶视图


图3-5 ADC0832 芯片顶视图

芯片接口说明:

GND      芯片参考 0 电位(地)。

DI       数据信号输入,选择通道控制。

DO       数据信号输出,转换数据输出。

CLK      芯片时钟输入。

VCC/REF  输入及参考电压输入(复用)。

CS       片选使能,低电平芯片使能。

CH0      模拟输入通道 0,或作为 IN+/-使用。

CH1      模拟输入通道 1,或作为 IN+/-使用。

3.2.1.4 ADC0832 与单片机的接口电路

ADC0832与单片机的接口电路如图3-7所示

图3-6 接口电路图

3.2.1.5 单片机对 ADC0832 的控制原理

正常情况下 ADC0832 与单片机的接口应为 4 条数据线,分别是 CS、CLK、 DO、DI。但由于 DO 端与 DI 端在通信时并未同时有效并与单片机的接口是双 向的,所以电路设计时可以将 DO 和 DI 并联在一根数据线上使用。(见图 3-7)

当ADC0832未工作时其CS输入端应为高电平此时芯片禁用,CLK 和DO/DI 的电平可任意。当要进行A/D转换时须先将CS使能端置于低电平并且保持低电平直到转换完全结束。此时芯片开始转换工作,同时由处理器向芯片时钟输入端 CLK 输入时钟脉冲,DO/DI 端则使用 DI 端输入通道功能选择的 数据信号。在第1个时钟脉冲的下沉之前 DI 端必须是高电平,表示启始信号。在第 2、3个脉冲下沉之前 DI 端应输入 2 位数据用于选择通道功能,其功能项见表3-1。


表3-1 Adc0832 单端 mux 模式

Mux 地址

频道

Sgl/dif

Odd/sign

0

1

1

0

+


1

1


+


表3-2 Adc0832 多端 mux 模式

Mux地址

频道

Sgl/dif

Odd/sign

0

1

0

0

+

-

0

1

-

+






如表3-1,表3-2所示,当此 2 位数据为“1”、“0”时,只对 CH0 进行单通道转换。当 2 位数据为“1”、“1”时,只对CH1进行单通道转换。当2位数据为“0”、“0”时,将CH0作为正输入端 IN+,CH1 作为负输入端 IN-进行输入。  当 2 位 数据为“0”、“1”时,将 CH0 作为负输入端 IN-,CH1 作为正输入端 IN+进行 输入。到第3个脉冲的下沉之后 DI 端的输入电平就失去输入作用。

此后 DO/DI 端则开始利用数据输出 DO 进行转换数据的读取。从第4个脉冲下沉开始由 DO 端输出转换数据最高位 DATA7,随后每一个脉冲下沉 DO端输出下一位数据。直到第 11个脉冲时发出最低位数据 DATA0,一个字节的数据输出完成。也正是 从此位开始输出下一个相反字节的数据,即从第11个字节的下沉输出 DATD0。随后输出 8 位数据,到第19个脉冲时数据输出完成也标志着一次 A/D 转换的结束。最后将 CS 置高电平禁用芯片,直接将转换后的数据进行处理就可以了。更详细的时序说明请见图3-7。

作为单通道模拟信号输入时 ADC0832 的输入电压是 0~5V 且 8 位分辨率时的电压精度为 19.53mV。如果作为由 IN+与 IN-输入的输入时,可是将电压值设定在某一个较大范围之内,从而提高转换的宽度。但值得注意的是,在进行 IN+与 IN-的输入时如果IN-的电压大于IN+的电压则转换后的数据结果始终为00H。

3.2.2 单片机89c51

为了设计此系统,我们采用了80c51单片机作为控制芯片。89C51是MCS-51系列单片机中CHMOS工艺的一个典型品种 ;其它厂商以8951为基核开发出的CMOS工艺单片机产品统称为89C51系列。该系列单片机是采用高性能的静态89C51 设计 由先进CMOS 工艺制造并带有非易失性Flash 程序存储器 全部支持12时钟和6 时钟操作 P89C51X2 和P89C52X2/54X2/58X2 分别包含128 字节和256 字节RAM 32条I/O 口线3 个16位定时/计数器 6 输入4优先级嵌套中断结构1 个串行I/O 口可用于多机通信I/O 扩展或全双工UART以及片内振荡器和时钟电路。此外,由于器件采用了静态设计,可提供很宽的操作频率范围,频率可降至0 。可实现两个由软件选择的节电模式,空闲模式和掉电模式,空闲模式冻结CPU但RAM定时器,串口和中断系统仍然工作掉电模式保存RAM的内容 但是冻结振荡器 导致所有其它的片内功能停止工作。由于设计是静态的时钟可停止而不会丢失用户数据 运行可从时钟停止处恢复。


图3-7 ADC0832时序图

3.2.2.1 89c51的基本结构

89C51的微处理器(CPU)

运算器

累加器ACC ;

寄存器B ;

程序状态字寄存器PSW。

控制器

程序计数器PC ;

指令寄存器IR ;

定时与控制逻辑。

89C51的片内存储器

内部ROM容量4K字节

内部RAM容量128字节

89C51的I/O口及功能单元

四个8位的并行口,即P0~P3。它们均为双向口,既可作为输入,又可作为输出。每个口各有8条I/O线。

有一个全双工的串行口(利用P3口的两个引脚P3.0和P3.1);

有2个16位的定时/计数器 ;

有1套完善的中断系统。

89C51的特殊功能寄存器(SFR)

低功耗的闲置和掉电模式

片内振荡器和时钟电路




图3-8 89c51结构图


3.2.2.2 89c51的引脚图


图3-9 89C51引脚图

89C51的制作工艺为CMOS,采用40管脚双列直插DIP封装,引脚说明如下:

VCC:供电电压。

GND:接地。

P0口:P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。当P1口的管脚第一次写1时,被定义为高阻输入。P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。在FIASH编程时,P0 口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。

P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在FLASH编程和校验时,P1口作为第八位地址接收。

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口将输出电流(ILL)这是由于上拉的缘故。

P3口也可作为AT89C51的一些特殊功能口,如下表所示:

口管脚 备选功能

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:复位输入。当振荡器复位器件时,要保持RST脚两个机器周期的高电平时间。

ALE/PROG:当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的地位字节。在FLASH编程期间,此引脚用于输入编程脉冲。在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。因此它可用作对外部输出的脉冲或用于定时目的。然而要注意的是:每当用作外部数据存储器时,将跳过一个ALE脉冲。如想禁止ALE的输出可在SFR8EH地址上置0。此时, ALE只有在执行MOVX,MOVC指令是ALE才起作用。另外,该引脚被略微拉高。如果微处理器在外部执行状态ALE禁止,置位无效。

/PSEN:外部程序存储器的选通信号。在由外部程序存储器取指期间,每个机器周期两次/PSEN有效。但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现。

/EA/VPP:当/EA保持低电平时,则在此期间外部程序存储器(0000H-FFFFH),不管是否有内部程序存储器。注意加密方式1时,/EA将内部锁定为RESET;当/EA端保持高电平时,此间内部程序存储器。在FLASH编程期间,此引脚也用于施加12V编程电源(VPP)。

XTAL1:反向振荡放大器的输入及内部时钟工作电路的输入。

XTAL2:来自反向振荡器的输出。

3.2.2.3 89c51的存储器配置

图3-10 89C51存储器配置

程序存储器
与ROM密切相关的两个引脚
地址锁存允许信号端
外部程序存储器允许输出信号端
当ROM容量不够时,尽量选择高容量存储器空间的单片机,如89C52,89C54,89C58等,应避免外扩程序存储器,因为会增加硬件负担.
通过16位PC寻址,最大可寻址64kB地址空间

数据存储器

数据存储器用于存放运算中间的结果、数据暂存、缓冲、标志位、待测程序等功能。

片内的128B的RAM地址为00H~7FH,供用户做RAM用,但是在这中间的前32单元,00H~1FH即引用地址寻址做用户RAM用,常常做工作寄存器区,分做四组,每组由8个单元组成通用寄存器R0~R7,任何时候都由其中一组作为当前工作寄存器,通过RS0,RS1的内容来决定选择哪一个工作寄存器。

低128字节中的20H~2FH共16字节可用位寻址方式访问各位,共128个位地址,30H~7FH共80个单元为用户RAM区,作堆栈或数据缓冲用,片内RAM不够用时,须扩展片外数据存储器。此时单片机通过P2口和P0口选出6位地址,使用ALE作低8位的锁存信号,再由P0口写入或读出数据。写时用,读时用做外部数据存储器的选通信号

特殊功能寄存器SFR

表3-3 特殊功能寄存器SFR的位置

3.2.2.4 89C51的工作模式

有四种工作模式:模式0,模式1,模式2,模式3

模式0:选择定时器的高8位和低5位组成一个13位定时器/计数器。TL低5位溢出时向TH进位,TH溢出时向中断标志位TF进位,并申请中断。

定时时间t=(213-初值)×振荡周期×12;计数长度位213=8192个外部脉冲

模式1:与模式0的唯一差别是寄存器TH和TL以全部16位参与操作。定时时间t=(216-初值)×振荡周期×12;计数长度位216=65536个外部脉冲

模式2:把TL0和TL1配置成一个自动重装载的8位定时器/计数器。TL用作8位计数器,TH用以保存初值。TL计数溢出时不仅使TF0置1,而且还自动将TH中的内容重新装载到TL中。

定时时间t=(28-初值)×振荡周期×12;计数长度位28=256个外部脉冲

模式3:对T0和T1不大相同

若设T0位模式3,TL0和TH0被分为两个相互独立的8位计数器。TL0为8位计数器,功能与模式0和模式1相同,可定时可计数。

TH0仅用作简单的内部定时功能,它占用了定时器T1的控制位TR1和中断标志位TF1,启动和关闭仅受TR1控制。

定时器T1无工作模式3,但T0在工作模式3时T1仍可设置为0~2。

3.2.2.5 89c51的系统时钟的设计

时钟电路是用来产生89c51单片机工作时所必须的时钟信号,89c51本身就是一个复杂的同步时序电路,为保证工作方式的实现,89c51在唯一的时钟信号的控制下严格的按时序执行指令进行工作 ,时钟的频率影响单片机的速度和稳定性。通常时钟由于两种形式:内部时钟和外部时钟。

我们系统采用内部时钟方式来为系统提供时钟信号。89c51内部有一个用于构成振荡器的高增益反向放大器,该放大器的输入输出引脚为XTAL1和XTAL2,它们跨接在晶体振荡器和用于微调的电容,便构成了一个自激励振荡器

电路中的C1、C2的选择在30PF左右,但电容太小会影响振荡的频率、稳定性和快速性。晶振频率为在1.2MHZ~12MHZ之间,频率越高单片机的速度就越快,但对存储器速度要求就高。为了提高稳定性我们采用温度稳定性好的NPO电容,采用的晶振频率为12MHZ。

图3-11 系统时钟

3.3 本章小结

本章主要介绍了主要芯片的简介,其中重点介绍了dht11温湿度传感器和89c51的元件结构及其各自的工作原理。


4 硬件设计

4.1 显示与报警的设计

4.1.1 显示电路            

该设计中我们采用显示驱动接口芯片方式。即用MAX7219 LED显示驱动芯片与单片机89c51和4位阴极数码管组成显示电路。

MAX7219是Maxim公司推出的8位LED串行显示驱动器,它采用3线串口传送数据,占用资源少且硬件简单,只需一个外部电阻即可方便地调节LED的亮度;可灵活地选择显示器的个数( 1~8个, 级联可成倍增加);可进行译码或不译码显示;内含硬件动态扫描控制,可设置低功耗停机方式。

显示电路的电路连接图如图4-1,图4-2,图4-3所示

图4-1 max7219引脚连接图

图4-2 4led引脚连接图

图4-3 89c51引脚连接图

4.1.2 报警电路

在微型计算机控制系统中,为了安全生产,对于一些重要的参数或系统部位,都设有紧急状态报警系统,以便提醒操作人员注意,或采取紧急措施。其方法就是把计算机采集的数据或记过计算机进行数据处理、数字滤波,标度变换之后,与该参数上下限给定值进行比较,如果高于上限值(或低于下限值)则进行报警,否则就作为采样的正常值,进行显示和控制。

本设计采用峰鸣音报警电路。峰鸣音报警接口电路的设计只需购买市售的压电式蜂鸣器,然后通过MCS-51的1根口线经驱动器驱动蜂鸣音发声。压电式蜂鸣器约需10mA的驱动电流,可以使用TTL系列集成电路7406或7407低电平驱动,也可以用一个晶体三极管驱动。在图中,P3.2接晶体管基极输入端。当P3.2输出高电平“1”时,晶体管导通,压电蜂鸣器两端获得约+5V电压而鸣叫;当P3.2输出低电平“0”时,三极管截止,蜂鸣器停止发声。

图4-4是一个简单的使用三极管驱动的峰鸣音报警电路:

图4-4 三极管驱动的峰鸣音报警电路

本设计是为在温湿度测量中对温湿度的上下限超出是的提示报警,接口位于单片机AT89C51的P3.2口,但温湿度过限时,P3.2口被置0,本系统开始工作。

4.2 本章小结

本章介绍了硬件系统的设计部分,包括显示电路和报警电路两部分。而下一章我将讲解软件设计部分。


5 软件设计
5.1标度变换的实现

温湿度主程序的设计应考虑以下问题:(1)温度显示;(2)温湿度采样,数字滤波;(3)越限报警(5)温度标度转换。通常,符合上述功能的温湿度监测程序由主程序和T0中断服务程序两部分组成。

这里所需要注意的是标度变换,下面简单的介绍一下标度变换:

标度变换的目的是要把实际采样的二进制值转换成BCD形式的温度值,然后存放到显示缓冲区34H-3BH。对一般线性仪表来说,标度变换公式为:

式中:A0为一次测量仪表的下限;Am为一次测量仪表的上限;AX为实际测量值;

N0为仪表下限所对应的数字量;Nm为仪表上限所对应的数字量;NX为测量所得数字量。

软件部分除主程序外,还包含有中断服务、测量、显示、A/D 转换等功能模块。由于系统控制过程是由中断服务程序实现的,本文给出了中断服务程序流程图(见图4-2),从中可以看到整个程序设计的思路和概貌。

5.2 主程序流程图

软件设计的主程序流程图如图5-1所示。

第一步,先设置堆栈,堆栈完后清标志,清除暂时存储的数据,最后再清显示的数字。

第二步进行T0初始化,然后进行串行口初始化。

第三步进行CPU开中断。

第四步进行扫描键盘之后进行温湿度采样。

第五步显示采集所得到的温湿度数据。

第六步循环进行温湿度采样,使得可以隔一段时间进行温湿度数据显示更新。



图5-1主程序流程图

5.3 T0中断流程图

软件的中断流程图如图5-2所示。

第一步先从中断服务程序入口进入,然后保护现场,送定时器初值,最后进行记时处理。

第二步进行温湿度采样,接着将温湿度值送显示,通过指针取设定值,与已经设定好的设定值进行比较,采用控制算法。

第三步输出温、湿度控制量。


图5-2 中断服务程序框图

5.4 报警子程序流程图

报警子程序图如图5-3所示。

图5-3报警子流程图

5.5 温湿度采样子程序流程图

温湿度采样子程序流程图如图5-4所示。

  

图5-4温湿度采集流程图


6 结论

6.1 总结

本文设计了一个简单的单点粮库监测系统,能自动简单的测量粮库一点的温湿度并且具有温湿度超过规定指标进行警报的功能。本系统具有硬件少,结构简单,容易实现,性能稳定可靠,成本低等特点。

6.2 改进思路

在电子系统设计中,为了少走弯路和节省时间,应充分考虑并满足抗干扰 的要求,避免在设计完成后再去进行抗干扰的补救措施。形成干扰的基本要素有三个:第一个是干扰源,指产生干扰的元件、设备或信号,第二个是传播路径,第三个是敏感器件。下面讲具体的抗干扰方案。

6.2.1软件方面

1、习惯于将不用的代码空间全清成“0”,因为这等效于NOP,可在程序跑飞时归位;

2、在跳转指令前加几个NOP,目的同1;

3、在无硬件WatchDog时可采用软件模拟WatchDog,以监测程序的运行;

4、涉及处理外部器件参数调整或设置时,为防止外部器件因受干扰而出错可定时将参数重新发送一遍,这样可使外部器件尽快恢复正确;

5、通讯中的抗干扰,可加数据校验位,可采取3取2或5取3策略;

6、在有通讯线时,如I^2C、三线制等,实际中发现将Data线、CLK线、INH线常态置为高,其抗干扰效果要好过置为低。

6.2.2硬件方面

1、地线、电源线的部线肯定重要了!

2、线路的去偶;

3、数、模地的分开;

4、每个数字元件在地与电源之间都要104电容;

5、在有继电器的应用场合,尤其是大电流时,防继电器触点火花对电路的干扰,可在继电器  线圈间并一104和二极管,在触点和常开端间接472电容,效果不错!

6、为防I/O口的串扰,可将I/O口隔离,方法有二极管隔离、门电路隔离、光偶隔离、电磁隔离等;

7、当然多层板的抗干扰肯定好过单面板,但成本却高了几倍。

8、选择一个抗干扰能力强的器件比之任何方法都有效,我想这点应该最重要。因为器件天生的不足是很难用外部方法去弥补的,但往往抗干扰能力强的就贵些

总结本文的研究工作,主要做了下面几点较突出的工作:

  • 通过查阅大量的相关资料,详细了解了dht11传感器的优点,以及他的结构与功能并且明确了研究目标。
  • 本文设计了自动采集温湿度后进过A/D转换器和单片机89c51与max7219的处理最后显示在led数码管上,使我们目测到目前的粮库的实际温湿度情况。
  • 文章给出了系统具体的硬件设计方案,硬件结构电路图,软件流程图和具体汇编语言程序设计等方面。
  • 在这次毕业设计的过程中学会了Proteus仿真软件的基本使用,感到Proteus仿真软件对我们专业的同学来说是一个非常方便,值得学习的软件。
  • 通过这次毕业设计,重新复习并进一步学习了MCS-51;并且熟练掌握了WORD等软件的使用。
  • 存在的缺陷是没进行干扰考虑,并且因为条件限制的原因没能制作成多点测量对粮库温湿度的测量带有局限性。

致谢
大学本科的学习终于快要毕业了。得以完成毕业论文是与方方面面的关怀和帮助分不开的。首先,我要衷心的感谢我的导师薛丽娟,从论文的选题到毕业设计和论文工作的进行,老师都给与我最大的帮助、指导和鼓励,并尽力为我创造了良好的环境,从而使我在面临一些困难的情况下完成了论文的研究工作。同时还要感谢我班的同学,感谢他们的帮助

附录A 粮库温湿度监测的硬件原理图


附录 B   汇编程序

            //--------------------------------
              //-----湿度读取子程序 ------------
              //--------------------------------
              //----以下变量均为全局变量--------
              //----温度高8位== U8T_data_H------
              //----温度低8位== U8T_data_L------
              //----湿度高8位== U8RH_data_H-----
              //----湿度低8位== U8RH_data_L-----
              //----校验 8位 == U8checkdata-----
              //----调用相关子程序如下----------
              //---- Delay();, Delay_10us();,COM();
              //--------------------------------

  1. #include <reg51.h>
  2. #include <intrins.h>
  3. #include <stdio.h>

  4. typedef unsigned char  U8;       /* defined for unsigned 8-bits integer variable                 无符号8位整型变量  */
  5. typedef signed   char  S8;       /* defined for signed 8-bits integer variable                              有符号8位整型变量  */
  6. typedef unsigned int   U16;      /* defined for unsigned 16-bits integer variable                 无符号16位整型变量 */
  7. typedef signed   int   S16;      /* defined for signed 16-bits integer variable                 有符号16位整型变量 */
  8. typedef unsigned long  U32;      /* defined for unsigned 32-bits integer variable                 无符号32位整型变量 */
  9. typedef signed   long  S32;      /* defined for signed 32-bits integer variable                 有符号32位整型变量 */
  10. typedef float          F32;      /* single precision floating point variable (32bits) 单精度浮点数(32位长度) */
  11. typedef double         F64;      /* double precision floating point variable (64bits) 双精度浮点数(64位长度) */
  12. //
  13. #define uchar unsigned char
  14. #define uint unsigned int
  15. #define   Data_0_time    4

  16. sbit DIN=P2^0;
  17. sbit LOAD=P2^1;
  18. sbit CLK=P2^2;
  19. sbit dout=P2^5;
  20. sbit nullio=P2^3;
  21. sbit sound =P3^2;
  22. sbit mode=P1^2;
  23. sbit set=              P1^3;

  24. uchar mode_flag;
  25. uchar  set_flag;

  26. U8  U8FLAG,k;
  27. U8  U8count,U8temp;
  28. U8  U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata;
  29. U8  U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp;
  30. U8  U8comdata;
  31. U8  outdata[5];  //定义发送的字节数               
  32. U8  indata[5];
  33. U8  count, count_r=0;
  34. U16 U16temp1,U16temp2;
  35. unsigned char th,tl,hh,hl;
  36. unsigned char th0,tl0,hh0,hl0;
  37. bit time_flag;
  38. uchar criterion_hum;
  39. uchar criterion_temp;

  40. void RH(void);
  41. void s_seg(uchar ,uchar ,uchar, uchar );
  42. void send(uchar ,uchar);
  43. void  COM(void);
  44. void  process(void);
  45. void Delay(U16 );
  46. void  Delay_10us(void);
  47. void key_scan(void);
  48. void winkling(void);
  49. void delayMs(unsigned int i);
  50. void special(unsigned char i);
  51. void init(void);
  52. void main(void)
  53. {
  54.   init();
  55.               while(1)
  56.               {
  57.               RH();//读取数据
  58.               process(); //数据处理

  59.   s_seg(th,tl,hh,hl);              //显示温湿度

  60.   key_scan();//按键扫描
  61.   winkling();
  62.               criterion_temp=th0*10+tl0;
  63.               criterion_hum=hh0*10+hl0;
  64.               if ((U8T_data_H>criterion_temp)||(U8RH_data_H>criterion_hum)) sound=0;

  65.               else sound =1;
  66. //              delayMs(150);
  67.   special(180);//延时

  68.   }
  69. }

  70. void init(void)
  71. {
  72. // s_seg(0x81,0x82,0x83,4,5,6,7,8);
  73.               criterion_temp=19;
  74.               criterion_hum=50;
  75.               th0=criterion_temp/10;
  76.               tl0=criterion_temp%10;
  77.               hh0=criterion_hum/10;
  78.               hl0=criterion_hum%10;
  79. }
  80. void special(unsigned char i)
  81. {
  82.   unsigned int j;
  83.      while(i--)
  84.       {
  85.          for(j = 0; j < 125; j++);
  86.                                                         key_scan();
  87.        }
  88. }

  89. void delayMs(unsigned int i)
  90.   {
  91.      unsigned int j;
  92.      while(i--)
  93.       {
  94.          for(j = 0; j < 125; j++);
  95.      }
  96. }

  97. void key_scan(void)
  98. {
  99.                             if(!set)
  100.                             {
  101.                                           delayMs(10);//延时10ms
  102.                                                         if(!set) {              set_flag ++ ;while(!set);}
  103.                             }
  104.                             if(!mode)
  105.                                           {
  106.                                           delayMs(10);//延时10ms
  107.        if(!mode){                                          mode_flag ++ ;              while(!mode) ;}
  108. }                                          }
  109.      void  COM(void)
  110.       {
  111.                       U8 i;
  112.        for(i=0;i<8;i++)               
  113.                   {
  114.                                    U8FLAG=2;
  115.                                //----------------------
  116.                       // P2_1=0 ;  //T
  117.                       // P2_1=1 ;  //T
  118.                   //----------------------
  119.                                while((!dout)&&U8FLAG++);
  120.                                           Delay_10us();
  121.                                           Delay_10us();
  122.                             //              Delay_10us();
  123.                                             U8temp=0;
  124.                    if(dout)U8temp=1;
  125.                                 U8FLAG=2;
  126.                             while((dout)&&U8FLAG++);
  127.                   //----------------------
  128.                       //  P2_1=0 ;  //T
  129.                      //   P2_1=1 ;  //T
  130.                  //----------------------
  131.                                //超时则跳出for循环                             
  132.                                if(U8FLAG==1)break;
  133.                                //判断数据位是0还是1            
  134.                             // 如果高电平高过预定0高电平值则数据位为 1
  135.                                U8comdata<<=1;
  136.                                   U8comdata|=U8temp;        //0
  137.                    }//rof
  138.               }
  139. void send(uchar add,uchar dat)
  140. {              uchar ADS,i,j;
  141.                  CLK=0;
  142.               LOAD=0;
  143.               DIN=0;
  144.                  i=4;
  145.                  while(i<16)
  146.                  {     if(i<8)
  147.                               {
  148.                                             ADS=add;
  149.                             }
  150.                 else
  151.                               {
  152.                                           ADS=dat;
  153.                             }
  154.                 for(j=8;j>=1;j--)
  155.                               {
  156.                                           if((ADS&0x80)==0)
  157.                                           {              DIN=0 ;}
  158.                                           else
  159.                                           {              DIN=1;}
  160.                                               ADS=ADS<<1;
  161.                             CLK=1;
  162.                             CLK=0;            
  163.                             }
  164.                 i=i+8;
  165.    }
  166.    LOAD=1;
  167. }
  168. //void s_seg(uchar X1,uchar X2,uchar X3,uchar X4,uchar X5,uchar X6,uchar X7, uchar X8)
  169. void s_seg(uchar X5,uchar X6,uchar X7, uchar X8)
  170. { send(0x0c,0x01);//正常状态
  171.    send(0x0b,0x07);//设置扫描范围DIG0-7
  172.               send(0x0a,0x05);//设置亮度11/32
  173.    send(0x09,0xff);//采用译码方式
  174.   // send(0x01,X1);
  175.   // send(0x02,X2);
  176.   // send(0x03,X3);
  177.   // send(0x04,X4);
  178.    send(0x05,X5);
  179.    send(0x06,X6);
  180.    send(0x07,X7);
  181.    send(0x08,X8);            
  182. }
  183. void RH(void)
  184.               {
  185.                 //主机拉低18ms
  186.      dout=0;
  187.                  Delay(180);
  188.                  dout=1;
  189.               //总线由上拉电阻拉高 主机延时20us
  190.                  Delay_10us();
  191.                  Delay_10us();
  192.                  Delay_10us();
  193.                  Delay_10us();
  194.               //主机设为输入 判断从机响应信号
  195.                  dout=1;
  196.               //判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行               
  197.                  if(!dout)                            //T !               
  198.                  {
  199.                  U8FLAG=2;
  200.               //判断从机是否发出 80us 的低电平响应信号是否结束            
  201.                  while((!dout)&&U8FLAG++);
  202.                  U8FLAG=2;
  203.               //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
  204.                  while((dout)&&U8FLAG++);
  205.               //数据接收状态                           
  206.                  COM();
  207.                  U8RH_data_H_temp=U8comdata;
  208.                  COM();
  209.                  U8RH_data_L_temp=U8comdata;
  210.                  COM();
  211.                  U8T_data_H_temp=U8comdata;
  212.                  COM();
  213.                  U8T_data_L_temp=U8comdata;
  214.                  COM();
  215.                  U8checkdata_temp=U8comdata;
  216.                  dout=1;
  217.               //数据校验
  218.               U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp);
  219.                  if(U8temp==U8checkdata_temp)
  220.                  {
  221.                                  U8RH_data_H=U8RH_data_H_temp;
  222.                                  U8RH_data_L=U8RH_data_L_temp;
  223.                               U8T_data_H=U8T_data_H_temp;
  224.                                  U8T_data_L=U8T_data_L_temp;
  225.                                  U8checkdata=U8checkdata_temp;
  226.                  }//fi
  227.                  }//fi

  228.               }
  229. void  process(void)
  230. {
  231.                             if(U8RH_data_H==0)
  232.               {              hh=0;
  233.                 hl=0;
  234.               }
  235.               else
  236.               {
  237.                             hh=U8RH_data_H/10;
  238.                             hl=U8RH_data_H%10;
  239.               }
  240.                             if(U8T_data_H==0)
  241.               {              th=0;
  242.                 tl=0;
  243.               }
  244.               else
  245.               {
  246.                             th=U8T_data_H/10;
  247.                             tl=U8T_data_H%10;
  248.               }            
  249. }

  250.      void Delay(U16 j)
  251.     {      U8 i;
  252.                   for(;j>0;j--)
  253.                 {              
  254.                             for(i=0;i<27;i++);
  255.                 }
  256.     }

  257. void  Delay_10us(void)
  258.       {
  259.         U8 i;
  260.         i--;
  261.         i--;
  262.         i--;
  263.         i--;
  264.         i--;
  265.         i--;
  266.        }
  267. void winkling(void)
  268. {
  269. switch(mode_flag)
  270. {
  271.               case 0:break;
  272.                     
  273.               case  1:
  274.               {
  275.                             while(mode_flag==1)
  276.                                                         {
  277.                                                                      
  278.                                                                                        send(0x05,0xf);
  279.                                                                                                     special(100);
  280.                                                                                                                 if(mode_flag!=1)                                           {                send(0x05,th0);               goto XX2;                                          }

  281.                                                                                                                 if(set_flag==1)
  282.                                                                                                   {
  283.                                                                                                                               set_flag=0;
  284.                                                                                                                               th0++;
  285.                                                                                                                               if(th0>9)              th0=0;                                                        
  286.                                                                                                                 }
  287.                                                                                                                                                                                                                                              
  288.                send(0x05,th0);
  289.                                                                                                     special(100);
  290.                                                                                                     if(set_flag==1)
  291.                                                                                                   {
  292.                                                                                                                               set_flag=0;
  293.                                                                                                                               th0++;
  294.                                                                                                                               if(th0>9)              th0=0;                                                        
  295.                                                                                                                 }
  296.                                                                       }
  297.                                                         }

  298.                             case  2:
  299.               {
  300. XX2:                            while(mode_flag==2)
  301.                                                         {
  302.                send(0x06,0xf);
  303.                                                                                                     special(100);
  304.                                                                                                                 if(mode_flag!=2){    send(0x06,tl0);  goto XX3;}
  305.                                                                                                                 if(set_flag==1)
  306.                                                                                                   {
  307.                                                                                                                               set_flag=0;
  308.                                                                                                                               tl0++;
  309.                                                                                                                               if(tl0>9)tl0=0;                                                                                   
  310.                                                                                                                 }
  311.                send(0x06,tl0);
  312.                                                                                                     special(100);
  313.                                                                                                     if(set_flag==1)
  314.                                                                                                   {
  315.                                                                                                                               set_flag=0;
  316.                                                                                                                               tl0++;
  317.                                                                                                                               if(tl0>9)tl0=0;                                                                                   
  318.                                                                                                                 }
  319.                                                                       }
  320.                                                         }
  321.                             case 3:
  322. XX3:                     { while(mode_flag==3)
  323.                                                                       {
  324.                                                                                        send(0x07,0xf);
  325.                                                                                                     special(100);
  326.                                                                                                                 if(mode_flag!=3)                                                                                       { send(0x07,hh0); goto XX4;}
  327.                                                                                                                 if(set_flag==1)
  328.                                                                                                   {
  329.                                                                                                                               set_flag=0;
  330.                                                                                                                               hh0++;
  331.                                                                                                                               if(hh0>9)hh0=0;                                                                                   
  332.                                                                                                                 }
  333.                                                                                        send(0x07,hh0);
  334.                                                                                                     special(100);
  335.                                                                                                     if(set_flag==1)
  336.                                                                                                   {
  337.                                                                                                                               set_flag=0;
  338. ……………………

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

完整的Word格式文档51黑下载地址:
http://www.51hei.com/bbs/dpj-125422-1.html


回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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