首页 > 编程知识 正文

温湿度传感器介绍,dht11温湿度传感器工作原理

时间:2023-05-04 12:23:28 阅读:140995 作者:3080

我们刚开始学习单片机,练习写传感器的时机是必不可少的。其实我比较推荐大家刚开始练习的时候使用DHT11来练习

推荐理由:

因为DHT11的时机很简单。 DHT11是国产的,是中文整体的参考手册,不用担心看不懂英语。 功能少的话,只有一个测量温湿度的功能。 综上所述,我认为DHT11非常适合刚入门单片机的朋友学习。

那么,在使用传感器之前,我们得先看一下数据手册。 你不需要看全部。 我们只要看看他的重点就可以了。

这就是DHT11温湿度传感器的外观。 我们知道就好了。

接下来,我们来看看DHT11的参数特性

重点是用红框围起来,需要知道这个DHT11温湿度传感器的测量范围、精度、分辨率。 超过此范围后,将无法使用DHT11。

接下来请看引脚的说明。 需要注意的是,虽然该设备使用的是单总线协议,但也需要知道他的供电范围。 范围为3.5-5.5v。 超过该范围时,传感器可能会烧焦,低于该范围时,传感器可能会读取错误的温湿度数据或进行罢工。 因此,我们在用它们的3.3v单片机编程时,必须注意这一点。

这是数据手册中显示的DHT11的典型电路连接方法,在数据端口上连接上拉电阻。 供电使用的是7805的稳压电源,也就是5V。 实际上,只要满足他的供电电压范围,我们都可以工作。

接下来,我们来看看其数据格式(重点)

DHT11使用单总线协议,一次传输40位数据。 请小心。 看这句话,每次读取DHT11的数据,一次读取40次,也就是40位。 而且,数据的前16位是与湿度有关的,中间的16位是与温度有关的,最后8位是用于检查的。 检测成功后,证明本次温湿度结果正确,单片机就可以使用该温湿度值。 如果检查失败,意味着这次读取的温湿度值错误,因此不进行采样。

另外,商家的数据手册中还提供了检查数据的样本图。 而且还是中文。 所以,我说得对吧。 这个设备真的很简单,再简单不过了。 最适合初学者的入门练习。

DHT11的整体通信流程。 步骤1 :主机首先发送开始信号,然后从机会发送回适当的信号并作出响应。 步骤2 :提升主机信号线准备接收数据。 第三部分:数据接收开始(一次接收40位)。

这就是单人数据读取的过程,但我们的每个过程该怎么办呢?

步骤一:DHT11上电后(DHT11上电后,等待1S克服不稳定状态,其间不能发送任何命令),测试环境

温湿度数据在记录数据同时,DHT11的DATA数据线被上拉电阻上拉,始终维持高电平; 此时DHT11的

DATA引脚处于输入状态,始终检测外部信号。

步骤二:微处理器的I/O被设定为在输出的同时输出低电平,低电平的保持时间为18ms以上,然后微处理器的I/O

当成为输入状态时,由于上拉电阻,作为微处理器I/O的DHT11的数据数据线也变高,等待DHT11动作

发出回答信号,发送信号如图所示:

步骤三:DHT11的DATA端子检测到外部信号的低电平时,等待外部信号的低电平结束,延迟后DHT11的DATA

管脚处于输出状态,输出80微秒的低电平作为响应信号,之后输出80微秒的高电平,向外部通知连接准备

接收数据,微处理器I/O此时处于输入状态,检测到I/O有低电平(DHT11响应信号)后,等待80微秒

的高电平后的数据接收、发送信号如下。

40位数据从3358www.Sina.com/DHT11的数据端子输出,微处理器根据I/O电平的变化接收40位数据,位数据为“0”

的格式为50微秒的低电平和26-28微秒的高电平,位数据“1”的格式为50微秒的低电平加70

微秒的高水平。 位数据“0”、“1”格式的信号如下。

enter;">

