能够感应外界温湿度的器件。
DHT11数字温湿度传感器是自带校准标准数字信号输出温湿度 复合传感器。
传感器性能说明:
测量范围:20%~90%RH 0~50℃
湿度精度:+-5%RH
温度精度:+-2℃
分辨率:1(可感知的被测量的最小变化能力)
数据格式
接收到传感器的40位数据:
0011 0101 0000 0000 0001 1000 0000 0000 0100 1101
湿度高8位 湿度低8位 温度高8位 温度低8位 校验位
传感器电源引脚说明
供电3.3-5v(宽电压)。传感器上电之后 需等待1s越过不稳定状态(可以忽略不计)
DHT100(4阵单排直插)
1、VCC (供电引脚)
2、DATA (串行数据,单总线)
3、NC (空脚,需要悬空。无效,可能为了起到更好的固定效果而存在)
4、GND (表示接地,电源负极)
计算
前32位相加=校验位
0011 0101 + 0000 0000 + 0001 1000 + 0000 0000 = 0100 1101(表示数据接收正确)
湿度高8位:0011 0101 = 35H = 53%RH
温度高8位:0001 1000 = 18H = 24℃
总结:低8位是0,所以可以互虐不看。
MCU角度分析:
用户MCU发送开始信号后,DHT11从低功耗模式转换为高速模式,等待主机开始信号结束后,给MCU发送响应信号,接着DHT11发送40bit数据,触发一次采集。(用户可选择读取部分数据 , MCU唤醒DHT11)
DHT11角度分析:
在从模式下DHT11接收到开始信号并触发一次温湿度采集,如果第二次为接收到MCU开始信号,DHT11不会主动温湿度采集。采集数据结束后转换到低功耗模式,(相当于休眠模式等待MCU唤醒)
数据时序(编码依据)
数据时序图:
MCU发开始信号及DHT11响应时序图:
编码思路:
一、单片机上电1s内不读取(不重要)
二、主机(单片机)发送开始信号:
1、总线空闲状态是高电平(先拉高)
2、主机拉低电平持续时间>18ms
3、主机拉高电平(单机片引脚设置为输入)
三、从机(DHT100传感器)收到信号响应应答:
从机拉低电平,主机读取电平被拉低持续80us后从机拉高电平再次持续80us,
直到高电平结束。意味着主机可以接收数据。
四:主机开始接收数据
1、主机IO设置为输入
2、从机把总线电平拉低,主机读取总线电平,直到低电平结束(大约50us),
(从机发回来的数据位表示)
从机拉高电平,延时40us左右(取 26-70us之间 中间值),主机再次读取电平。
(在40us内读到的高电平表示0,超出40us表示1)
3、重复执行1、2两步40次。(目的读取40位)
五:从机拉低总线50us,随后总线由上拉电阻拉高电平进入空闲状态。
具体实现
/*
* dht11.c
*
* created: 2022/06/22
* author:
*/
#include "ls1b.h"
#include "ls1b_gpio.h"
#include "dht11.h"
#include "tick.h"
//单总线 控数据引脚 电平高低 gpio输入的值(传感器给的电平高低)
void DHT11_DQ_OUT(int e)
{
gpio_enable(DHT11_IO, e); // Pin: SPI0_CS2
}
void DHT11_DQ_IN(void)
{
gpio_read(DHT11_IO);
}
//单总线设置为输入
void DHT11_IO_IN(void)
{
gpio_enable(DHT11_IO, DIR_IN);
}
//单总线设置为输出
void DHT11_IO_OUT(void)
{
gpio_enable(DHT11_IO, DIR_OUT);
}
//复位(开始信号)DHT11
void DHT11_Reset(void)
{
DHT11_IO_OUT(); //设置 为 输出
DHT11_DQ_OUT(0); //io为低电平。
delay_ms(19); //持续时间 >=18ms
DHT11_DQ_OUT(1); //主机拉高
delay_us(30); //持续时间30us
}
//检测传感器(判断是否响应)
unsigned char DHT11_Check(void)
{
unsigned char flag=0; //延时条件
DHT11_IO_IN(); //改变IO输入方向为输入 电平接的复位信号的高电平。
while(gpio_read(DHT11_IO)&&flag<100) //
{
flag++;
delay_us(1);
}
if(flag>=100)return 1;
else flag=0;
while(!gpio_read(DHT11_IO)&&flag<100)
{
flag++;
delay_us(1);
}
if(flag>=100)
return 1;
return 0;
}
//读取一位
unsigned char DHT11_Read_Bit()
{
unsigned char flag;
while(gpio_read(DHT11_IO)&&flag<100)
{
flag++;
delay_us(1);
if(flag==99)
{
return -1;
}
}
flag=0;
while(gpio_read(DHT11_IO)&&flag<100)
{
flag++;
delay_us(1);
}
delay_us(40); //取中间值。。26-70us
if(gpio_read(DHT11_IO))return 1;
else return 0;
}
//读一字
unsigned char DHT11_Read_Byte()
{
unsigned char i,flag;
flag=0;
for(i=0; i<8; i++)
{
flag<<=1;
flag|=DHT11_Read_Bit();
}
return flag;
}
//读取温湿度数据
unsigned char DHT11_read_Data(unsigned int *temp,unsigned int *huami)
{
unsigned char buf[5]; //五个字节
unsigned char i;
DHT11_Reset(); //复位。
if(DHT11_Check()==0)
{
for(i=0; i<5; i++)
{
buf[i]=DHT11_Read_Byte();
}
if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
{
*temp = buf[0]*10+buf[1];
*huami= buf[2]*10+buf[3];
}
}
else return 1;
return 0;
}
//初始化
unsigned char DHT11_Init(void)
{
gpio_enable(DHT11_IO,DIR_OUT);
gpio_write(DHT11_IO,1);
DHT11_Reset();
return DHT11_Check();
}
1 条评论
感谢分享,赞一个