传感器驱动系列之DHT11温湿度传感器

本文详细介绍了DHT11数字温湿度传感器的工作原理、单总线接口、通信流程以及在STM32平台上的驱动源码实现,包括初始化、数据读取和补偿值设置等内容。
摘要由CSDN通过智能技术生成

一、温湿度传感器简介

        DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器,它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性和卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点,如图1所示。

图1  DHT11温湿度传感器实物图

        其中每个DHT11传感器的校准系数以程序的形式存在OTP内存中,传感器内部在检测信号的处理过程中要调用这些校准系数,这也就导致了每个传感器的系数不一样,因此可能测得的温湿度数据值也不一样,在实际使用过程中需要加入温湿度补偿值以便让其可以适应大多数应用场合。DHT11的引脚说明见下图2所示。

图2  DHT11温湿度传感器引脚说明

        DHT11温湿度传感器采用单线制串行接口,使系统集成变得简易快捷。其拥有的超小体积、极低功耗,信号传输距离可达 60 米以上,使其成为该类应用中,在苛刻应用场合的最佳选择。

二、工作原理

       单总线即只有一根数据线,系统中的数据交换、控制均由数据线完成。设备(微处理器)通过一个漏极开路或三态端口连至该数据线,以允许设备在不发送数据时能够释放总线,而让其它设备使用总线;单总线通常要求外接一个约 4.7kΩ的上拉电阻,这样,当总线闲置时,其状态为高电平。由于它们是主从结构,只有主机呼叫传感器时,传感器才会应答,因此主机访问传感器都必须严格遵循单总线序列,如果出现序列混乱,传感器将不响应主机。

        DHT11温湿度传感器的功耗很低,在5V电源电压下,工作平均最大电流 0.5mA。其工作参数如下图3所示。

图3  DHT11传感器工作参数

        DHT11 数字湿温度传感器采用单总线数据格式,即单个数据引脚端口完成输入输出双向传输。DHT11上电后,需要等待1s以越过不稳定状态。其数据包由 5Byte(40Bit)组成。数据分小数部分和整数部分,一次完整的数据传输为40bit,高位先出。DHT11的数据格式为:

8bit湿度整数数据 8bit湿度小数数据 8bit温度整数数据 8bit温度小数数据 8bit校验和

        其中8bit校验和的值为前四个字节相加。传感器数据输出的是未编码的二进制数据。数据(湿度、温度、整数、小数)之间应该分开处理。例如,某次从DHT11读到的数据如图4所示。

图4  读取DHT11温湿度数据

        由以上数据就可得到湿度和温度的值,计算方法如下:

湿度 = byte4 . byte3 45.0 (RH)

温度 = byte2 . byte1 28.0 ( )

校验 = byte4 + byte3 + byte2 + byte1 73 (湿度+温度)   --->   (校验正确)

        DHT11 和 MCU 的一次通信最大为 3ms 左右,因此在使用MCU主机连续读取温湿度传感器数据的时间间隔不要小于100ms。DHT11 的数据通信流程如图5所示。

图5  DHT11数据通信流程

        上图中每个信号的详细说明如下:t1时刻:主机(MCU)发送开始信号,即:拉低数据线,保持至少18ms;t2时刻:主机(MCU)拉高数据线20~40us,然后判断DHT11是否响应;t3时刻:DHT11拉低数据线40~50us,作为响应信号;t4时刻:DHT11 拉高数据线,保持40~50us后,开始输出数据。

        DHT11 输出数据0的时序如下图6所示。

图6  DHT11输出数据0

        DHT11 输出数据1的时序如下图7所示。

图7  DHT11 输出数据1

三、STM32驱动源码

        由于上述已经对传感器原理进行了详细描述,这里以STM32的驱动源码实现。dht11.c文件的代码如下:

#include "dht11.h"
#include "delay.h"

static STRUCT_DHT11_TYPEDEF dht11; /* 定义结构体用于保存传感器获取的数据 */

/*
 * 函数名称 : dht11_init
 * 函数功能 : 初始化DHT11的IO口(DQ)
 * 参    数 : 无
 * 返 回 值 : 无
 */
