基于某DHT11地温度检测
- 格式:doc
- 大小:1.50 MB
- 文档页数:17
西安邮电大学温度测控与报警系统课程设计报告书系部名称:自动化学院学生姓名:专业名称:测控技术与仪器班级:1001班2013年4月8日至时间:2013 年4月19日温湿度测控与报警系统设计一、设计要求:以DHT11作为温度传感器,进行环境温湿度测试。
将结果显示在数码管或液晶屏上。
同时,设定温度上下限,当温度越限即报警。
二、设计方案分析1、方案设计:2、背景知识介绍:(1)控制部分控制部分是采用单片机STC89C52。
<1>STC89C52简介STC89C52是一种带8K字节闪烁可编程可檫除只读存储器的低电压,高性能COMOS8的微处理器,俗称单片机。
该器件采用ATMEL搞密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。
单片机总控制电路如下图<2>复位操作复位操作有上电自动复位相按键手动复位两种方式。
上电自动复位是通过外部复位电路的电容充电来实现的,其电路如图所示。
这佯,只要电源Vcc的上升时间不超过1ms,就可以实现自动上电复位,即接通电源就成了系统的复位初始化。
按键手动复位有电平方式和脉冲方式两种。
其中,按键电平复位是通过使复位端经电阻与Vcc电源接通而实现的,其电路如图(b)所示;而按键脉冲复位则是利用RC微分电路产生的正脉冲来实现的,其电路如下图所示:(a)上电复位(b)按键电平复位(c)按键脉冲复位上述电路图中的电阻、电容参数适用于6MHz晶振,能保证复位信号高电平持续时间大于2个机器周期。
本系统的复位电路采用上电复位方式。
(2)测量部分测量部分我们采用DHT11温度传感器。
1> 概述:DHT11是广州奥松有限公司生产的一款湿温度一体化的数字传感器。
该传感器包括一个电阻式测湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。
通过单片机等微处理器简单的电路连接就能够实时的采集本地湿度和温度。
DHT11与单片机之间能采用简单的单总线进行通信,仅仅需要一个I/O口。
传感器内部湿度和温度数据40Bit的数据一次性传给单片机,数据采用校验和方式进行校验,有效的保证数据传输的准确性。
DHT11功耗很低,5V电源电压下,工作平均最大电流0.5mA。
性能指标和特性如下:作电压范围:3.5V-5.5V作电流:平均0.5mA度测量范围:20-90%RH度测量范围:0-50℃度分辨率:1%RH 8位度分辨率:1℃ 8位样周期:1S总线结构TTL兼容(5V)2> 管脚排列如下:3> 应用电路连接说明DHT11数字湿温度传感器连接方法极为简单。
第一脚接电源正,第四脚接电源地端。
数据端为第二脚。
可直接接主机(单片机)的I/O口。
为提高稳定性,建议在数据端和电源正之间接一只4.7K的上拉电阻。
第三脚为空脚,此管脚悬空不用。
●引脚说明:Vcc 正电源Dout 输出NC 空脚GND 地4> DHT11数据结构●DHT11数字湿温度传感器采用单总线数据格式。
即,单个数据引脚端口完成输入输出双向传输。
其数据包由5Byte(40Bit)组成。
数据分小数部分和整数部分,具体格式在下面说明。
●一次完整的数据传输为40bit,高位先出。
●数据格式:8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据 +8bit校验和●校验和数据为前四个字节相加。
●传感器数据输出的是未编码的二进制数据。
数据(湿度、温度、整数、小数)之间应该分开处理。
如果,某次从传感器中读取如下5Byte数据:byte4 byte3 byte2 byte1 byte000101101 00000000 00011100 00000000 01001001整数小数整数小数校验和●湿度温度校验和由以上数据就可得到湿度和温度的值,计算方法:humi (湿度)= byte4 . byte3=45.0 (%RH)temp (温度)= byte2 . byte1=28.0 ( ℃)jiaoyan(校验)= byte4+ byte3+ byte2+ byte1=73(=humi+temp)(校验正确)●注意:DHT11一次通讯时间最大3ms,主机连续采样间隔建议不小于100ms。
5 > DHT11的传输时序5.1 > DHT11开始发送数据流程主机发送开始信号后,延时等待20us-40us后读取DH11T的回应信号,读取总线为低电平,说明DHT11发送响应信号,DHT11发送响应信号后,再把总线拉高,准备发送数据,每一bit数据都以低电平开始,格式见下面图示。
如果读取响应信号为高电平,则DHT11没有响应,请检查线路是否连接正常。
5.2 > 主机复位信号和DHT11响应信号5.3 > 数字‘0’信号表示方法5.4 > 数字‘1’信号表示方法(3)显示部分1602采用标准的16脚接口,其中:●第1脚:VSS为地电源●第2脚:VDD接5V正电源●第3脚:V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度●第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。
●第5脚:RW为读写信号线,高电平时进行读操作,低电平时进行写操作。
当RS和RW共同为低电平时可以写入指令或者显示地址,当RS为低电平RW为高电平时可以读忙信号,当RS为高电平RW为低电平时可以写入数据。
●第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。
●第7~14脚:D0~D7为8位双向数据线。
●第15~16脚:空脚1602液晶模块内部的字符发生存储器(CGROM)已经存储了160个不同的点阵字符图形,如表1所示,这些字符有:阿拉伯数字、英文字母的大小写、常用的符号、和日文假名等,每一个字符都有一个固定的代码,比如大写的英文字母“A”的代码是01000001B(41H),显示时模块把地址41H中的点阵字符图形显示出来,我们就能看到字母“A”1602液晶模块内部的控制器共有11条控制指令,如表2所示它的读写操作、屏幕和光标的操作都是通过指令编程来实现的。
(说明:1为高电平、0为低电平)●指令1:清显示,指令码01H,光标复位到地址00H位置●指令2:光标复位,光标返回到地址00H●指令3:光标和显示模式设置 I/D:光标移动方向,高电平右移,低电平左移 S:屏幕上所有文字是否左移或者右移。
高电平表示有效,低电平则无效●指令4:显示开关控制。
D:控制整体显示的开与关,高电平表示开显示,低电平表示关显示 C:控制光标的开与关,高电平表示有光标,低电平表示无光标 B:控制光标是否闪烁,高电平闪烁,低电平不闪烁●指令5:光标或显示移位 S/C:高电平时移动显示的文字,低电平时移动光标●指令6:功能设置命令 DL:高电平时为4位总线,低电平时为8位总线 N:低电平时为单行显示,高电平时双行显示 F: 低电平时显示5x7的点阵字符,高电平时显示5x10的点阵字符●指令7:字符发生器RAM地址设置●指令8:DDRAM地址设置●指令9:读忙信号和光标地址 BF:为忙标志位,高电平表示忙,此时模块不能接收命令或者数据,如果为低电平表示不忙。
●指令10:写数据●指令11:读数据三、硬件设计:四、软件设计:(见附录)五、测试数据及设计结果:六、调试中出现的错误及解决方法:用Proteus仿真软件仿真的时候里面的器件符号里找不到DHT11,只能用DS18B20代替。
在电路调试方面,我们组四个人先把每一个外围电路的工作原理弄懂,对它的工作电压电流核实,然后我们在实验板上把实际的电路连接起来,加上实际的电源,一个一个的调试,发现它确实能够正常工作时在做下一步。
:本次设计我主要是做软件部分,采用的是STC89C52单片机,该单片机的稳定性比较好,编程简单,功能易实现。
在本次设计的过程中,发现很多的问题,单片机课程设计重点就在于软件算法的设计,需要有很巧妙的程序算法,虽然以前写过几次程序,但我觉的写好一个程序并不是一件简单的事。
:通过这次对数字温度计的设计与制作,让我了解了设计电路的程序,也让我了解了关于数字温度计的原理与设计理念。
要设计一个电路总要先用仿真,仿真成功之后才实际接线的。
但是最后的成品却不一定与仿真时完全一样。
因为,再实际接线中有着各种各样的条件制约着。
而且,在仿真中无法成功的电路接法。
在实际中因为芯片本身的特性而能够成功。
所以,在设计时应考虑两者的差异,从中找出最适合的设计方法。
通过这次学习,让我对各种电路都有了大概的了解,所以说,坐而言不如立而行,对于这些电路还是应该自己动手实际操作才会有深刻理解。
:我做的焊接的工作,从这次的课程设计中,我真真正正的意识到,在以后的学习中,要理论联系实际,把我们所学的理论知识用到实际当中,学习单机片机更是如此,程序只有在经常的写与读的过程中才能提高,在焊接晶振电路时,没有注意两个电容的大小,导致程序烧进去却不工作,后来自己的检查后发现错误的根源,换了电容,数码管立马显示数据。
那刻真的很高兴。
附程序:#ifndef __TOU_H__#define __TOU_H__#include<reg51.h>#include <intrins.h>#include <string.h>#include<math.h>#include<stdio.h>#define uint unsigned int#define uchar unsigned char/**********1602宏定义**********#define LCD_SCREEN_ON 0x0C //显示开#define LCD_SCREEN_OFF 0x08 //显示关#define LCD_CURSOR_ON 0x0A //显示光标#define LCD_CURSOR_OFF 0x0c //无光标#define LCD_C_FLASH_ON 0x0f //有光标,光标闪动#define LCD_C_FLASH_OFF 0x0e //有光标,光标不闪动//进入模式设置指令#define LCD_AC_UP 0x06 //新数据后光标右移#define LCD_AC_DOWN 0x04 //新数据后光标左移#define LCD_S_MOVE_ON 0x05 // 画面可平移#define LCD_S_MOVE_OFF 0x04 //画面不可平移//设定显示屏或光标移动方向指令#define LCD_C_LEFT 0x10 //光标左移1 格,且AC 值减1#define LCD_C_RIGHT 0x11 //光标右移1 格,且AC 值加1#define LCD_CHAR_LEFT 0x18 //显示器上字符全部左移一格,但光标不动#define LCD_CHAR_RIGHT 0x1C //显示器上字符全部右移一格,但光标不动*/#define LCD_DATA P0/*****************1602端口定义**********/sbit BF = P0^7; //忙碌标志位,,将BF位定义为P0.7引脚//sbit RS = P2^4;//sbit RW = P2^3;//sbit EN = P2^2;sbit RS = P2^6;sbit RW = P2^4;sbit EN = P2^0;/*****************DHT11端口定义**********/sbit DHT11 = P3^4;//sbit DHT11 = P2^1;//sbit BUZZ = P1^7;sbit BUZZ = P2^3;/****************全局变量声明***************/extern float F16T,F16RH;/********LCD函数声明*******/void Init_Lcd(void);void LCD_write_str(uchar X,uchar Y,uchar *s);void LCD_set_xy( uchar x, uchar y );void LCD_en_write(void);void LCD_write_char(uchar cd,uchar ab);void LCD_byte(uchar abc);int LCD_value(uchar x,uchar y,float f);void Delay_ms(uint n);void Delay_us(uchar n);/************DHT11函数声明************/void getDHT11(void);#endif#include<TOU.h>uchar U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata; float F16T,F16RH; //用于最终读取的温湿度数据float F16T,F16RH;//以下为延时函数void Delay_ms(uint n){uchar j;while(n--){for(j=0;j<125;j++);}}void Delay_us(uchar n) //N us 延时函数精度±4us{n=n/2;while(--n);}//读取数据char COM(void){char i,U8temp,U8comdata;for(i=0;i<8;i++){while(!DHT11);//表示读取的高电位延时大于20 多us 则读取的是1 否则读取的是0Delay_us(35); //通过U8FLAG 可判断bit11 显示数据的脉长U8temp=0;if(DHT11)U8temp=1;while(DHT11);U8comdata<<=1;U8comdata|=U8temp;}return U8comdata;}//----以下变量均为全局变量--------//----温度高8 位== U8T_data_H------//----温度低8 位== U8T_data_L------//----湿度高8 位== U8RH_data_H-----//----湿度低8 位== U8RH_data_L-----//----校验8 位== U8checkdata-----void getDHT11(void){GO1:DHT11=0;Delay_ms(20); //主机拉低18msDHT11=1; //总线由上拉电阻拉高主机延时20usDelay_us(60); //主机设为输入判断从机响应信号if(!DHT11) //判断从机是否有低电平响应信号如不响应则跳出,响应则向下运行//T !{while(!DHT11); //wait DHT goto highwhile(DHT11); //数据接收状态U8RH_data_H=COM();U8RH_data_L=COM();U8T_data_H=COM();U8T_data_L=COM();U8checkdata=COM();DHT11=1; //数据校验if((U8T_data_H+U8T_data_L+U8RH_data_H+U8RH_data_L)!=U8checkdata) goto GO1;}F16T=U8T_data_H+((float)U8T_data_L)/256;F16RH=U8RH_data_H+((float)U8RH_data_L)/256;// F16T=33;}//F16=(U8T_data_H*10+(float)U8T_data_L*10/256)/10;#include<TOU.h>/********************************************************** 名称:LCD_write_char(uchar cd,uchar ab)* 功能:写指令或数据当写ab 时应使cd=0 当cd 不为0 则写cd 且ab 的赋值无效* 入口参数:cd:指令内容ab:数据内容指令常量已在上面定义但一般不用* 出口参数:无* 范例: LCD_write_char( 0, ‘f’)*************CD_set_xy*************/void LCD_write_char(uchar cd,uchar ab){Delay_us(20);if(cd==0){RS=1; //RS=1,写显示内容LCD_byte(ab);}else{RS=0; //RS=0,写命令LCD_byte(cd);}}/**************************************************************************** * 名称:Init_Lcd() 主函数调用* 功能:Lcd 初始化* 入口参数:无* 出口参数:无* 范例: 在主函数中直接调用****************************************************************************/ void Init_Lcd(){LCD_write_char(0x38,0);Delay_ms(1);LCD_write_char(0x38,0);Delay_ms(1);LCD_write_char(0x38,0);Delay_ms(1);LCD_write_char(0x0c,0);Delay_ms(1);LCD_write_char(0x06,0);Delay_ms(1);LCD_write_char(0x0c,0);Delay_ms(1);LCD_write_char(0x01,0);Delay_ms(1);}/**************************************************************************** * 名称:LCD_write_str(uchar X,uchar Y,uchar *s)主函数调用* 功能:在指定地址写一个字符串eg:Y=0,1,2,3,4,5,6,7,8,9,10...15。