手把手教你玩转DHT11(原理+驱动)

news2024/11/27 16:43:05

大家生活中一定经常使用温湿度数据,比如:天气预报、智能家居、智慧大屏等等。这些数据可以通过温湿度传感器进行获取。在嵌入式开发中,温湿度传感器是一种十分常用的传感器。本文将为大家介绍温湿度传感器 DHT11,内容包含模块介绍、工作原理、驱动方法,并提供编程实战示例。

1. 源码下载及前置阅读

本文首发 良许嵌入式网 :https://www.lxlinux.net/e/ ,欢迎关注!

本文所涉及的源码及安装包如下(由于平台限制,请点击以下链接阅读原文下载):

https://www.lxlinux.net/e/stm32/dht11-tutorial.html

如果不知道如何搭建 STM32 编程环境,不知道如何烧录 STM32 代码,可以阅读这篇文章:

https://www.lxlinux.net/e/stm32/stm32-quick-start-for-beginner.html

如果你连代码都不知道怎么烧录到 STM32 的,可以参考下文,提供了 5 种代码烧录方式:

https://www.lxlinux.net/e/stm32/five-ways-to-flash-program-to-stm32.html

文中所使用的芯片是 STM32F103C8T6 ,配套了一个工程模板,如果你需要自己搭建一个工程模板,可以参考下文:

https://www.lxlinux.net/e/stm32/create-stm32-hal-project-template.html

2. DHT11介绍

DHT11(数字温湿度传感器)为 3 或 4 针单排引脚封装,连接方便。具有品质卓越、超快响应、抗干扰能力强、性价比极高、超小的体积、极低的功耗的优点,使其成为在测温、测湿应用,在苛刻应用场合的一个非常不错的选择。

DHT11 内置一个电阻式感湿元件和一个 NTC 测温元件,并与一个单片机相连接(DHT11 内部)。每个 DHT11 都在极为精确的湿度校验室中进行校准,校准系数以程序的形式存在传感器中,传感器内部在检测信号的处理过程中要调用这些校准系数。DHT11 采用简易快捷的单线制串行接口,方便系统集成。

2.1 DHT11型号介绍

DHT11 有 3 脚和 4 脚两款,在使用上没有差别,接线都一样,主要接三根,四脚的款式有一脚悬空。四脚款接杜邦线会有点不稳,只能插面包板上,建议直接买三脚的。

同样可以测量温湿度的还有 DHT20、DHT22 等,都是大同小异。

DHT11 虽然可以同时测量温湿度,但是测量范围是打不过专业测温传感器的,比如 ds18b20 测量的温度范围就有 -55°C ~ 125°C,而 DHT11 只有 0~50℃。

2.2 DHT11工作参数及引脚介绍

DHT11 工作参数:

  1. 湿度测量范围:20~90%RH
  2. 湿度测量精度:±5%RH
  3. 温度测量范围:0~50℃
  4. 温度测量精度:±2℃
  5. 工作电压:DC 3.3V/5V

接线如下,别把正负极接反啦,接反会烧坏掉的。

DHT11STM32
VCC3.3/5V
DATA任意一个GPIO口
GNDGND

DHT11 采用单总线协议,也就是使用一根 DATA 线进行数据的收发。DHT11 的 DATA 线一次通讯时间 4ms 左右,数据分整数部分、小数部分和校验位,具体为: 8bit 湿度整数数据 + 8bit 湿度小数数据 + 8bit 温度整数数据 + 8bit 温度小数数据 + 8bit 校验位。

3. DHT11工作原理

3.1 正常工作验证

上电后,「电源指示灯/POWER」红灯亮,表示上电成功,正常工作。

3.2 DHT11工作时序

3.2.1 整体工作时序

DHT11 整体工作时序为:主机发送开始信号、DHT11 响应输出、主机接收 40bit 数据(湿度数据+温度数据+校验值),结束信号(可选)。具体过程如下:

  1. 总线空闲状态为高电平,主机拉低总线等待 DHT11 响应, 主机把总线拉低必须大于 18ms,保证 DHT11 能检测到起始信号;

  2. 主机发送开始信号结束后,拉高总线电平并延时等待 20-40us 后,读取 DHT11 的响应信号;

  3. DHT11 接收到主机的开始信号后,等待微处理器开始信号结束,发送 80us 低电平响应信号;

  4. DHT11 发送 80us 高电平准备发送数据;

  5. DHT11 发送 40bit 数据(湿度数据+温度数据+校验值)。

