DHT22温湿度传感器概述
DHT22 湿敏电容数字温湿度模块是一款含有己校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。传感器包括一个电容式感湿元件和一个高精度测温元件,并与一个高性能 8 位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。标准单总线接口,使系统集成变得简易快捷。超小的体积、极低的功耗,信号传输距离可达 20 米以上,使其成为各类应用甚至最为苛刻的应用场合的最佳选择。
以下为 DHT22 湿敏电容数字温湿度模块的实物图与外形尺寸。
单总线接口定义
引脚① VDD 电源(3.3v-5.5v)
引脚② SDA 串行数据,双向口
引脚③ NC 空脚
引脚④ GND 接地
DHT22温湿度模块引脚分配图
单总线通信协议
DHT22温湿度传感器采用简化的单总线通信单总线即只有一根数据线,系统中的数据交换、控制均由数据线完成。设备(微处理器)通过一个漏极开路或三态端口连至该数据线,以允许设备在不发送数据时能够释放总线,而让其它设备使用总线;单总线通常要求外接一个约 5.1kΩ的上拉电阻,这样,当总线闲置时,其状态为高电平。由于它们是主从结构,只有主机呼叫传感器时,传感器才会应答,因此主机访问传感器都必须严格遵循单总线序列,如果出现序列混乱,传感器将不响应主机。
DHT22单总线通信协议说明
单总线数据计算示例
外设读取步骤
步骤一:DHT22 上电后(DHT22 上电后要等待 2S 以越过不稳定状态,在此期间读取设备不能发送任何指令),测试环境温湿度数据,并记录数据,此后传感器自动转入休眠状态。DHT22的 SDA 数据线由上拉电阻拉高一直保持高电平,此时DHT22的 SDA 引脚处于输入状态,时刻检测外部信号。
//复位DHT22
//主机信号
void DHT22_Rst(void)
{
DHT22_IO_OUT();//SET OUTPUT
DHT22_DQ_OUT=0;//拉低DQ
delay_ms(1);//主机知道拉低500us
DHT22_DQ_OUT=1;//DQ=1
delay_us(30);//主机拉高20~40us
}
步骤二:微处理器的 I/O 设置为输出,同时输出低电平,且低电平保持时间不能小于 800us,典型值是拉低 1MS,然后微处理器的 I/O 设置为输入状态,释放总线,由于上拉电阻,微处理器的 I/O 即的 SDA 数据线也随之变高,等主机释放总线后,DHT22 发送响应信号,即输出 80 微秒的低电平作为应答信号,紧接着输出 80 微秒的高电平通知外设准备接收数据,信号传输如下图所示。
//等待DHT22的回应
//返回1:未检测到DHT22的存在
//返回0:DHT22已连接
//数据维持电平固定时间为80us左右,故等待时间为其2倍,即200us,观察200us之内
//检查电平状态是否会改变,先变低再变高
u8 DHT22_Check(void)
{
u8 retry=0;
DHT22_IO_IN();//SET INPUT
while (DHT22_DQ_IN&&retry<200)//等待低电平
{
retry++;
delay_us(1);
}
if(retry>=200)return 1;//如果retry大于200直接返回1
else retry=0;
while (!DHT22_DQ_IN&&retry<200)//DHT22拉低后会再次拉高80us左右
{
retry++;
delay_us(1);
}
if(retry>=200)return 1;
else return 0;
}
步骤三:DHT22发送完响应后,随后由数据总线 SDA 连续串行输出 40 位数据,微处理器根据 I/O 电平的变化接收 40 位数据。
位数据“0”的格式为: 50 微秒的低电平加 26-28 微秒的高电平;
位数据“1”的格式为: 50 微秒的低电平加 70 微秒的高电平;
位数据“0”、位数据“1”格式信号如下图所示:
//从DHT22读取一个位
//返回值:1/0
u8 DHT22_Read_Bit(void)
{
u8 retry=0;
while(DHT22_DQ_IN&&retry<200)//等待变为低电平
{
retry++;
delay_us(1);
}
retry=0;
while(!DHT22_DQ_IN&&retry<200)//等待变高电平
{
retry++;
delay_us(1);
}
delay_us(40);//等待40us
if(DHT22_DQ_IN)return 1;
return 0;
}
//从DHT22读取一个字节
//返回值:读到的数据
u8 DHT22_Read_Byte(void)
{
u8 i,dat;
dat=0;
for (i=0;i<8;i++)
{
dat<<=1;
dat|=DHT22_Read_Bit();
}
return dat;
}
DHT22的数据总线 SDA 输出 40 位数据后,继续输出低电平 50 微秒后转为输入状态,由于上拉电阻随之变为高电平。同时DHT22内部重测环境温湿度数据,并记录数据,测试记录结束,单片机自动进入休眠状态。单片机只有收到主机的起始信号后,才重新唤醒传感器,进入工作状态。
//从DHT22读取一次数据
//temp:温度值(范围:-40~80°)
//humi:湿度值(范围:20%~100%)
//返回值:0,正常;1,读取失败DHT22连接断开
u8 DHT22_Read_Data(u16 *temp,u16 *humi)
{
u8 buf[5];
u8 i,sum;
DHT22_Rst();//等待响应
if(DHT22_Check()==0)
{
for(i=0;i<5;i++)//读取40位数据
{
buf[i]=DHT22_Read_Byte();
}
// *humi=buf[0]*256+buf[1];
// *temp=buf[2]*256+buf[3];
sum =((buf[0]+buf[1]+buf[2]+buf[3])&0xFF);
if(sum==buf[4])//校验
{
*humi=buf[0]*256+buf[1];
*temp=buf[2]*256+buf[3];
}
}else return 1;
return 0;
}
//初始化DHT22的IO口 DQ 同时检测DHT22的存在
//返回1:不存在
//返回0:存在
u8 DHT22_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); //使能PE端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //PE4端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &GPIO_InitStructure); //初始化IO口
GPIO_SetBits(GPIOE,GPIO_Pin_4); //PE4 输出高
DHT22_Rst(); //复位DHT22
return DHT22_Check();//等待DHT22的回应
}
以上的GPIO口PE4对应的为DHT22上的SDA引脚,大家可以更改为自己所对应的GPIO口。
以下为dht22.h的声明
#ifndef __DHT22_H
#define __DHT22_H
#include "sys.h"
//
//多功能传感器
//V2
//DHT22_IO -> PE.4
//All rights reserved
//
//IO方向设置
#define DHT22_IO_IN() {GPIOE->CRL&=0XFFF0FFFF;GPIOE->CRL|=8<<16;}
#define DHT22_IO_OUT() {GPIOE->CRL&=0XFFF0FFFF;GPIOE->CRL|=3<<16;}
IO操作函数
#define DHT22_DQ_OUT PEout(4) //数据端口 PE4
#define DHT22_DQ_IN PEin(4) //数据端口 PE4
u8 DHT22_Init(void);//初始化DHT22
u8 DHT22_Read_Data(u16 *temp,u16 *humi);//读取温湿度
u8 DHT22_Read_Byte(void);//读出一个字节
u8 DHT22_Read_Bit(void);//读出一个位
u8 DHT22_Check(void);//检测是否存在DHT22
void DHT22_Rst(void);//复位DHT22
#endif