(我们可以把这一段的时序理解为,我们主机先把数据线拉低50us,然后延时等待40us,然后再去读取信号线的电平,如果为低电平,则为位“0”;如果为高电平,则为位“1”)。

结束信号:DHT11 的 DATA 引脚输出 40 位数据后,继续输出低电平 50 微秒后转为输入状态,由于上拉电阻随
之变为高电平。但 DHT11 内部重测环境温湿度数据,幵记录数据,等待外部信号的到来。

我们在数据手册上了解的就这么多就可以了。

 

同时,我自己也对DHT11的时序做了一个总结

一. 单片机上点后1s内不读取(不重要)

二. 主机(单片机)发送起始信号:1.主机先拉高data。2.拉低data延迟18ms。
                                3.拉高data(单片机引脚设置为输入)。
                                
三. 从机(DHT11)收到起始信号后进行应答:
        从机拉低data,主机读取到data线被拉低持续80us后从机拉高data线,
        持续80us,直到高电平结束,意味着主机可以开始接受数据。
       
四. 主机开始接收数据:
        1.主机先把data线拉高(io设置为输入)。
        2.从机把data线拉低,主机读取data线电平,直到低电平结束(大约50us)
        从机拉高data线后,延迟40us左右(28~70us之间)主机再次读取data线
        电平,如果为低电平,则为“0”,如果为高电平,则为“1”。
        3.继续重复上述1,2步骤累计40次。

五. data线拉低50us代表读取结束

六. 校验数据

 

那么我们在程序上应该如何设计呢?(这里我的程序是基于stm32微处理器来讲解的,其他单片机也一样的操作,时序都是相同的)

 

准备阶段我们先要有3个函数,数据引脚初始化函数,还有数据引脚切换输入输出方向的函数。

void dht11_init (void ){ GPIO_InitTypeDef GPIO_InitStructure; /* Enable clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); /* Configure Ports */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_SetBits(GPIOA, GPIO_Pin_7);}void mode_input(void ){ GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOA, &GPIO_InitStructure);}void mode_output(void ){ GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOA, &GPIO_InitStructure);}

接下来我们就再写一个函数,来读取dht11数据即可

unsigned int dht11_read(void){ int i; long long val; int timeout; GPIO_ResetBits(GPIOA, GPIO_Pin_7); delay_us(18000); //pulldown for 18ms GPIO_SetBits(GPIOA, GPIO_Pin_7); delay_us( 20 );//pullup for 30us mode_input(); //等待dht11拉高80us timeout = 5000; while( (! GPIO_ReadInputDataBit (GPIOA, GPIO_Pin_7)) && (timeout > 0) ) timeout--; //wait HIGH //等待dht11拉低80us timeout = 5000; while( GPIO_ReadInputDataBit (GPIOA, GPIO_Pin_7) && (timeout > 0) ) timeout-- ; //wait LOW#define CHECK_TIME 28 for(i=0;i<40;i++) {timeout = 5000;while( (! GPIO_ReadInputDataBit (GPIOA, GPIO_Pin_7)) && (timeout > 0) ) timeout--; //wait HIGHdelay_us(CHECK_TIME);if ( GPIO_ReadInputDataBit (GPIOA, GPIO_Pin_7) ){ val=(val<<1)+1;} else { val<<=1;}timeout = 5000;while( GPIO_ReadInputDataBit (GPIOA, GPIO_Pin_7) && (timeout > 0) ) timeout-- ; //wait LOW } mode_output(); GPIO_SetBits(GPIOA, GPIO_Pin_7); if (((val>>32)+(val>>24)+(val>>16)+(val>>8) -val ) & 0xff ) return 0; //校验 else return val>>8; }

只要按照上述的时序步骤来操作,就能够读取出DHT11的温湿度值啦。

同时我们要注意,只有读出来的数据校验通过了,我们才使用这一次的温湿度数据。

还有他读取出来40位数据的数据结构: 8位湿度整数数据+8位湿度小数数据+8位温度整数数据+8位温度小数数据+8位校验位

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。