过程主机DHT11
1拉低>18ms
2拉高20~40us
3响应 80us 低电平
4拉高 80us
5发送 40bit 数据(湿度数据+温度数据+校验值)
3.2.2 起始及响应信号

总流程讲完介绍一下细分流程:

首先主机拉低总线至少 18ms,然后再拉高总线,延时 20~40us,此时起始信号(有时也叫复位信号)发送完毕。

DHT11 检测到复位信号后,触发一次采样,并拉低总线 80us 表示响应信号,告诉主机数据已经准备好了。DHT11 之后拉高总线 80us,然后开始传输数据。如果检测到响应信号为高电平,则 DHT11 初始化失败,请检查线路是否连接正常。

3.2.3 读时序

DHT11 开始传输数据。每 1bit 数据都以 50us 低电平开始,告诉主机开始传输一位数据了。DHT11 以高电平的长短定义数据位是 0 还是 1:当 50us 低电平过后拉高总线,高电平持续 26~28us 表示 0,高电平持续 70us 表示数据 1。

当最后 1bit 数据传送完毕后,DHT11 拉低总线 50us,表示数据传输完毕,随后总线由上拉电阻拉高进入空闲状态。

位数据0表示方式:

以 50us 低电平开始,高电平持续 26~28us 表示 0。

位数据1表示方式:

以 50us 低电平开始,高电平持续 70us 表示 1。

3.3 DHT11数据格式

DHT11 的 DATA 传输一次完整的数据为 40bit,按照高位在前,低位在后的顺序传输。

数据格式为:8bit 湿度整数数据 + 8bit 湿度小数数据 + 8bit 温度整数数据 + 8bit 温度小数数据 + 8bit 校验位,一共 5 字节(40bit)数据。

正常情况下,前四个字节的和刚好与校验位相等,通过这种机制可以保证数据传输的准确性。

4. 编程实战

4.1 硬件接线

本教程使用的硬件如下:

  • 单片机:STM32F103C8T6

  • 温湿度传感器:DHT11

  • 串口:USB 转 TTL

  • 烧录器:ST-LINK V2

DHT11STM32USB 转 TTL
VCC3.3/5V
DATA8
GNDG
A10TX
A9RX
GGND

我们使用 A8 作为 DHT11 的数据引脚,串口 1 进行 log 输出。

接线如下图:

4.2 加载DHT11模块

我们在模板工程里的 BSP 目录下创建一个 dht11 目录,然后创建 dht11.c 及 dht11.h 两个空文件。

打开工程,跟着我的贪吃蛇点点点:)

4.3 微秒级延时实现

DHT11 对时序要求严格,需要微妙级延时,我们常用的 HAL_Delay() 是毫秒级时延。实现微秒级延时的方法有很多,但是我们可以直接用模板工程中 delay 文件的 delay_us

void delay_us(uint32_t nus)
{
    uint32_t temp;
    SysTick->LOAD = nus * g_fac_us; /* 时间加载 */
    SysTick->VAL = 0x00;            /* 清空计数器 */
    SysTick->CTRL |= 1 << 0 ;       /* 开始倒数 */

    do
    {
        temp = SysTick->CTRL;
    } while ((temp & 0x01) && !(temp & (1 << 16))); /* CTRL.ENABLE位必须为1, 并等待时间到达 */

    SysTick->CTRL &= ~(1 << 0) ;    /* 关闭SYSTICK */
    SysTick->VAL = 0X00;            /* 清空计数器 */
}

4.4 DATA引脚配置

DHT11 采用单总线协议与单片机通信,有时作为输入有时作为输出,所以我们需要在 DATA 引脚上配置输入和输出。

void DHT_GPIO_INPUT(void) 
{
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.Pin=DHT11_PIN;
    GPIO_InitStructure.Mode=GPIO_MODE_INPUT;
    GPIO_InitStructure.Speed=GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(DHT11_IO,&GPIO_InitStructure);
}

void DHT_GPIO_OUTPUT(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.Pin=DHT11_PIN;
    GPIO_InitStructure.Mode=GPIO_MODE_OUTPUT_PP;
    GPIO_InitStructure.Speed=GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(DHT11_IO,&GPIO_InitStructure);
}

4.5 起始及响应信号实现

按照前面介绍的 DHT11 工作时序:

