目录
1.简介
DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。传感器包括一个电容式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。DHT11实物图和内部框图如下图。
2.主要参数
湿度量程 | 5 - 95 %RH | 误差:±5%RH(25℃) |
湿度量程 | -20 - 60 ℃ | 误差:±2℃(25℃) |
供电电压 | 3.3 - 5.5 | 单位:V |
供电电流 |
0.06(待机) 、1.0(测量)
| 单位:mA |
采样周期 | >2 | 单位:s |
3.引脚说明
VDD |
供电3.3~5.5V DC
|
DATA |
串行数据,单总线
|
NC |
空脚
|
GND |
接地,电源负极
|
4.注意事项
1、典型应用电路中建议连接线长度短于5m时用4.7K上拉电阻,大于5m时根据实际情况降低上拉电阻的阻值。2、使用3.3V电压供电时连接线尽量短,接线过长会导致传感器供电不足,造成测量偏差。3、每次读出的温湿度数值是上一次测量的结果,欲获取实时数据,需连续读取2次,但不建议连续多次读取传感器,每次读取传感器间隔大于2秒即可获得准确的数据。4、电源部分如有波动,会影响到温度。如使用开关电源,温度就会跳动。
5.单总线协议
DHT11器件采用单总线通信来实现数据交换和控制,这种通信方式只有一根数据线。设备可以通过漏极开路或三态端口连接到数据线上,以允许设备在不发送数据时释放总线并让其他设备使用。为了让总线保持高电平状态,通常需要外接一个约4.7kΩ的上拉电阻。由于DHT11器件采用主从结构,只有在主机呼叫从机时,从机才能作出响应。因此,主机访问DHT11器件时必须严格遵循单总线序列,否则器件将不会响应主机。
6.数据格式
DATA用于微处理器与DHT11之间的通讯和同步,采用单总线数据格式,一次传送40位数据,高位先出。
(1)数据格式:
8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据+8bit校验位。注:其中湿度小数部分为0。
(2)校验位数据定义:
“8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据”8bit校验位等于所得结果的末8位。
(3)校验:
校验位=湿度高位+湿度低位+温度高位+温度低位
7.工作时序
首先主机发送开始信号,即:拉低数据线,保持t1(至少18ms)时间,然后拉高数据线t2(20~40us)时间,然后读取DHT11的响应,正常的话,DHT11会拉低数据线,保持t3(40~50us)时间,作为响应信号,然后DHT11拉高数据线,保持t4(40~50us)时间后,开始输出数据。
8.分模块编写程序
(1)IO方向设置和输出设置
//IO方向设置
#define DHT11_IO_IN() {GPIOA->CRL&=0XFFFFFFF0;GPIOA->CRL|=8;}
#define DHT11_IO_OUT() {GPIOA->CRL&=0XFFFFFFF0;GPIOA->CRL|=3;}
//IO操作函数
#define DHT11_DQ_OUT(x) {if(x==0) GPIO_ResetBits(GPIOA,GPIO_Pin_0); else if(x==1) GPIO_SetBits(GPIOA,GPIO_Pin_0);}//数据端口
#define DHT11_DQ_IN GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) //数据端口
(2)STM32发出复位信号
拉低数据线,保持t1(至少18ms)时间,然后拉高数据线t2 (20~40us)时间
void DHT11_Rst(void)
{
DHT11_IO_OUT(); //SET OUTPUT
DHT11_DQ_OUT(0); //拉低DQ 至少18ms
delay_ms(20);
DHT11_DQ_OUT(1); //主机拉高20~40us
delay_us(30);
}
(3)等待DHT11回应(检测DHT11是否存在)
DHT11会拉低数据线,保持t3(40~50us)时间,作为响应信号,然后DHT11拉高数据线,保持t4(40~50us)时间
u8 DHT11_Check(void)
{
u8 retry = 0;
DHT11_IO_IN();//SET INPUT
while(DHT11_DQ_IN && retry < 100) //DHT11会拉低40~80us(拉低会跳出while)
{
retry++;
delay_us(1);
}
if(retry >= 100)
return 1;
else
retry = 0;
while(!DHT11_DQ_IN && retry < 100) //DHT11拉低后会再次拉高(DHT11_DQ_IN = 1)40~80us (!DHT11_DQ_IN 为0 跳出while 表示DHT11拉高)
{
retry++;
delay_us(1);
}
if(retry >= 100)
{
return 1;
}
return 0;
}
(4)读一个位数据
DHT11发送0时序
首先12-14us的开始信号,然后是26-28us高电平(代表0)
DHT11发送1时序
首先12-14us的开始信号,然后是116-118us高电平(代表1)
u8 DHT11_Read_Bit(void)
{
u8 retry = 0;
while(DHT11_DQ_IN && retry < 100) //主机读时 DHT11会先拉低12~14us(拉低会跳出while)
{
retry++;
delay_us(1);
}
if(retry >= 100)
return 1;
else
retry = 0;
while(!DHT11_DQ_IN && retry < 100) //主机读时 为0(再拉高26~28us) 为1(再拉高116~118us)
{
retry++;
delay_us(1);
}
delay_us(40); //等40us 判断此时电位 高电平为1 低电平为0
if(DHT11_DQ_IN)
return 1;
else
return 0;
}
(5)读一个字节数据
u8 DHT11_Read_Byte(void)
{
u8 i, dat;
dat = 0;
for (i = 0; i < 8; i++)
{
dat <<= 1;
dat |= DHT11_Read_Bit();
}
return dat;
}
(6)一次性读取数据并校验
u8 DHT11_Read_Data(u8 *temp, u8 *humi)
{
u8 buf[5];
u8 i;
DHT11_Rst();
if(DHT11_Check() == 0) //温湿度传感器连接正常
{
for(i = 0; i < 5; i++)
{
buf[i] = DHT11_Read_Byte(); //5个字节读入buf数组
}
if((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4])//校验 前四个字节和等于第五个字节
{
*humi = buf[0];
*temp = buf[2];
}
}
else
return 1;
return 0;
}
(7)初始化代码
u8 DHT11_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能PC端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //PC2端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化IO口
GPIO_SetBits(GPIOA, GPIO_Pin_0); //PC2 输出高
DHT11_Rst(); //复位DHT11
return DHT11_Check();//等待DHT11的回应
}
说明:本文章部分内容参考 ASARI温湿度模块DHT11 产品手册
以上就是DHT11的所有内容了,更多传感器驱动代码请订阅我的传感器专栏