void dht11_init(void)
{
    /* ----- 1. dht11 IO口初始化 ----- */
    RCC_APB2PeriphClockCmd(DHT11_GPIO_CLK, ENABLE);     /* 使能端口时钟 */
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin   = DHT11_GPIO_PIN;     /* 端口配置 */
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;   /* 推挽输出 */
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(DHT11_GPIO_PORT, &GPIO_InitStructure);    /* 初始化IO口 */
    
    /* ----- 2. dht11结构体初始化 ----- */
    dht11.temperature = 0.f;
    dht11.humidity = 0.f;
    dht11.temp_offset = 0.f;
    dht11.humi_offset = 0.f;
}

/*
 * 函数名称 : dht11_io_inout
 * 函数功能 : 配置DQ引脚为输入/输出模式
 * 参    数 : dir io方向 0-输入 1-输出
 * 返 回 值 : 无
 */
static void dht11_io_inout(uint8_t dir)
{
    RCC_APB2PeriphClockCmd(DHT11_GPIO_CLK, ENABLE);         /* 使能端口时钟 */
    
    GPIO_InitTypeDef  GPIO_InitStructure;
    if( !dir ) {
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;/* 浮空输入 */
    } else {
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;    /* 推挽输出 */
    }
    GPIO_InitStructure.GPIO_Pin = DHT11_GPIO_PIN;           /* 端口配置 */
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(DHT11_GPIO_PORT, &GPIO_InitStructure);        /* 初始化IO口 */
}

/*
 * 函数名称 : dht11_start
 * 函数功能 : 向DHT11发送起始信号
 * 参    数 : 无
 * 返 回 值 : 无
 */
static void dht11_start(void)
{
    dht11_io_inout(1);  /* 配置为输出模式 */
    DHT11_DQ(0);        /* 拉低DQ引脚 */
    delay_ms(20);       /* 拉低至少18ms */
    DHT11_DQ(1);        /* 拉高DQ引脚 */
    delay_us(30);       /* 主机拉高20~40us */
}

/*
 * 函数名称 : dht11_check
 * 函数功能 : 等待DHT11的回应
 * 参    数 : 无
 * 返 回 值 : 1 -- 通信失败; 0 -- 通信成功
 */
static uint8_t dht11_check(void)
{
    uint8_t retry = 0;
    dht11_io_inout(0);  /* 配置为输入模式 */
    
    while(!DHT11_DQ_IN) {/* DHT11会拉低40~80us */
        retry ++;
        delay_us(1);
        if(retry >= 100)
            return 1;
    }
    retry = 0;
    while(DHT11_DQ_IN){/* DHT11拉低后会再次拉高40~80us */
        retry ++;
        delay_us(1);
        if(retry >= 100)
            return 1;
    }
    return 0;
}

/*
 * 函数名称 : dht11_readBit
 * 函数功能 : 从DHT11读取一个比特
 * 参    数 : 无
 * 返 回 值 : 1 -- 读取数据为1; 0 -- 读取数据为0
 */
static uint8_t dht11_readBit(void)
{
    uint8_t retry = 0;
    while(DHT11_DQ_IN && retry<100){ /* 等待变为低电平 */
        retry ++;
        delay_us(1);
    }
    retry = 0;
    while(!DHT11_DQ_IN && retry<100) { /* 等待变高电平 */
        retry ++;
        delay_us(1);
    }
    delay_us(40);   /* 等待40us 用于判断高低电平,即数据1或0 */
    if(DHT11_DQ_IN)
        return 1;
    return 0;
}

/*
 * 函数名称 : dht11_readByte
 * 函数功能 : 从DHT11读取一个字节
 * 参    数 : 无
 * 返 回 值 : 读到的数据
 */
static uint8_t dht11_readByte(void)
{
    uint8_t i,data=0;
    for(i=0;i<8;i++) {
        data <<= 1;
        data  |= dht11_readBit();
    }
    return data;
}

/* -------------------------------------- 接口函数 --------------------------------- */
/*
 * 函数名称 : dht11_measure
 * 函数功能 : dht11测量数据(温度、湿度)
 * 参    数 : 无
 * 返 回 值 : 无
 */
