DHT11

文章目录

  • DHT11
  • DHT11
    • 一、DHT11基础储备
    • 二、接口说明
      • 1. 接线图
      • 2. 电源引脚
      • 3. 串行接口(单线双向)
    • 三、协议及数据格式
    • 四、操作时序
      • 4.1 主机发送复位信号
      • 4.2 DHT11 发送响应信号
      • 4.3 数据传输
      • 4.4 区分数据0/1的巧法
    • 五、测量分辨率与电气特性
    • 六、使用注意事项
      • 6.1 工作与贮存条件
      • 6.2 暴露在化学物质中
      • 6.3 恢复处理
      • 6.4 温度影响
      • 6.5 光线
      • 6.6 配线注意事项
    • 七、51及STM32例程
      • 7.1 51对应的
        • dht11.h
      • 7.2 STM32对应的
        • dht11.h
        • dht11.c
        • main.c
        • 百度网盘资源

DHT11

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

一、DHT11基础储备

DHT11 数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器,内部由一个 8 位单片机控制一个电阻式感湿元件和一个 NTC 测温元件。DHT11 虽然也是采用单总线协议,但是该协议与 DS18B20 的单总线协议稍微有些不同之处。

相比于 DS18B20 只能测量温度,DHT11 既能检测温度又能检测湿度,不过 DHT11 的精度和测量范围都要低于 DS18B20,其温度测量范围为 0~50℃,误差在±2℃;湿度的测量范围为 20%~90%RH(Relative Humidity 相对湿度—指空气中水汽压与饱和水汽压的百分比),误差在±5%RH。DHT11 电路很简单,只需要将 DATA 引脚连接单片机的一个 I/O 即可,不过该引脚需要上拉一个 5K 的电阻,DHT11 的供电电压为 3~5.5V

二、接口说明

1. 接线图

2. 电源引脚

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

3. 串行接口(单线双向)

DATA 用于微处理器与 DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间4ms左右,数据分小数部分和整数部分,具体格式在下面说明,当前小数部分用于以后扩展,现读出为零.操作流程如下:

(1)一次完整的数据传输为40bit,高位先出。

(2)数据格式:
8bit湿度整数数据 + 8bit湿度小数数据 + 8bi温度整数数据 + 8bit温度小数数据 + 8bit校验和

(3)数据传送正确时,校验和数据等于
“8bit湿度整数数据+8bit湿度小数数据 +8bi温度整数数据+8bit温度小数数据”所得结果的末8位

三、协议及数据格式

DHT11 采用单总线协议与单片机通信,单片机发送一次复位信号后,DHT11 从低功耗模式转换到高速模式,等待主机复位结束后,DHT11 发送响应信号,并拉高总线准备传输数据。一次完整的数据为 40bit,按照高位在前,低位在后的顺序传输

数据格式为:8bit 湿度整数数据+8bit 湿度小数数据+8bit 温度整数数据+8bit 温度小数数据+8bit 校验和,一共 5 字节(40bit)数据。由于 DHT11 分辨率只能精确到个位,所以小数部分是数据全为 0。校验和为前 4 个字节数据相加,校验的目的是为了保证数据传输的准确性。

DHT11 只有在接收到开始信号后才触发一次温湿度采集,如果没有接收到主机发送复位信号,DHT11 不主动进行温湿度采集。当数据采集完毕且无开始信号后,DHT11 自动切换到低速模式。

注意:由于 DHT11 时序要求非常严格,所以在操作时序的时候,为了防止中断干扰总线时序,先关闭总中断,操作完毕后再打开总中断。

四、操作时序

4.1 主机发送复位信号

DHT11 的初始化过程同样分为复位信号和响应信号
首先主机拉低总线至少 18ms,然后再拉高总线,延时 20~40us,取中间值 30us,此时复位信号发送完毕。

从模式下,DHT11接收到开始信号触发一次温湿度采集,**如果没有接收到主机发送开始信号,DHT11不会主动进行温湿度采集。**采集数据后转换到低速模式。

4.2 DHT11 发送响应信号

DHT11 检测到复位信号后,触发一次采样,并拉低总线 80us 表示响应信号,告诉主机数据已经准备好了;然后 DHT11 拉高总线 80us,之后开始传输数据。如果检测到响应信号为高电平,则 DHT11 初始化失败,请检查线路是否连接正常。

