基于DHT11的温湿度检测报告Word文档下载推荐.docx
《基于DHT11的温湿度检测报告Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《基于DHT11的温湿度检测报告Word文档下载推荐.docx(30页珍藏版)》请在冰豆网上搜索。
第一根引脚
第二根引脚
第三根引脚
第四根引脚
VDD
供电3—5.5VDC
串行数据
单总线
空脚,请悬空
GND
接地,电源负极
3、工作原理
3.1数据传输格式
单片机发送一次开始信号后,DHT11从低功耗模式转换到高速模式,等待单片机开始信号结束后,DHT11发送40bit的数据,高位先出。
数据格式:
8bit湿度整数数据+8bit湿度小数数据
+8bit温度整数数据+8bit温度小数数据+8bit校验和
数据传输正确时,校验和数据等于“8bit湿度整数数据+8bit湿度小数数据
+8bit温度整数数据+8bit温度小数数据”所得结果的末八位
如果没有接收到单片机发送的开始信号,DHT11不会主动进行温湿度采集,转换到低功耗模式。
图三:
DHT11工作时序图
3.2采集开始方式
DHT11空闲时为高电平,单片机把总线拉低等待DHT11响应,拉低时间需大于18ms,保证DHT11能检测到起始信号。
DHT11接收到主机的开始信号后,等待单片机开始信号结束,然后发送80us低电平响应信号。
单片机发送开始信号结束后,延时等待20~40us后,读取DHT11的响应信号,可以切换到输入模式,或者输出高电平均可,总线由上拉电阻拉高。
图四:
DHT11启动时序图
3.3DHT11信号发送方式
图五:
“0”信号表示时序图
图六:
“1”信号表示时序图
如果总线为低电平,说明DHT11发送响应信号,DHT11发送响应信号后,会再把总线拉高80us,开始准备数据,每一bit数据都以50us低电平开始,通过判断高电平的时间,来决定采集到的数是“0”还是“1”;
当高电平时间为26us~28us时,则采集到的数为“0”,如图四所示;
当高电平时间大于28us时,则采集到的数“1”,如图五所示。
当最后1bit数据传输完毕后,DHT11拉低总线50us,随后由上拉电阻拉高进入空闲状态。
如果总线为高电平,说明DHT11没有响应,有可能是线路没插好。
四、方案说明及相关功能电路接线图
4.1整体框架图
4.2控制中心——AT89C52单片机
图七:
AT89C52单片机的最小系统电路图
该系统的控制中心,是由一片AT89C52单片机来控制、分析。
该款单片机的最小系统由复位电路、晶振电路,I\O口电路,完成其它功能的元器件均接在该片单片机的I\O口上,由该单片机控制。
4.3采集装置——DHT11传感器
DHT11信号端接单片机的P2.1口,外加上拉电阻。
DHT11与单片机之间的数据传输都是从该P2.1口上传输。
电路接法如图八所示。
4.4输入装置——按键
图八:
DHT11接线图
按键由一个光电开关和4个普通按键组成。
用户可根据固定的按键来设置温湿度报警的上限线,电路解法如图九所示。
各个按键的作用如下:
P3.3口的光电开关:
用于切换进入设置界面
还是显示界面
P3.4口的普通按键:
当前设定对象值减一
P3.5口的普通按键:
当前设定对象值加一
P3.6口的普通按键:
切换设置对象的上、下限
P3.7口的普通按键:
切换设置对象(温——湿度)
图九:
按键接线图
4.5显示装置——数码管
显示部分由四位数码管构成的,用户可根据数码管的显示,看到的温、湿度,以及其当前设置的上、下限。
接线图如图十所示。
每位数码管的功能如下:
首位:
当首位灭时,为显示状态;
亮时为设置状态
当显示“∪”时,表示设置当前对象的上限
当显示为“∩”时,表示设置当前对象的下限
末尾:
用于判别对象:
当显示“E”时,则表示湿度
当显示“C“时,则表示温度
中间两位数:
用于显示数值
图十:
数码管接线图
4.6报警装置——蜂鸣器
当温湿度的其中一项超过其设定的上下限,蜂鸣器就会产生报警,用户可根据不同的报警方式,判断是温度超过界限,还是湿度超过界限。
温度报警:
急促的响声
湿度报警:
缓慢的响声
二则同时报警:
响停时间一样
图十一:
蜂鸣器接线图
五、主要程序流程图
六、调试结果:
6.1总体显示:
开机上电后,数码管能正常显示当前温度、湿度,并且每隔一段时间会温湿度自动切换。
6.2按键调试:
1、进入设置界面(光电开关P3.3),后,数码管会自动显示成当前对应对象所设的对应值,再按一次,则又退出设置界面。
例如:
数码管显示“∪40C”,则表示当前设置的温度上限为40℃;
显示“∩50E”则表示当前湿度下限设置值为50%。
2、进入设置界面后(光电开关P3.3),按温湿度切换按钮(普通按键P3.7),数码管会自动切换对应对象,并且出现前对应对象所设的对应值。
数码管本来显示“∩50E”,按下按钮后,变成“∩20C”,则表示数码管本来显示的是湿度下限设置为50%,按下按钮后,则数码管变成显示温度下限当前设置值位20℃。
3、进入设置界面后(光电开关P3.3),按上下限切换按钮(普通按键P3.6),数码管会自动切换显示当前对象所设的对应值。
数码管本来显示“∪40C”,按下该按钮后,数码管会变成“∩20C”,则表示数码管本来显示的是温度上限为40℃,按下该按钮后,则数码管会变成显示温度下限当前设置值位20℃。
4、进入设置界面后(光电开关P3.3),按加一按钮(普通按键P3.5),会把当前对象的设置值加一,数码管显示的值也会对应加一。
数码管本来显示“∩20C”,按下该按钮后,数码管显示“∩21C”。
即表示本来当前的温度下限设置值为20℃,按下该按钮后,温度下限的设置值变为21℃。
5、进入设置界面后(光电开关P3.3),按减一按钮(普通按键P3.4),会把当前对象的设置值减一,数码管显示的值也会对应减一。
数码管本来显示“∩50E”,按下该按钮后,数码管显示“∩49E”。
即表示湿度下限本来设置值为50%,按下该按钮后,湿度下限设置值变49%。
6、没有进入设置界面,按其它四个按键无反应。
6.3报警调试
1、将温度的报警下限调到超过当前温度或者报警上限调低于当前温度时,蜂鸣器会发出急促的报警声。
2、将湿度的报警下限调到超过当前湿度或者报警上限调低于当前湿度时,蜂鸣器会发出缓慢的报警声。
3、当温湿度同时都报警时,蜂鸣器会发出响停一致的报警声。
4、当正处于报警时,进入设置界面,报警声会停止,用户可重新设置上下限,让报警取消,以免扰民。
七、调试过程遇到的问题
7.1问题:
单片机始终未接收到DHT11的信号。
现象:
运行程序后,数码管始终显示00。
分析:
硬件原因,1、DHT11坏了,信号未采集,导致单片机无信号。
软件原因,1、采集步骤出错,未理解透DHT11采集原理,导致信号未采集。
2、显示程序错误,未正确赋值显示,以至于DHT11已采集到信号,但未能正确显示,以至于误以为是DHT11未采集信号。
问题解决:
硬件问题排除,买了几个全新的DHT11,分别接上单片机,发现全都不能使用,所以初步排除了硬件原因。
软件原因,最有可能的就是未能正确理解DHT11采集过程,所以特地跟组员规定,先不探讨,各自去看DHT11采集原理,之后再探讨各自认为DHT11如何采集,然后再按各自的理解,一个一个实验,看那个能采集到信号,确定出DHT11正确的采集过程。
7.2问题:
数码管动态扫描不稳定。
本来在主程序调用数码管显示程序,使4位数码管逐个给值、显示,4位数码管都能正常稳定的显示,但经过一次数据采集之后,数码管会有一段时间的晃动,甚至全灭,之后再变稳定。
未采集信号前,数码管能正常显示,遇到采集信号时,数码管不能正常显示,推测是DHT11采集时耗时太久,所以数码管更新显示时间边长,所以数码管动态扫描不稳定。
采用定时器中断,每隔一段时间,中断发生时,扫描数码管的一位,下次扫描时,自动切换到扫描数码管下一位。
这样能保证数码管稳定显示。
但用中断时,DHT11采集前时,需把中断关掉,防止采集过程中,信号丢失。
7.3问题:
数码管显示位数太少,要显示的东西太多。
数码管只有四位,不仅要显示温度、湿度,还要显示湿度与温度各自的最大值与最小值,数据较多。
由于没有标志,不知道当前显示的是什么数,显示是否正确。
经小组统一决定将四位数码管的中间两位来显示数值,首尾两个数码管用来确定当前显示的是什么数。
具体的格式如前面数码管的介绍中所说。
在程序中,建立了4个变量,来给数码管显示判断,各个变量各种状态效果如下所述:
变量名
“0”状态
“1”状态
bianliang
显示界面
设置界面
bianliang1
设置湿度
设置温度
bianliang2
最小值
最大值
bianliang3
显示当前湿度
显示当前温度
bianliang和bianliang3都为“0”,则数码管显示当前湿度
bianliang=1并且bianliang1和bianliang2都为0,则数码管显示的湿度的最小值。
PS:
只有进入设置界面,才能看到温湿度所设置的最大值和最小值。
7.4问题:
报警太单一,无法区分是湿度报警,还是温度报警。
报警时,蜂鸣器产生长鸣,想把上下限调到合适的位置,让报警取消以免扰民,却不知道要跳那个界限。
报警只有单一的长鸣,不能辨别
解决方案:
将报警方式分为,温度报警、湿度报警、两则同时报警三种情况。
通过判断响停时间长短来判断报警形式,具体报警形式如前面蜂鸣器中所说。
若停止报警,只需进入设置界面,将改报警对象的上下限合适调整即可。
八、实验总结
经过了这两周的实训,使我收获颇多。
首先,使我懂得了DHT11传感器的工作原理,理解其工作时序图。
DHT1部有测温元件和测湿元件,当单片机发送采集信号给DHT11后,DHT11会将采集到的温度、湿度转换成40bit的数据给单片机。
其次,让我懂得用定时器中断来实现数码管的动态显示。
数码管显示的程序本来是放在主程序里,当扫描到数码管程序时才能显示,最后发现要是主程序程序太多的话,数码管显示出来的数字就会不稳定。
经过研究后,发现可以用定时器中断,让每隔一段时间,中断产生时,扫描数码管的其中一位。
这样就可以让数码管稳定显示了。
最后,使我深刻的意识到了自己在汇编上的不足。
该程序本来是打算用汇编语言写的,由于事先没有安排好变量的存储地址,后来一写才发现自己被汇编语言的跳转指令,跳得自己都晕了。
不像C语言那样,会自动分配变量的存储地址。
两周时间,说长也不算长,却让我对控制有了兴趣。
当自己所写的程序,如自己所想的那般执行时,那种喜悦是不可言语的。
实训虽结束了,但激情还在。
之后还应以这次的经历,多多研究控制其它元器件。
九、程序清单
/*****************实验目标********************
采用DHT11实现温湿度的采集,并在4位数码管上显示
通过对应的按键,可实现设置温湿度的上下限
当温湿度超过上下限时,会产生报警
**********************************************/
/******************定义区*********************
***********地址、变量定义*********************
#include<
at89x52.h>
//头文件
#defineuintunsignedint
#defineucharunsignedchar
sfrsmg=0x80;
//数码管显示值,当前定义为P0口
sfresmg=0xa0;
//数码管位选地址,当前定义为P2口
sbitdht11=0xa1;
//DHT11信号端,当前定义为P2_1
sbitmoshi=0xb7;
//设置温度——湿度切换按钮,当前定义为P3_7
sbitqiehuan=0xb6;
//切换上限——下限切换按钮,当前定义为P3_6
sbitadd=0xb5;
//设置值加1按钮,当前定义为P3_5
sbitsub=0xb4;
//设置值减一按钮,当前定义为P3_4
sbitshezhi=0xb3;
//设置界面——显示界面切换按钮
sbitfengming=0x93;
//蜂鸣器地址,当前定义为P1_3
bitbianliang=0;
//设置与显示的标志位
bitbianliang1=0;
//设置————温度与湿度的标志位
bitbianliang2=0;
//设置————最大值与最小值的标志位
bitbianliang3=1;
//显示————温度与湿度测定值标志位
bitbaojing1=0;
//温度报警标志位
bitbaojing2=0;
//湿度报警标志位
uintbj,bj1,bj2;
//报警蜂鸣器低电平时间*50us,周期时间*50us
uintxs;
//四位数码管中间两位显示的值
uintds,cj,qh;
//定时次数变量,ds:
用于数码管显示频率cj:
用于温湿度采集频率qh,温湿度显示切换频率
ucharmax_R=80,min_R=20,max_T=50,min_T=10;
//用于设置湿度上限、下限;
温度上限、下限
ucharshou=0xff,mo=0xff;
//数码管首位和末位显示
ucharbyte,RH,RL,TH,TL;
//采集到的字节、湿度整数、湿度小数;
温度整数,温度小数
inta[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
//数码管字段码
/**********************************************************************
**************************延时程序区***********************************
**********************************************************************/
voidDelay20ms()//11.0592MHz
{
unsignedchari,j;
i=36;
j=217;
do
{
while(--j);
}while(--i);
}
voidDelay8ms()//11.0592MHz
i=15;
j=84;
voidDelay28us()//11.0592MHz
unsignedchari;
i=10;
while(--i);
/*****************************************************
*****************定时中断设置区***********************
*****************************************************/
voidTimer0Init(void)//50微秒11.0592MHz
TMOD&
=0xF0;
//设置定时器模式
TMOD|=0x02;
TL0=0xD2;
//设置定时初值
TH0=0xD2;
//设置定时重载值
TF0=0;
//清除TF0标志
TR0=1;
//定时器0开始计时
/********************************************************
******************数码管显示区***************************
********************************************************/
voidxianshi(intnum)
inti;
switch(i)
{case0:
esmg=0xf0|esmg;
smg=shou;
esmg=0xef&
esmg;
i++;
break;
case1:
smg=a[num%100/10];
esmg=0xdf&
case2:
smg=a[num%10/1];
esmg=0xbf&
case3:
smg=mo;
esmg=0x7f&
default:
i=0;
}
}
********************报警处理区***************************
voidbaojing()
{
if(TH>
=max_T||TH<
=min_T)baojing1=1;
//温度超极限,温度报警标志位置一
elsebaojing1=0;
//否则,温度报警标志位清零
if(RH>
=max_R||RH<
=min_R)baojing2=1;
//湿度超极限,湿度报警标志位置一
elsebaojing2=0;
//否则,湿度报警标志位清零
}
voidbaojingchuli()
if(baojing1==1&
&
baojing2==1)
{//温湿度同时报警
bj1=5000;
//响时间
bj2=10000;
//周期
}
else//都无报警
{//温湿度都无报警
bj1=0;
//响时间
bj2=0;
//周期
if(baojing1)
{//只有温度报警
bj1=1000;
bj2=5000;
}
if(baojing2)
{//只有湿度报警
bj1=9000;
bj2=30000;
//如果计数<
bj1,响;
bj1<
计数<
bj2,停;
计数>
bj2,计数清零
if(bj<
bj1)fengming=0;
elseif(bj<
bj2)fengming=1;
elsebj=0;
}
/*********************************************************
*******************数码管显示判断区************************
*********************************************************/
voidpanduan()
if(!
bianliang)
{//进入显示界面
shou=0xff;
//数码管首位灭
baojing();
//判断是否报警
if(!
bianliang3)
{//显示界面,显示湿度
xs=RH;
//当前湿度给数码管显示
mo=0x86;
//数码管末尾出现“E"
else
{//显示界面,显示温度
xs=TH;
//当前温度给数码管显示
mo=0xC6;
//数码管末尾出现"
C"
else
{//设置界面
if(bianliang1==0&
bianliang2==0)
{//设置湿度最小值
shou=0xC8;
//数码管首位出现最小值符号
mo=0x86;
//数码管末尾出现湿度符号
xs=min_R;
//把当前的湿度最小值给数码管显示
}
elseif(bianliang1==1&
{//设置温度最小值
//数码管首位出现最小值符号
mo=0xc6;
//数码管末尾出现温度符号
xs=min_T;
//把当前的温度最小值给数码管显示
elseif(bianliang1==0&
bianliang2==1)
{//设置湿度最大值
shou=0xc1;
//数码管首位出现最大值符号
xs=max_R;
//把当前的湿度最大值给数码管显示
{//设置温度最大值
shou=0xC1;
mo=0xC6;
//数码管末尾出现温度符号
xs=max_T;
//把当前的温度最大值给数码显示
/********************************************
***************中断程序**********************