主机发送起始信号:先将总线设为输出模式,总线空闲状态为高电平,拉低总线至少 18ms,然后再拉高总线,延时 20~40us,此时复位信号发送完毕。

DHT11 发送响应信号:总线设为输入模式,使用 while(HAL_GPIO_ReadPin(DHT11_IO, DHT11_PIN)) 检测总线从高电平跳变到低电平,等待 DHT11 拉低总线 。DHT11 响应信号持续 80us,使用 while(!HAL_GPIO_ReadPin(DHT11_IO, DHT11_PIN)) 检测总线低电平跳变到高电平。之后 DHT11 拉高总线 80us ,使用 while(HAL_GPIO_ReadPin(DHT11_IO, DHT11_PIN)) 检测总线从高电平跳变到低电平,然后 DHT11 开始传输数据。

起始信号及响应信号代码如下:

void DHT11_Start()
{
    DHT_GPIO_OUTPUT();
    HAL_GPIO_WritePin(DHT11_IO, DHT11_PIN, GPIO_PIN_SET);
    HAL_GPIO_WritePin(DHT11_IO, DHT11_PIN, GPIO_PIN_RESET);
    HAL_Delay(20);                                               //拉低总线至少 18ms
    HAL_GPIO_WritePin(DHT11_IO, DHT11_PIN, GPIO_PIN_SET);

    DHT_GPIO_INPUT();

    while(HAL_GPIO_ReadPin(DHT11_IO, DHT11_PIN));               //上一步将总线设为高电平,等待DHT11响应低电平
    while(!HAL_GPIO_ReadPin(DHT11_IO, DHT11_PIN));              //上一步DHT11响应低电平,等待DHT11拉高总线
    while(HAL_GPIO_ReadPin(DHT11_IO, DHT11_PIN));               //上一步DHT11拉高了总线,等待DHT11拉低总线,开始传送数据
}

4.6 读取1字节数据

将 DHT11 发来的二进制数据存储到 ReadData 变量中,读取一位后,左移一位,循环8次,最终得到 1 byte 数据。

那么如何判断我们读到的数据是 0 还是 1 呢?

通过 3.2.3 的分析可以知道,0 和 1 的时序只是高电平持续时间不同,所以我们只需要在 DHT11 拉低电平之后延时 40~60 微秒(代码中使用 50 微秒),再读取电平状态就可以了,如果是高电平则为 1,低电平则为 0 。

uint8_t DHT_Read_Byte(void)  //从DHT11读取一位(8字节)信号
{
    uint8_t i;
    uint8_t ReadData = 0;    //ReadData用于存放8bit数据,即8个单次读取的1bit数据的组合
    uint8_t temp;            //临时存放信号电平(0或1)

    for(i=0;i<8;i++){
        while(!HAL_GPIO_ReadPin(DHT11_IO, DHT11_PIN));
        Delay_us(50);
        if(HAL_GPIO_ReadPin(DHT11_IO, DHT11_PIN) == 1){
            temp = 1;
            while(HAL_GPIO_ReadPin(DHT11_IO, DHT11_PIN));
        }else{
            temp = 0;
        } 
        ReadData = ReadData << 1;
        ReadData |= temp;
    }
    return ReadData;
}

4.7 一次数据读取及显示

根据 3.2 的时序,我们就可以使用代码实现 DHT11 一次读取数据过程。

注意:DHT11 读取数据间隔至少为 2 秒,否则读取到的数据可能不稳定,所以在最后可以延时 2 秒。

void DHT_Read()
{
    uint8_t i;

    DHT11_Start();
    DHT_GPIO_INPUT();

    for(i= 0;i < 5;i++){
        Data[i] = DHT_Read_Byte();
    }
    if((Data[0]+Data[1]+Data[2]+Data[3])==Data[4])
    {
        printf("湿度: %d.%dRH ,", Data[0], Data[1]);
        printf("温度: %d.%d℃\r\n", Data[2], Data[3]);
    }else{
        printf("ERROR DATA\r\n");
    }
    HAL_Delay(2000);
}

dht11.h文件内容如下:

#ifndef __DHT11_H__
#define __DHT11_H__

#include "stdio.h"
#include "stm32f1xx.h"

#define DHT11_IO         GPIOA
#define DHT11_PIN        GPIO_PIN_8

void DHT_Read(void);

#endif

4.8 最终效果