void dht11_measure(void)
{
    int i;
    uint8_t buf[5];
    dht11_start();
    if(!dht11_check()) {
        for(i=0;i<5;i++)//读取数据 数据格式为 湿度整数 + 湿度小数 + 温度整数 + 温度小数 + 校验和(前四位之和)
            buf[i] = dht11_readByte();
        if((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4]) {
            dht11.temperature = buf[0] * 1.f + buf[1] * 0.1f;
            dht11.humidity    = buf[2] * 1.f + buf[3] * 0.1f;
        }
    }
}

/*
 * 函数名称 : dht11_getTemperature
 * 函数功能 : 获取dht11的温度数据
 * 参    数 : 无
 * 返 回 值 : 温度值(范围:0~50°)
 */
float dht11_getTemperature(void)
{
    return (dht11.temperature + dht11.temp_offset);
}

/*
 * 函数名称 : dht11_getHumidity
 * 函数功能 : 获取dht11的湿度数据
 * 参    数 : 无
 * 返 回 值 : 湿度值(范围:20%~90%)
 */
float dht11_getHumidity(void)
{
    return (dht11.humidity + dht11.humi_offset);
}

/*
 * 函数名称 : dht11_set_temperature_offset
 * 函数功能 : 设置dht11温度数据补偿值
 * 参    数 : 温度数据补偿值
 * 返 回 值 : 无
 */
void dht11_set_temperature_offset(float offset)
{
    dht11.temp_offset = offset;
}

/*
 * 函数名称 : dht11_set_humidity_offset
 * 函数功能 : 设置dht11湿度数据补偿值
 * 参    数 : 湿度数据补偿值
 * 返 回 值 : 无
 */
void dht11_set_humidity_offset(float offset)
{
    dht11.humi_offset = offset;
}

        dht11.h文件实现如下:

#ifndef __DHT11_H
#define __DHT11_H 

#include "stm32f10x.h"  

typedef struct {
    float temperature;  /* 温度数据 */
    float humidity;     /* 湿度数据 */
    float temp_offset;  /* 温度补偿 */
    float humi_offset;  /* 湿度补偿 */
} STRUCT_DHT11_TYPEDEF;

/* 定义DQ端口 可以直接修改该宏定义更改DQ端口引脚定义 */
#define     DHT11_GPIO_CLK      RCC_APB2Periph_GPIOC
#define     DHT11_GPIO_PORT     GPIOC
#define     DHT11_GPIO_PIN      GPIO_Pin_7

#define     DHT11_DQ(x)         GPIO_WriteBit(DHT11_GPIO_PORT, DHT11_GPIO_PIN, (BitAction)x)
#define     DHT11_DQ_IN         GPIO_ReadInputDataBit(DHT11_GPIO_PORT, DHT11_GPIO_PIN)

/* ----------------------------- DHT11操作函数 ----------------------------- */
void        dht11_init(void);           /* 初始化DHT11 */
void        dht11_measure(void);        /* 采集一次温湿度传感器数据 只有调用该函数后才能获取到温湿度数据 */
float       dht11_getTemperature(void); /* 读取温度数据 */
float       dht11_getHumidity(void);    /* 读取湿度数据 */
void        dht11_set_temperature_offset(float offset); /* 设置温度补偿 */
void        dht11_set_humidity_offset(float offset);    /* 设置湿度补偿 */

#endif

        代码一般驱动和使用流程如下:

1. 在dht11.h文件中修改DQ端口宏定义,使之适配自己的端口引脚;

2. 调用dht11_init()函数用于初始化传感器引脚;

3. 周期性的调用dht11_measure()函数用于测量传感器数据(注意:这里的测量/采集数据并没有返回值进行数据返回);

4. 在需要获取温度和湿度数据的地方调用dht11_getTemperature()和dht11_getHumidity()获取传感器的数据;