当复位信号发送完毕后,如果检测到总线被拉低,就每隔 1us 计数一次,直至总线拉高,计算低电平时间;当总线被拉高后重新计数检测 80us 的高电平。如果检测到响应信号之后的80us 高电平,就准备开始接收数据。实际上 DHT11 的响应时间并不是标准的 80us,往往存在误差,当响应时间处于 20~100us 之间时就可以认定响应成功。

4.3 数据传输

DHT11 在拉高总线 80us 后开始传输数据。每 1bit 数据都以 50us 低电平时隙开始,告诉主机开始传输一位数据了。DHT11 以高电平的长短定义数据位是 0 还是 1,当 50us 低电平时隙过后拉高总线,高电平持续 26~28us 表示数据“0”持续 70us 表示数据“1”

最后 1bit 数据传送完毕后,DHT11 拉低总线 50us,表示数据传输完毕,随后总线由上拉电阻拉高进入空闲状态。

4.4 区分数据0/1的巧法

还是像检测响应时间那样计算高电平持续时间那就太麻烦了!!!

数据“0”的高电平持续 26~28us,数据“1”的高电平持续70us,每一位数据前都有 50us 的起始时隙。如果我们取一个中间值 40us 来区分数据“0”和数据“1”的时隙。

当数据位之前的 50us 低电平时隙过后,总线肯定会拉高,此时延时 40us 后检测总线状态,如果为高,说明此时处于 70us 的时隙,则数据为“1”;如果为低,说明此时处于下一位数据 50us 的开始时隙,那么上一位数据肯定是“0”。

为什么延时 40us?
由于误差的原因,数据“0”时隙并不是准确 26~28us,可能比这短,也可能比这长。
当数据“0”时隙大于 26~28us 时,
如果延时太短,无法判断当前处于数据“0”的时隙还是数据“1”的时隙;
如果延时太长,则会错过下一位数据前的开始时隙,导致检测不到后面的数据

五、测量分辨率与电气特性

测量分辨率分别为 8bit(温度)、8bit(湿度)。

VDD=5V,T = 25℃,除非特殊标注

注:最新版厂家升级,采样周期为2秒,老版为1秒。

六、使用注意事项

6.1 工作与贮存条件

超出建议的工作范围可能导致高达3%RH的临时性漂移信号。返回正常工作条后,传感器会缓慢地向校准状态恢复。要加速恢复进程/可参阅6.3小节的“恢复处理”。在非正常工作条件下长时间使用会加速产品的老化过程。

6.2 暴露在化学物质中

电阻式湿度传感器的感应层会受到化学蒸汽的干扰,化学物质在感应层中的扩散可能导致测量值漂移和灵敏度下降。在一个纯净的环境中,污染物质会缓慢地释放出去。下文所述的恢复处理将加速实现这一过程。高浓度的化学污染会导致传感器感应层的彻底损坏。

6.3 恢复处理

置于极限工作条件下或化学蒸汽中的传感器,通过如下处理程序,可使其恢复到校准时的状态。在50-60℃和< 10%RH的湿度条件下保持2 小时(烘干);随后在20-30℃和>70%RH的湿度条件下保持 5小时以上。

6.4 温度影响

气体的相对湿度,在很大程度上依赖于温度。因此在测量湿度时,应尽可能保证湿度传感器在同一温度下工作。如果与释放热量的电子元件共用一个印刷线路板,在安装时应尽可能将DHT11远离电子元件,并安装在热源下方,同时保持外壳的良好通风。为降低热传导,DHT11与印刷电路板其它部分的铜镀层应尽可能最小,并在两者之间留出一道缝隙。

6.5 光线

长时间暴露在太阳光下或强烈的紫外线辐射中,会使性能降低。

6.6 配线注意事项

DATA信号线材质量会影响通讯距离和通讯质量,推荐使用高质量屏蔽线。

七、51及STM32例程

7.1 51对应的

dht11.h

while(t–)执行的时间T = T2 -T1 = 201us - 195.5us = 4.5us。