5. 小结

通过本文的学习与实践,相信大家已经了解并掌握 DHT11 的特性和使用,能够更好地应用于嵌入式开发。无论是构建智能家居系统还是开发物联网设备,DHT11 都可以成为您的得力助手,让我们一起玩转 DHT11,love and peace!


另外,想进大厂的同学,一定要好好学算法,这是面试必备的。这里准备了一份 BAT 大佬总结的 LeetCode 刷题宝典,很多人靠它们进了大厂。

刷题 | LeetCode算法刷题神器,看完 BAT 随你挑!

有收获?希望老铁们来个三连击,给更多的人看到这篇文章

推荐阅读:

  • 程序员必备编程资料大全
  • 程序员必备软件资源

欢迎关注我的博客:良许嵌入式教程网,满满都是干货!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1300656.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mac电脑投屏AirServer 2024怎么下载安装激活许可期限

对于那些想要将 iPhone、iPad 或其他 iOS 设备上的小屏幕镜像到计算机上的大屏幕的人来说&#xff0c;AirPlay 是一个很好的工具。 基于此&#xff0c;AirServer 非常需要将您的 Mac 或 PC 变成 AirPlay 设备。 但是如何使用计算机上的设置对 iPhone 等 iOS 设备进行屏幕镜像&a…

nginx中Include使用

1.include介绍 自己的理解&#xff1a;如果学过C语言的话&#xff0c;感觉和C语言中的Include引入是一样的&#xff0c;引入的文件中可以写任何东西&#xff0c;比如server相关信息&#xff0c;相当于替换的作用&#xff0c;一般情况下server是写在nginx.conf配置文件中的&…

三. LiDAR和Camera融合的BEV感知算法-BEVFusion实战

目录 前言1. BEVFusion实战 前言 自动驾驶之心推出的《国内首个BVE感知全栈系列学习教程》&#xff0c;链接。记录下个人学习笔记&#xff0c;仅供自己参考 本次课程我们来学习下课程第三章——LiDAR和Camera融合的BEV感知算法&#xff0c;一起去学习下 BEVFusion 的相关代码 课…

理解MyBatis原理、思想

JDBC编码的缺点 结果集解析复杂&#xff0c;列名硬编码&#xff0c;sql变化导致解析代码变化&#xff0c;系统不易维护。Sql语句硬编码&#xff0c;难以维护。 数据库配置硬编码。频繁连接、释放数据库资源&#xff0c;降低系统性能。preparedStatement向占位符号传参数存在硬…

SpringBoot集成系列--xxlJob

文章目录 一、搭建调度中心xxl-job-admin1、下载项目2、调整项目参数3、执行初始化数据库SQL4、启动项目5、访问 二、集成步骤1、添加xxl-job的依赖2、添加xxl-job的依赖3、配置执行器4、创建执行器5、开发任务1&#xff09;方式1&#xff1a;BEAN模式&#xff08;方法形式&…

文心ERNIE Bot SDK+LangChain:基于文档、网页的个性化问答系统

现在各行各业纷纷选择接入大模型&#xff0c;其中最火且可行性最高的形式无异于智能文档问答助手&#xff0c;而LangChain是其中主流技术实现工具&#xff0c;能够轻松让大语言模型与外部数据相结合&#xff0c;从而构建智能问答系统。ERNIE Bot SDK已接入文心大模型4.0能力&am…

2023-12-10 LeetCode每日一题(爬楼梯)

2023-12-10每日一题 一、题目编号 70. 爬楼梯二、题目链接 点击跳转到题目位置 三、题目描述 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 示例 1&#xff1a; 示例 2&#xff1a; 提…

【vim】常用操作

用的时候看看&#xff0c;记太多也没用&#xff0c;下面都是最常用的&#xff0c;更多去查文档vim指令集。 以下均为正常模式下面操作&#xff0c;正在编辑的&#xff0c;先etc一下. 1/拷贝当前行 yy&#xff0c;5yy为拷贝包含当前行往下五行 2/p将拷贝的东西粘贴到当前行下…

(第一部分1-3 / 13)PMBOK 6

项目管理协会 PMI 价值观 责任、尊重、公正、诚实 法约尔 亨利法约尔_百度百科 管理的5项职能 计划组织指挥协调控制管理的14项原则&#xff08;该原则的提出&#xff0c;标志着法约尔管理理论的形成&#xff09; 【劳动分工】劳动分工是合理使用个人力量和集体力量的最好…