5. 若传感器数据与本地的温湿度数据有差异的话,可以调用dht11_set_temperature_offset()或dht11_set_humidity_offset()设置温湿度的补偿值。

  • 33
    点赞
  • 123
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
### 回答1: DHT11湿度传感器是一种数字化的湿度传感器,可与STM32单片机相连并进行数据的采集和处理。以下是关于DHT11湿度传感器STM32程序下载的说明。 1. 首先,需要准备一台已安装STM32开发环境的计算机。这个开发环境可以是Keil、IAR等常用的嵌入式开发工具。 2. 接下来,需要根据具体的硬件连接情况,将DHT11传感器STM32单片机相连。一般来说,DHT11传感器的供电线连接到STM32的供电引脚上,数据线连接到STM32的某个IO口,接地线连接到STM32的接地引脚上。 3. 然后,打开STM32开发环境,创建一个新的工程用于DHT11湿度传感器程序的开发。选择适合自己的芯片型号,配置相应的系统时钟等参数。 4. 根据DHT11的通信协议,编写相应的程序代码。代码中需要使用STM32的IO口来读取传感器的数据,将数据转换为度和湿度值,并进行相应的处理。 5. 在代码编写完成后,进行编译和链接,并生成可执行文件。将可执行文件下载到STM32单片机上,可以通过JTAG/SWD等调试工具来完成下载。 6. 最后,将STM32与已下载的程序电路连接好,给STM32供电,开始进行测试。通过使用串口调试助手或者LCD屏幕来显示度和湿度数据,以验证程序的正确性。 以上是关于DHT11湿度传感器STM32程序下载的一般步骤。需要提醒的是,在具体的开发过程中,还需要根据实际情况进行程序的调试和优化,以保证传感器STM32的正常工作。 ### 回答2: DHT11湿度传感器是一种常用的数字湿度传感器,可以与STM32微控制器一起使用。要下载DHT11湿度传感器STM32程序,需要进行以下几个步骤: 1. 配置STM32的开发环境:首先要确保已经安装了适当的开发环境,例如Keil或者STM32CubeIDE等。 2. 编写程序代码:为了读取DHT11传感器的数据,需要编写相应的程序代码。可以使用C语言或者汇编语言来编写。在代码中,需要包含DHT11驱动库或者编写自己的库函数来与传感器进行通信。 3. 配置STM32的引脚:在STM32上,需要选择合适的引脚连接DHT11传感器。可以参考DHT11的数据手册或者资料表来确定引脚的配置。 4. 下载程序到STM32:在完成程序代码编写和引脚配置后,可以通过调试器将程序下载到STM32微控制器上。根据开发环境的不同,下载的具体步骤会有所不同。 5. 测试程序:下载完成后,可以将STM32DHT11传感器连接,并通过串口或者其他方式将读取到的湿度数据传输到电脑或其他设备上,进行测试。在测试过程中,需要确保程序能够正确地读取并解析DHT11传感器的数据,并将其显示出来。 总结起来,下载DHT11湿度传感器STM32程序,需要配置开发环境、编写程序代码、配置引脚、下载程序到STM32,并进行测试。以上这些步骤的具体实现方式,可以根据具体的开发环境和需求进行调整。 ### 回答3: DHT11湿度传感器是一种常用的数字式湿度传感器。作为STM32微控制器的用户,我们可以通过编写程序来获取DHT11传感器度和湿度数据。 首先,我们需要连接DHT11传感器STM32微控制器。DHT11传感器有三个引脚:VCC(正电源)、DATA(数据信号)和GND(地)。我们需要将VCC引脚连接到STM32的3.3V电源,将DATA引脚连接到一个GPIO引脚(例如PA0),将GND引脚连接到GND。 其次,我们需要编写STM32的程序来读取DHT11传感器的数据。具体的程序可以通过使用STM32的GPIO库来配置和读取GPIO引脚的状态。我们需要将DATA引脚设置为输出模式,并给它一个高电平(1ms),然后将DATA引脚设置为输入模式,等待DHT11传感器的响应。一旦DHT11传感器给出响应,我们可以开始读取它发送的数据。DHT11发送的数据位共有40位,我们需要通过计时来确定每位数据的1或0的时间长度。 最后,我们可以将获取的数据进行处理,将度和湿度的数值提取出来,并进行进一步的处理或显示。我们可以使用串口或LCD等外设来进行数据的显示和记录。 总之,通过编写STM32的程序,我们可以实现DHT11湿度传感器的数据获取功能。这个程序可以根据具体的需求进行进一步的扩展和优化,以满足不同的应用场景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值