#define uchar unsigned char
#define uint unsigned intsbit Data=P1^0; //数据线
uchar rec_dat[9]; //储存数据
void DHT11_delay_us(uchar n)
{while(--n);
}
void DHT11_delay_ms(uint z)
{uint i,j;for(i=z;i>0;i--)for(j=110;j>0;j--);
}/*
主机(单片机)发送起始信号:
1.主机先拉高data。
2.拉低data延迟18ms。
3.拉高data并延迟等待(通过此操作将单片机引脚设置为输入)。
*/
void DHT11_start()
{Data=1;DHT11_delay_us(2);Data=0;DHT11_delay_ms(25);   //拉低延时18ms以上Data=1;DHT11_delay_us(30);   //拉高 延时 20~40us,取中间值 30us
}/*------------------------------------------------接收八位二进制
------------------------------------------------*/
uchar DHT11_rec_byte()      //接收一个字节
{unsigned char i,dat=0;for(i=0;i<8;i++)    //从高到低依次接收8位数据{          while(Data);   //等待进入低电平while(!Data);   //等待50us低电平过去DHT11_delay_us(8);     //延时60us,如果还为高则数据为1,否则为0 dat<<=1;//移位(低位补零)使正确接收8位数据,数据为0时直接移位if(Data==1)    //数据为1时,使dat加1来接收数据1dat+=1;while(Data);  //等待数据线拉低    }  return dat;
}/*------------------------------------------------接收40bit数据(具体的温湿度)
1.主机先把data线拉高(io设置为输入)。
2.从机把data线拉低,主机读取data线电平,直到低电平结束(大约50us)从机拉高data线后,延迟40us左右(28~70us之间)主机再次读取data线电平,如果为低电平,则为“0”,如果为高电平,则为“1”。
3.继续重复上述1,2步骤累计40次。
------------------------------------------------*/
uchar T_H;
void DHT11_receive()      //接收40位的数据
{uchar R_H,R_L,T_L,RH,RL,TH,TL,revise; DHT11_start();//发送起始信号:if(Data==0){while(Data==0);   //等待拉高     DHT11_delay_us(40);  //拉高后延时80usR_H=DHT11_rec_byte();    //接收湿度高八位  R_L=DHT11_rec_byte();    //接收湿度低八位  T_H=DHT11_rec_byte();    //接收温度高八位  T_L=DHT11_rec_byte();    //接收温度低八位revise=DHT11_rec_byte(); //接收校正位DHT11_delay_us(25);    //结束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]='0'+(RH/10);rec_dat[1]='0'+(RH%10);rec_dat[2]=' ';rec_dat[3]=' ';//温度rec_dat[4]='0'+(TH/10);rec_dat[5]='0'+(TH%10); rec_dat[6]=' ';}}

7.2 STM32对应的

dht11.h

#ifndef __DHT11_H
#define __DHT11_H
#include "stm32f10x.h"                  // Device header#define dht11_high GPIO_SetBits(GPIOB, GPIO_Pin_12)
#define dht11_low GPIO_ResetBits(GPIOB, GPIO_Pin_12)
#define Read_Data GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12)void DHT11_GPIO_Init_OUT(void);
void DHT11_GPIO_Init_IN(void);
void DHT11_Start(void);
unsigned char DHT11_REC_Byte(void);
void DHT11_REC_Data(void);#endif

dht11.c

#include "stm32f10x.h"                  // Device header
#include  "dht11.h"
#include  "delay.h"
//数据
unsigned int rec_data[4];//对于stm32来说,是输出
void DH11_GPIO_Init_OUT(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP; //推挽输出GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_12;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);}//对于stm32来说,是输入
void DH11_GPIO_Init_IN(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN_FLOATING; //浮空输入GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_12;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);}//主机发送开始信号
void DHT11_Start(void)
{DH11_GPIO_Init_OUT(); //输出模式dht11_high; //先拉高delay_us(30);dht11_low; //拉低电平至少18usdelay_ms(20);dht11_high; //拉高电平20~40usdelay_us(30);DH11_GPIO_Init_IN(); //输入模式
}//获取一个字节
char DHT11_Rec_Byte(void)
{unsigned char i = 0;unsigned char data;for(i=0;i<8;i++) //1个数据就是1个字节byte,1个字节byte有8位bit{while( Read_Data == 0); //从1bit开始,低电平变高电平,等待低电平结束delay_us(30); //延迟30us是为了区别数据0和数据1,0只有26~28usdata <<= 1; //左移if( Read_Data == 1 ) //如果过了30us还是高电平的话就是数据1{data |= 1; //数据+1}while( Read_Data == 1 ); //高电平变低电平,等待高电平结束}return data;
}//获取数据void DHT11_REC_Data(void)
{unsigned int R_H,R_L,T_H,T_L;unsigned char RH,RL,TH,TL,CHECK;DHT11_Start(); //主机发送信号dht11_high; //拉高电平if( Read_Data == 0 ) //判断DHT11是否响应{while( Read_Data == 0); //低电平变高电平,等待低电平结束while( Read_Data == 1); //高电平变低电平,等待高电平结束R_H = DHT11_Rec_Byte();R_L = DHT11_Rec_Byte();T_H = DHT11_Rec_Byte();T_L = DHT11_Rec_Byte();CHECK = DHT11_Rec_Byte(); //接收5个数据dht11_low; //当最后一bit数据传送完毕后,DHT11拉低总线 50usdelay_us(55); //这里延时55usdht11_high; //随后总线由上拉电阻拉高进入空闲状态。if(R_H + R_L + T_H + T_L == CHECK) //和检验位对比,判断校验接收到的数据是否正确{RH = R_H;RL = R_L;TH = T_H;TL = T_L;}}rec_data[0] = RH;rec_data[1] = RL;rec_data[2] = TH;rec_data[3] = TL;
}

main.c

OLED文章见-》[STM32-OLED]((85条消息) STM32—OLED显示屏_安赫.的博客-CSDN博客_基于stm32的oled屏幕介绍)

#include "stm32f10x.h"                  // Device header
#include "delay.h"
#include "OLED.h"
#include  "dht11.h"
#include  "usart.h"extern unsigned int rec_data[4];int main()
{OLED_Init();uart_init(9600);OLED_ShowCHinese(0, 0, 0);                         //温OLED_ShowCHinese(0, 16, 1);                      //度OLED_ShowCHinese(0, 32, 4);                          //:OLED_ShowCHinese(0, 60, 5);                           //.OLED_ShowCHinese(0, 90, 6);                          //℃OLED_ShowCHinese(4, 0, 2);                           //湿OLED_ShowCHinese(4, 16, 3);                      //度OLED_ShowCHinese(4, 32, 4);                          //:OLED_ShowCHinese(4, 60, 5);                           //.OLED_ShowCHinese(4, 90, 7);                          //%while(1){delay_s(1);DHT11_REC_Data(); //接收温度和湿度的数据OLED_ShowNum(1,7,rec_data[2],2);OLED_ShowNum(1,10,rec_data[3],1);OLED_ShowNum(3,7,rec_data[0],2);OLED_ShowNum(3,10,rec_data[1],2);printf("温度:%d\r\n",rec_data[2]); printf("湿度:%d\r\n",rec_data[0]);printf("\r\n\n");   }
}

百度网盘资源

链接:https://pan.baidu.com/s/1JJJd9XXphZ8yOXY_3A1nJw?pwd=1234
提取码:1234
–来自百度网盘超级会员V2的分享

既然都看到最后了,关注 收藏 不迷路。


给那些看完的朋友,奖励一个 赤赤博客-后端+前端,觉得不错的话可以推荐给身边的朋友哟!

DHT11详细介绍(内含51和STM32代码)相关推荐

  1. 详细介绍如何读懂STM32开发板电路原理图以及芯片文档和开发手册,并编写一个测试程序:点亮一个LED灯

    开发环境: 开发板:STM32PZ6806L芯片:ARM_STM32F103_ZE 软件开发环境:KEIL5 开发所需资料: STM32F1XX芯片电路原理图 STM32F1XX系列芯片手册 XX代表 ...

  2. 蚁群算法(ACA)详细介绍(JAVA实现及代码详解)

    文章目录 1.蚁群算法概要 什么是蚁群算法 蚁群算法的数学公式 蚂蚁从i城市到j城市的概率公式 信息素的释放公式 信息素的挥发公式 蚁群算法的框架 2.TSP描述(旅行商问题) 3.JAVA源代码实现 ...

  3. 区块链 java 开源_详细介绍Java区块链开源代码背后的内容

    什么是Java区块链开源代码?它是一种分布式分类帐技术,将所有不同的属性放在一起.那么Java区块链开源代码就可以通过不同的共识机制,使所有添加的数据不变.2015年之前,估计大家都知道的区块链的申请 ...

  4. unordered_map详细介绍

    转载自关联容器:unordered_map详细介绍(附可运行代码) 介绍 1 特性 2 Hashtable和bucket 模版 1 迭代器 功能函数 1 构造函数 12示例代码 2 容量操作 21 s ...

  5. java中的static属性详细介绍

    标题 java中static属性详细介绍 类的生命周期 代码块 静态代码块: 静态方法 静态属性和非静态属性的区别: 使用static的注意事项 继承关系中静态和非静态的关系 普通代码块和构造代码块区 ...

  6. php 运营商授权,PHP判断手机号运营商(详细介绍附代码)

    道理很简单,知道手机号规则 进行正则判断就可以 移动:134.135.136.137.138.139.150.151.157(TD).158.159.187.188 联通:130.131.132.15 ...

  7. 超声波模块详细介绍(stm32循迹小车中超声波的介绍)

    超声波模块详细介绍(stm32循迹小车中超声波的介绍) 超声波模块是非常重要的一个模块,今天给大家全面介绍一下超声波模块的原理以及用法,代码的编写. 1 超声波模块的认识 首先,市面上的常见超声波模块 ...

  8. DL之YoloV3:Yolo V3算法的简介(论文介绍)、各种DL框架代码复现、架构详解、案例应用等配图集合之详细攻略

    DL之YoloV3:Yolo V3算法的简介(论文介绍).各种DL框架代码复现.架构详解.案例应用等配图集合之详细攻略 目录 Yolo V3算法的简介(论文介绍) 0.YoloV3实验结果 1.Yol ...

  9. php mysql 字段自增_MySQL自增字段取值的详细介绍(附代码)

    本篇文章给大家带来的内容是关于MySQL自增字段取值的详细介绍(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 1 前言 本文来自回答思否网友的一个问题,这个网友新建了一张表 ...

  10. linux源码acl,Linux自主访问控制机制模块详细分析之posix_acl.c核心代码注释与acl.c文件介绍...

    原标题:Linux自主访问控制机制模块详细分析之posix_acl.c核心代码注释与acl.c文件介绍 2.4.4.6 核心代码注释 1 posix_acl_permission() int(stru ...

最新文章

  1. centos7 查看ip_VMware安装CentOS 7操作系统详细操作教程(网络配置)
  2. Scala的自定义类型标记
  3. pyspider 连接mysql_pyspider 导入模块报错 提示 No module named mysqldb
  4. 编写程序计算 sentence 中有多少个单词,并指出其中最长和最短的单词。如果有多个最长或最短的单词,则将它们全部输出。
  5. github star破13k,Dapr 能否引领云原生中间件的未来?
  6. Asp.Net Core2.0 基于QuartzNet任务管理系统
  7. MIP 组件库升级公告
  8. C#实现多级子目录Zip压缩解压实例
  9. 简化document.createElement(div)动态生成层方法
  10. 一些常用的google scholar网站
  11. 风儿轻轻地吹,沙儿轻轻地飘
  12. Excel·VBA单元格内容拆分
  13. smartbi服务器缓存文件,导出资源 - Smartbi V10帮助中心 -
  14. 特斯拉被曝低级漏洞:用树莓派DIY车钥匙,开锁仅需90秒
  15. 关于Excel表格的导入
  16. c语言写程序if else,if else用法详解,C语言if else用法完全攻略
  17. 什么是Ninja -
  18. 【uni-app怎么引用使用阿里巴巴矢量图标库iconfont】
  19. 安装SQLSERVER2000时出现以前的某个程序安装已在安装计算机上创建挂起的文件操作
  20. 后台管理系统--首页及登录认证

热门文章

  1. Android APP极光推送取消关联启动配置
  2. Synchronized保证线程安全的原理
  3. ios 使用SourceTree,KDiff3进行代码的冲突解决步骤
  4. 软件著作权 php代码行数,申报软件著作权时,如何快捷计算源码行数
  5. 计算机网络OSI模型的各层及主要功能
  6. 分析google关键词de工具
  7. Scrapy-2:东莞阳光政务平台
  8. ls-dyna常用结构单元类型
  9. 思岚雷达rplidar S1配置调试全纪录
  10. Mac下用命令行打开pdf文件