文章目录
DHT11介绍
DHT11是一款常用的温湿度传感器,广泛应用于气候监测、智能家居、农业和环境监测等领域。它可以测量周围环境的温度和湿度,并通过数字信号的形式输出测量结果。DHT11具有以下特性:
- 测量范围:DHT11能够测量的温度范围通常在0℃到50℃之间,湿度测量范围是20%RH到90%RH。
- 精确度:温度误差±2℃,湿度误差±5%RH。
- 分辨率:DHT11传感器的温度分辨率为1℃,湿度分辨率为1%RH。
- 供电电压:一般工作电压为3.3V至5V。
- 数字输出:DHT11输出的是数字信号,因此不需要额外的模数转换。
- 接口类型:通常只需要一个数字引脚就能读取数据,适合直接与微控制器(如Arduino)等连接。
- 使用简便性:提供了多种编程语言的库函数,容易集成和编程。
DHT11传感器包含一个湿度检测电容和一个NTC温度测量元件,并且有一个高性能8位微控制器来处理信号。数据从传感器输出通常是单总线数字信号,因此读取数据的过程需要按照特定的通信协议来进行。
DHT11工作原理
DHT11传感器的工作原理可以从温度和湿度检测来分别说明:
温度检测
DHT11中的温度检测是通过一个负温度系数(Negative Temperature Coefficient,NTC)热敏电阻实现的。NTC热敏电阻的电阻值会随着温度的升高而降低。DHT11内部的微控制器会测量这个电阻值,并将其转换为温度读数。
湿度检测
湿度检测是通过湿敏电容来实现的。湿敏电容是一种特殊的电容器,其电容值会随着环境湿度的变化而变化。湿度升高,空气中水分增加,湿敏电容表面的电介质常数会增加,从而导致电容值增加;相反,湿度降低电容值则减小。传感器内的微控制器会测量这个电容值的变化,并据此计算出相对湿度的读数。
数字信号输出
温度和湿度的物理量被转换成电信号后,DHT11内部的微控制器会对这些信号进行处理,并将它们转换成数字信号。然后,它通过单一的数据线以一种特定的协议发送数字信号给外部微控制器(如Arduino)。这些数字信号包含了温度和湿度的测量值以及校验位来确保数据的完整性。
总结来说,DHT11利用NTC热敏电阻和湿敏电容检测环境的温度和湿度,然后通过内部的微控制器将这些模拟信号转换为数字信号,并通过单线接口传输给外部设备。
DHT11单总线时序
用户主机(MCU)发送一次开始信号后,DHT11从低功耗模式转换到高速模式,待主机开始 信号结束后,DHT11发送响应信号,送出40bit的数据,并触发一次信号采集。
DHT11数据校验
DATA用于微处理器与DHT11之间的通讯和同步,采用单总线数据格式,一次传送40位数据, 高位先出。 数据格式: 8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据+8bit校验位, 校验位数据定义 “8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据”8bit校验位等于8bit校验位。
示例:假如接收到的40位数据为 湿度高8位:00110101、 湿度低8位:00000000、温度高8位:00011000、温度低8位:00000100、校验位计算:01010001。
校验结果00110101+00000000+00011000+00000100=01010001,说明接收数据正确,所以湿度:53%RH+0.0%RH=53.0%RH,温度为:24℃+0.4℃=24.4℃。
全部代码
dht11.c
#include "dht11.h"
unsigned int rec_dat[4];
//DHT11起始信号
void DHT11_start()
{
dht_data=1;
delay_us(5);
dht_data=0;
delay_ms(13);//这个延时不能过短,18ms以上,实际在仿真当中要想读到数据延时要在延时参数要在40以上才能出数据
dht_data=1;
delay_us(25);//MCU释放总线20~40us,需要在40微秒到100微秒之间
}
//接收一个字节
unsigned char DHT11_rec_byte()
{
unsigned char i,dat=0;
for(i=0; i<8; i++)
{
while(!dht_data);//跳过数据前段的50us
Delayus(17);//过了数据0和数据1相同区域,再做检测
dat <<=1;
if(dht_data==1)
{
//如果读到的数据是1
dat +=1;
}
while(dht_data);
}
return dat;
}
//接收温湿度数据
void DHT11_receive(unsigned char* t_h, unsigned char* t_l, unsigned char* r_h, unsigned char* r_l)
{
unsigned int R_H,R_L,T_H,T_L;
unsigned char RH,RL,TH,TL,revise;
DHT11_start();
// dht_data=1;
if(dht_data==0)
{
while(dht_data==0); //等待DHT响应信号,80us内来拉高总线
while(dht_data==1); //等待DHT响应信号,80us内来拉低总线
R_H=DHT11_rec_byte(); //接收湿度高八位
R_L=DHT11_rec_byte(); //接收湿度低八位
T_H=DHT11_rec_byte(); //接收温度高八位
T_L=DHT11_rec_byte(); //接收温度低八位
revise=DHT11_rec_byte(); //接收校正位
delay_us(13); //结束
if((R_H+R_L+T_H+T_L)==revise) //校正
{
RH=R_H;
RL=R_L;
TH=T_H;
TL=T_L;
}
/*数据处理,方便显示*/
rec_dat[0]=RH;
rec_dat[1]=RL;
rec_dat[2]=TH;
rec_dat[3]=TL;
*t_h = TH;
*t_l = TL;
*r_h = RH;
*r_l = RL;
}
}
void DHT11_process()
{
float temp,hump;
hump= rec_dat[0] + rec_dat[1]/256.0;
temp = rec_dat[2] + rec_dat[3]/256.0;
}
dht11.h
#ifndef __DHT11_H_
#define __DHT11_H_
#include "reg52.h"
#define dht_data = P14 ;
void DHT11_start();//DHT开始信号
unsigned char DHT11_rec_byte();
void DHT11_receive(unsigned char* t_h, unsigned char* t_l, unsigned char* r_h, unsigned char* r_l);
void DHT11_process();
#endif
总结
DHT11读写方式为单总线,需要延时判断设备是否响应,同时数据校验最好不要省略。关于DHT11的详细数据请参考数据手册