欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

DHT11型温湿度传感器的使用(附源码)

程序员文章站 2022-07-13 17:16:00
...

一、产品概述

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

二、产品参数

2.1 原理图

DHT11型温湿度传感器的使用(附源码)

2.2 封装信息

DHT11型温湿度传感器的使用(附源码)

2.3 引脚说明

DHT11型温湿度传感器的使用(附源码)

2.4 传感器性能说明

DHT11型温湿度传感器的使用(附源码)

2.5 典型应用电路

DHT11型温湿度传感器的使用(附源码)

三、传感器工作时序图说明

3.1 发送数据前的准备

总线空闲状态为高电平,主机把总线拉低等待DHT11响应,主机把总线拉低必须大于18毫秒,保证DHT11能检测到起始信号。DHT11接收到主机的开始信号后, 等待主机开始信号结束,然后发送80us低电平响应信号.主机发送开始信号结束后,延时等待20-40us后, 读取DHT11的响应信号,主机发送开始信号后,可以切换到输入模式,或者输出高电平均可, 总线由上拉电阻拉高。
DHT11型温湿度传感器的使用(附源码)

3.2 通讯过程

一次完整的数据传输为40bit,高位先出。数据格式:8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据+8bit校验和。数据传送正确时校验和数据等于“8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据”所得结果的末8位。

用户MCU发送一次开始信号后,DHT11从低功耗模式转换到高速模式,等待主机开始信号结束后,DHT11发送响应信号,送出40bit的数据,并触发一次信号采集, 用户可选择读取部分数据.从模式下,DHT11接收到开始信号触发一次温湿度采集, 如果没有接收到主机发送开始信号,DHT11不会主动进行温湿度采集.采集数据后转换到低速模式。

DHT11型温湿度传感器的使用(附源码)

四、例程(例程均为自己编写且通过验证成功)

/*所用单片机型号为STC89C52RC,晶振为11.0592MHz*,将测得的温湿度用8段数码管由低位向高位一位一位显示/

4.1 头文件、子函数声明、变量声明等

#include<reg51.h>
#include<intrins.h>
#define ERROR 0
#define OK 1

typedef unsigned char unchar;
typedef unsigned int unint;

sbit Bus=P2^2;//数据总线

unchar  value[5];//储存检测值
unint check;

void Delay10us(void);
void Delay20ms(void);
void Delay1s(void);
unchar Read_Temp();
void show(int x);


//上电需要越过1s的不稳定期,测试间隔不能小于1s
//读数时高位先出
//校验和等于前四个字节相加的低八位
//温湿度小数部分作为拓展用,目前输出为0

4.2 温湿度读取函数

unchar Read_Temp()
{
	unchar i,j=0,mask;
	Bus=0;//主机主动拉低并持续20ms(超过18ms)
	Delay20ms();
	Bus=1;//主机再主动拉高40us(20-40us)
	Delay10us();
	Delay10us();
	Delay10us();
	Delay10us();
	if(Bus==1)//如果总线没有响应
	{
		return ERROR;
	}
	else //如果总线有响应
	{
		while(!Bus);//等待总线的低响应(80us)
		while(Bus);//等待总线的高响应(80us)
		while(j<5)
		{
			mask=0x80;
			for(i=0;i<8;i++)//一次接收一个字节
			{
				while(!Bus);//等待过一个低电平间隙
				Delay10us();//0保持26-28us的高电平,1保持70us的高电平,取40us的处的电平监测
				Delay10us();
				Delay10us();
				Delay10us();
				if(Bus==0)
				{
					value[j]&=(~mask);	
				}
				else
				{
					value[j]|=mask;
				}
				mask>>=1;
				while(Bus);//等待该位传送结束
			}
			j++;//继续接受下一个字节
		}
			
	}
	check=(value[0]+value[2])&0x00ff;//计算校验和
	if(check==value[4])//如果校验和没错
	{
		return OK;
	}
	else
	{
		return ERROR;
	}


}

 4.3 数码管显示子函数

void show(int x)
{
	while(x>0)
	{
		switch(x%10)
		{
			case 0:P0=0xc0;break;	
			case 1:P0=0xf9;break;
			case 2:P0=0xa4;break;
			case 3:P0=0xb0;break;
			case 4:P0=0x99;break;
			case 5:P0=0x92;break;
			case 6:P0=0x82;break;
			case 7:P0=0xf8;break;
			case 8:P0=0x80;break;
			case 9:P0=0x90;break;
		}
		x=x/10;
		Delay1s();
		P0=0xff;
		Delay1s();
		
	}
}

4.4 各延时子函数


/*10us延时子函数*/
void Delay10us()
{
	unchar i;
	i=2;
	while(--i);
}


/*20ms延时子函数*/
void Delay20ms(void)   //误差 -0.000000000005us
{
    unsigned char a,b,c;
    for(c=1;c>0;c--)
        for(b=222;b>0;b--)
            for(a=40;a>0;a--);
}  

/*1s延时子函数*/
void Delay1s(void)   //误差 -0.000000000227us
{
    unsigned char a,b,c;
    for(c=13;c>0;c--)
        for(b=247;b>0;b--)
            for(a=142;a>0;a--);
    _nop_();  //if Keil,require use intrins.h
}

4.5 主函数

int main()
{
	unchar result,temp,hum;
	Delay1s();//越过1s不稳定期
	while(1)
	{
		result=Read_Temp();
		if(result==OK)
		{
			temp=value[2];
			hum=value[0];
			show(temp);
			Delay1s();
			show(hum);
			Delay1s();
			Delay1s();
			Delay1s();
		}
		else
		{
			continue;
		}
	}
	return 0;
}

 

左肩理想右肩担当,君子不怨永远不会停下脚步!