36 括号匹配问题

import java.util.HashMap; import java.util.LinkedList; import java.util.Scanner;public class Main {// 输入获取public static void main(String[] args) {Scanner sc new Scanner(System.in);String s sc.nextLine();System.out.println(getResult(s));}// 算法入口pu…

EdgeYOLO: anchor-free,边缘部署友好

简体中文 1 Intro 2 Updates 3 Coming Soon 4 Models 5 Quick Start \quad 5.1 setup

Cpolar配置外网访问和Dashy

Dashy是一个开源的自托管的导航页配置服务,具有易于使用的可视化编辑器、状态检查、小工具和主题等功能。你可以将自己常用的一些网站聚合起来放在一起,形成自己的导航页。一款功能超强大,颜值爆表的可定制专属导航页工具 结合cpolar内网工具,我们实现无需部署到公网服务器…

详解异常 ! !(对异常有一个全面的认识)

【本章目标】 1. 异常概念与体系结构 2. 异常的处理方式 3. 异常的处理流程 4. 自定义异常类 1. 异常的概念与体系结构 1.1 异常的概念 在生活中&#xff0c;一个人表情痛苦&#xff0c;出于关心&#xff0c;可能会问&#xff1a;你是不是生病了&#xff0c;需要我陪你去看医…

T曲线速度控制与S曲线速度控制

梯形速度控制曲线&#xff08;T曲线&#xff09; 所谓梯形速度曲线&#xff0c;也称为直线加减速或T型加减速。 其算法十分简易&#xff0c;规划周期耗时短&#xff0c;有利于缩减系统的连续运行时间&#xff0c;从而提高系统的运动控制速度&#xff0c;实施起来比较易&#x…

构建linux系统的强有力工具buildroot

目录 01. buildroot简介 1.1简介 1.2 源码下载 1.3 buildroot版本更新介绍 02. 实操演示 2.1 buildroot源码目录层级的简介 2.2 实操演示 03. 结语 01. buildroot简介 1.1简介 Buildroot是一个嵌入式Linux系统的工具链&#xff0c;它用于构建嵌入式设备的根文件系统。…

利用pycharm进行python代码的debug各功能解释

利用pycharm进行python代码的debug各功能解释 利用pycharm进行python代码的debug各功能解释 一 进入debug 1 左键点击代码文件目标行&#xff0c;确定debug节点&#xff08;可一次选择多个debug节点&#xff09; 2 鼠标右键&#xff0c;选择debug 二 各功能解读 debug调试…

第九天:信息打点-CDN绕过篇amp;漏洞回链amp;接口探针amp;全网扫描amp;反向邮件

信息打点-CDN绕过篇 cdn绕过文章&#xff1a;https://www.cnblogs.com/qiudabai/p/9763739.html 一、CDN-知识点 1、常见访问过程 1、没有CDN情况下传统访问&#xff1a;用户访问域名-解析服务器IP–>访问目标主机 2.普通CDN&#xff1a;用户访问域名–>CDN节点–>…

鸿蒙OS应用开发之语句

在程序开发中&#xff0c;已经有上面的运算符和数据类型了&#xff0c;可以满足了大部的需求&#xff0c;但是这些程序还是比较简单的计算和逻辑运算&#xff0c;如果需要复杂的计算和逻辑处理&#xff0c;就需要采用复杂逻辑程序块来处理了&#xff0c;也就是复杂条件语句才能…

Kubernetes里的DNS;API资源对象ingress;Kubernetes调度;节点选择器NodeSelector;节点亲和性NodeAffinity

Kubernetes里的DNS K8s集群内有一个DNS服务&#xff1a; kubectl get svc -n kube-system |grep dns测试&#xff1a; 在tang3上安装bind-utils,目的是安装dig命令 yum install -y bind-utils apt install dnsutils #ubuntu上 解析外网域名 dig 10.15.0.10 www.baidu.com…

C语言笔试例题_指针专练30题(附答案解析)

C语言笔试例题_指针专练30题(附答案解析) 指针一直是C语言的灵魂所在&#xff0c;是掌握C语言的必经之路&#xff0c;收集30道C语言指针题目分享给大家&#xff0c;测试环境位64位ubuntu18.04环境&#xff0c;如有错误&#xff0c;恳请指出&#xff0c;文明讨论&#xff01;&am…