基于STM32的DHT11温湿度测量

目录

1.简介

2.主要参数 

 3.引脚说明

4.注意事项

5.单总线协议

6.数据格式

7.工作时序

8.分模块编写程序


1.简介

  DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。传感器包括一个电容式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。DHT11实物图和内部框图如下图。
DHT11
DHT11内部框图
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的所有内容了,更多传感器驱动代码请订阅我的传感器专栏

  • 2
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值