一篇文章教会你DHT11读取温湿度,附STM32代码示例

目录

一、DHT11说明:

1.典型电路:

2.串行通信说明(单线双向):

单总线说明:

单总线传送数据位定义:

校验位数据定义: 

二、DHT11读取时为啥要切换模式:

1. 通信时序要求

2. 信号检测的灵敏度

3. 浮动输入模式的优势

4. 避免冲突

5. 功耗考虑

6.结论

7.切换模式代码:

 ​三、发送开始准备读取信号:

步骤一:

步骤二:

四、接收DHT11应答信号:

五、接收DHT11发送的数据一位:

读取方法:

六,接收DHT11发送的数据字节:

接收到的40位数据为:

计算:

特殊说明:

示例:

完整时序图:

七、示例代码及结果:


一、DHT11说明:

1.典型电路:

 

  • 在使用DHT11传感器时,其DATA数据线通过一个上拉电阻与微处理器的I/O端口相连,这是为了在数据线空闲时保持一个稳定的高电平状态。对于短距离通信(线长小于5米),通常推荐使用4.7kΩ的上拉电阻。如果通信距离较长(超过5米),可能需要根据实际情况选择一个更小的电阻值,以确保数据线上的信号能够稳定地到达微处理器。

  • 当DHT11使用3.3V电压供电时,推荐保持数据线尽可能短,因为长距离的接线可能会因为线路损耗而导致传感器供电不足,进而影响测量结果的准确性。此外,如果电源部分存在波动,这也可能会影响温度的测量值。特别是当使用开关电源时,电源的不稳定可能会导致温度读数出现跳动。

  • DHT11传感器的一个特性是,它每次读出的温湿度数值实际上是上一次测量的结果。为了获得实时数据,需要连续读取两次,第二次读取的结果通常更接近当前的实时值。但是,不建议连续多次读取传感器,因为这样可能会影响传感器的性能和数据的准确性。每次读取之间应至少间隔2秒钟,这样可以给传感器足够的时间来准备下一次测量,从而获得更准确的数据。

2.串行通信说明(单线双向):

单总线说明:
  • DHT11是一种常用的单总线数字温湿度传感器,它通过一条数据线与微控制器通信。这种单总线的设计意味着所有的数据交换和控制都通过这一根线完成。在这种通信协议中,设备通过一个漏极开路或三态端口连接到数据线,这样当设备不发送数据时,它能够释放总线,允许其他设备使用总线。为了确保在没有数据传输时总线为高电平状态,单总线通常需要外接一个约4.7kΩ的上拉电阻。

  • 由于DHT11采用主从结构,只有主机(微控制器)发起请求时,从机(DHT11)才会响应。因此,主机访问DHT11时必须严格遵守单总线通信序列。如果通信序列出现混乱,DHT11将不会响应主机的请求。

单总线传送数据位定义:
  • DATA用于微处理器与DHT11之间的通讯和同步,采用单总线数据格式,一次传送40位数据, 高位先出。

  • 数据格式: 8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据+8bit校验位。

  • 其中湿度小数部分为0。

校验位数据定义: 

“8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据”=8bit校验位。

二、DHT11读取时为啥要切换模式:

使用推挽输出模式来读取电平变化在某些情况下是可行的,但可能会遇到一些问题,特别是在与DHT11这类传感器通信时。以下是一些关键点,解释了为什么在与DHT11通信时,仅使用推挽输出模式可能不够:

1. 通信时序要求

DHT11通信协议对时序有严格的要求。它依赖于精确的高电平和低电平持续时间来传输数据。在推挽输出模式下,GPIO引脚可以驱动电流,但在读取数据时,需要引脚处于浮动状态以准确检测由传感器拉高或拉低的电平变化。

2. 信号检测的灵敏度

在推挽输出模式下,GPIO引脚会尽力保持其状态(高或低),直到程序改变它。这意味着,如果引脚被配置为输出高电平,它可能无法准确检测到微弱的低电平信号,尤其是当这些信号由外部设备(如DHT11)生成时。

3. 浮动输入模式的优势

将GPIO配置为浮动输入模式(GPIO_Mode_IN_FLOATING)时,引脚会处于高阻抗状态,这意味着它不会尝试驱动信号,而是允许外部信号驱动它。这使得微控制器能够更准确地读取由外部设备设置的电平状态,无论是高还是低。

4. 避免冲突

如果GPIO被配置为推挽输出,并且尝试读取数据,而此时外部设备(如DHT11)也在尝试通过同一引脚驱动信号,可能会导致冲突。这种冲突可能导致不稳定的读数或通信失败。

5. 功耗考虑

在某些低功耗应用中,可能希望在不活跃时减少GPIO引脚的功耗。在输出模式下,GPIO引脚会持续消耗电流以维持其电平状态,而在浮动输入模式下,引脚在不活跃时消耗的电流要少得多。

6.结论

虽然在理论上可以使用推挽输出模式来读取电平变化,但在实践中,特别是在需要精确时序和敏感信号检测的应用(如DHT11通信)中,推荐使用浮动输入模式。这样可以确保微控制器能够准确地检测到由外部设备生成的信号,避免通信错误和提高系统的可靠性。

7.切换模式代码:
 void DHT11_Mode(uint8_t mode) {GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = DHT11_PIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;if (mode) {GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   //推挽输出} else {GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入//数据线会被上拉电阻拉高,主机通过检测数据线的电平变化来读取DHT11发送的数据。}GPIO_Init(DHT11_PORT, &GPIO_InitStructure);}

 ​三、发送开始准备读取信号:

步骤一:

DHT11上电后(DHT11上电后要等待1s以越过不稳定状态在此期间不能发送任何指令),测试环境温湿度数据,并记录数据,同时DHT11的DATA数据线由上拉电阻拉高一直保持高电平; 此时DHT11的DATA引脚处于输入状态,时刻检测外部信号。

 //初始化PA5引脚void DHT11_Init(void) {RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);DHT11_Mode(1);                       // 推挽输出GPIO_SetBits(DHT11_PORT, DHT11_PIN); // 将PA5设置为高电平}
步骤二:

微处理器的I/O设置为输出同时输出低电平,且低电平保持时间不能小于18ms(最大不得 超过30ms),然后微处理器的I/O设置为输入状态,由于上拉电阻,微处理器的I/O即DHT11的 DATA数据线也随之变高,等待DHT11作出回答信号。发送信号如图所示:

 void DHT11_Start(void) {DHT11_Mode(1);  //推挽输出GPIO_ResetBits(DHT11_PORT, DHT11_PIN);Delay_ms(20);  // 保持20ms起始信号GPIO_SetBits(DHT11_PORT, DHT11_PIN);Delay_us(60);  // 拉高等待电平被拉低(确保延时完之前,电平被拉低)}

四、接收DHT11应答信号:

DHT11的DATA引脚检测到外部信号有低电平时,等待外部信号低电平结束,延迟后DHT11的 DATA引脚处于输出状态,输出80微秒的低电平作为应答信号,紧接着输出80微秒的高电平通知外设准备接收数据,微处理器的I/O此时处于输入状态,检测到I/O有低电平(DHT11回应信号)后,等待80微秒的高电平后的数据接收,发送信号如图所示:

 uint8_t DHT11_Reply(void) {DHT11_Start();    //发送准备读取信号uint8_t timeout = 100;DHT11_Mode(0);    //切换模式为浮空输入,接收电平变化// 等待低电平结束,DHT11首先输出80微秒的低电平作为应答信号while (!GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) && timeout > 0) {timeout--;Delay_us(1);}if (timeout == 0) return 1;  // 超时//等待高电平结束,低电平之后输出80微秒的高电平通知 外设准备接收数据timeout = 100;//重置timeoutDHT11while (GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) && timeout > 0) {timeout--;Delay_us(1);        }return (timeout > 0) ? 0 : 1;  // 返回0表示成功,1表示失败}

五、接收DHT11发送的数据一位:

在DHT11发送应答信号结束之后,由DHT11的DATA引脚输出40位数据,微处理器根据I/O电平的变化接收40位数据,位数据 “0”的格式为:50微秒的低电平和26-28微秒的高电平,位数据“1”的格式为:50微秒的低 电平加70微秒的高电平。位数据“0”、“1”格式信号如图所示:

 

读取方法:

可以等待发送位数据“0”的低电平之后的高电平结束之后读取引脚电平,由于位数据“1”的高电平时长比位数据“0”长,如果读取到的为1,则输出的信号为位数据“1”,否则为零。

uint8_t DHT11_ReadBit(void) {//DHT11_Reply();          //可用于调试int8_t timeout = 100;// 等待低电平结束,50微秒的低电平while (!GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) && timeout > 0) {timeout--;Delay_us(1);}Delay_us(50); //等待超过位数据0值的高电平时间,26-28微秒的高电平timeout = -5;//检测高电平持续时间,直到高电平结束,或超时timeout>=100while (GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) && timeout <100) {timeout++;Delay_us(1);}return (timeout > 0) ? 1 : 0;}

六,接收DHT11发送的数据字节:

DHT11传感器通过单总线传输数据,每次通信传输40位,包括湿度的整数部分、湿度的小数部分、温度的整数部分、温度的小数部分以及校验和。每个位的持续时间不同,表示0和1的高低电平持续时间不同,因此需要逐个位地读取并解析。

接收到的40位数据为:

0011 0101(湿度高8位)0000 0000 (湿度低8位)0001 1000(温度高8位 )0000 0100(温度低8位)    0101 0001( 校验位)                                           

校验位=湿度高位+湿度低位+温度高位+温度低位

计算:

00110101+00000000+00011000+00000100=01010001

接收数据正确:

湿度:00110101(整数)=35H=53%RH00000000=00H=0.0%RH=>53%RH+0.0%RH=53.0%RH

温度:00011000(整数)=18H=24℃00000100=04H=0.4℃=>24℃+0.4℃=24.4℃

特殊说明:

当温度低于0℃时温度数据的低8位的最高位置为1。

示例:

-10.1℃表示为0000101010000001

温度:00001010(整数)=0AH=10℃,00000001(小数)=01H=0.1℃

完整时序图:

 //读取一个字节uint8_t DHT11_ReadByte(void) {uint8_t byte = 0;  // 初始化一个变量来存储最终的字节数据,初值为0​for (int i = 0; i < 8; i++) { // 循环8次,因为1个字节等于8个位(bit)byte <<= 1; // 将byte变量的当前值左移1位,为新的位数据腾出位置(相当于乘以2)byte |= DHT11_ReadBit(); // 读取一个位的数据,使用逻辑或操作(|=)更新byte变量的最低位}return byte; // 返回组合好的字节数据}
 //温度湿度数据读取float DHT11_Read_Temperature_Humidity(uint8_t *temp_H, uint8_t *temp_L, uint8_t *humi_H, uint8_t *humi_L) {uint8_t buf[5]; // 定义一个数组来存储从DHT11读取的5个字节的数据uint8_t i; // 循环计数器​if (DHT11_Reply() != 0) { // 检测DHT11的应答信号return -1;  // 如果应答失败,返回-1}​for (i = 0; i < 5; i++) {  // 循环读取5次,因为DHT11每次传输40位数据,即5个字节buf[i] = DHT11_ReadByte(); // 调用DHT11_ReadByte函数读取单个字节数据,并存储到buf数组中}​// 检查数据的校验和是否正确if ((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4]) {*humi_H = buf[0]; // 将湿度的高位部分存储到指向的变量中*humi_L = buf[1]; // 将湿度的低位部分存储到指向的变量中*temp_H = buf[2]; // 将温度的高位部分存储到指向的变量中*temp_L = buf[3]; // 将温度的低位部分存储到指向的变量中return 0;  // 如果校验和正确,返回0表示成功读取数据} else {return -2;  // 如果校验和不正确,返回-2表示校验失败}}

七、示例代码及结果:

通过网盘分享的文件:16-DHT11温湿度模块读取
链接: https://pan.baidu.com/s/10ZGZvjZaA7SQtP8yX2gGpQ?pwd=1gbr 提取码: 1gbr

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

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

相关文章

【Linux】进程第三弹(虚拟地址空间)

目录 现象 底层原因 数据不发生修改 数据修改 小总结 地址空间本质 为什么要有地址空间 现象 来看代码&#xff1a; #include <stdio.h> #include <unistd.h> #include <sys/types.h>int val 50;int main() {printf("father process is running…

【springboot】简易模块化开发项目整合Redis

接上一项目&#xff0c;继续拓展项目 1.整合Redis 添加Redis依赖至fast-demo-config模块的pom.xml文件中 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependenc…

九、3 串口发送+printf函数移植+打印汉字

1、接线图 TX与RX交叉连接&#xff0c;TXD接STM32的PA10&#xff0c;RXD接STM32的PA9 VCC与3.3V用跳线帽连接 2、函数介绍 3、代码部分 &#xff08;1&#xff09;发送字节的函数&#xff08;Byte&#xff09; 可直接发送十六进制数 如0x41&#xff0c;也可直接发送字符 如A …

关于函数模板的一些不为人知的用法

欢迎来到 破晓的历程的 博客 ⛺️不负时光&#xff0c;不负己✈️ 引言 关于函数模板&#xff0c;大家都不陌生。但是如下的函数模板&#xff0c;大家肯定没有见过 没有提供任何特例化的模板 不管我们传入的是什么类型的参数&#xff0c;都可以匹配到这个模板【所以又被称为…

基于Springboot+Vue的在线问诊系统的设计与实现(含源码数据库)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 系统中…

动手学大模型应用开发之大模型简介

动手学大模型应用开发之大模型简介 主要学习目标什么是大语言模型大模型的能力和特点涌现能力作为基座模型支持多元应用的能力支持对话作为统一入口的能力大模型特点 常见大模型ChatGpt通义千问 LangChainLangChain的核心模块 总结相关学习链接 主要学习目标 学习如何进行大模…

Alignment与Correspondence,用于量化衡量MLLM中视觉特征的视觉语义对齐与视觉结构程度的方法

Alignment与Correspondence&#xff0c;用于量化衡量MLLM中视觉特征的视觉语义对齐与视觉结构程度的方法 FesianXu 20241006 at Wechat Search Team 前言 在多模态大模型&#xff08;Multimodal Large Language Model&#xff0c; MLLM&#xff09;中&#xff0c;视觉特征就像…

ai智能论文生成系统有用吗?分享5款ai文献综述自动生成器

近年来&#xff0c;人工智能&#xff08;AI&#xff09;技术在学术写作领域的应用越来越广泛&#xff0c;尤其是在文献综述的自动生成方面。AI智能论文生成系统通过深度学习和自然语言处理技术&#xff0c;能够帮助研究人员快速生成高质量的文献综述&#xff0c;从而提高写作效…

安可数据库产品目录

‌国家安可数据库产品目录包括以下主要产品‌&#xff1a; ‌华为GaussDB、openguass&#xff1a; 由华为云计算技术有限公司提供。‌金仓数据库管理系统&#xff1a;由中电科金仓&#xff08;北京&#xff09;科技股份有限公司提供。‌神通数据库管理系统&#xff1a;由天津神…

【Python】Python知识总结浅析

Python是一种高级编程语言&#xff0c;由Guido van Rossum于1991年首次发布。它以简洁的语法和强大的功能著称&#xff0c;适用于多种应用场景&#xff0c;包括Web开发、数据分析、人工智能、自动化脚本等。 易于学习和使用&#xff1a;Python的语法简洁明了&#xff0c;适合初…

AEye激光雷达公司的战略调整与成本控制分析

AEye激光雷达公司的战略调整与成本控制分析 当地时间9月3日,美国激光雷达领域的知名上市公司AEye在其向美国证券交易委员会(SEC)提交的8-K报告中披露了一项重大战略调整措施。报告指出,作为公司全面成本控制计划的一部分,AEye已对员工总数进行了大幅缩减,减少比例约达三分…

容器领航者:Kubernetes集群部署秘籍

目录 前言 一、ubernetes简介 1.1 应用部署方式演变 1.2 容器编排应用 1.3 kubenetes简介 二、Kubernetes核心概念 2.1 K8S各个组件用途 2.2 K8S 各组件之间的调用关系 2.3 K8S 的常用名词感念 2.4 k8S的分层架构​编辑 三、部署前的准备 3.1 k8s中容器的管理方式 3…

Java体系中的异常

1. 异常 1.1 异常的概念 在Java中&#xff0c;我们将程序执行过程中发生的不正常行为称为异常。异常是在程序运行过程中发生的错误或意外情况&#xff0c;它打破了程序的正常执行流程。在Java中通过面向对象的编程思想&#xff0c;我们也将这些扰乱程序正常执行的行为用类组织…

LeetCode Hot100 | Day1 | 二叉树:二叉树的直径

LeetCode Hot100 | Day1 | 二叉树&#xff1a;二叉树的直径 主要学习内容&#xff1a; 二叉树深度求法 深度的 leftright1 得到的是从根结点到叶子结点的节点数量 543.二叉树的直径 [543. 二叉树的直径 - 力扣&#xff08;LeetCode&#xff09;](https://leetcode.cn/prob…

【韩顺平Java笔记】第8章:面向对象编程(中级部分)【262-271】

262. 回顾上一章内容 看视频 263. IDEA介绍 263.1 IDEA 介绍 IDEA 全称 IntelliJ IDEA在业界被公认为最好的 Java 开发工具IDEA 是 JetBrains 公司的产品&#xff0c;总部位于捷克的首都布拉格除了支持 Java 开发&#xff0c;还支持 HTML&#xff0c;CSS&#xff0c;PHP&am…

Qt之TCP收发图片的例子

一.效果 二.实现 1.发图片 void MainWindow::slotSendImage() {matrix.rotate(90);QPixmap tempPixmap = pixmap.transformed(matrix);QBuffer buffer;tempPixmap.save(&buffer,"jpg");ui->labelImage->setPixmap(tempPixmap);int dataLength = buffer.d…

[图形学]在半球面上均匀采样和cos加权采样

一、简介 本文介绍了如何在半球表面上进行半球面均匀采样、半球面cos加权采样采样。 给出了相关公式推导和python代码实现。 二、在半球上采样 0.预备知识 1).球面坐标系与笛卡尔坐标系 在半球面上采样时&#xff0c;常使用球面坐标系。先采样球面坐标系下的坐标参数 ( θ…

python sqlite3 工具函数

起因&#xff0c; 目的: sqlite3 最常用的函数。 比如&#xff0c;某人给了一个 database.db 文件。 但是你登录的时候&#xff0c;不知道账号密码。 此文件就是&#xff0c;查看这个数据库的详细内容。 有哪些表某个表的全部内容。添加数据 代码&#xff0c; 见注释 impor…

《数字图像处理基础》学习01-数字图像处理的相关基础知识

这篇文章只是对数字图像处理的相关基础知识有个大概的了解&#xff0c;之后的文章会接着补充和扩展。 目录 一&#xff0c;图像的基本概念 1&#xff0c;图像 2&#xff0c;图像的分类 1&#xff09;物理图像 2&#xff09;虚拟图像 二&#xff0c;数字图像处理 三&…

PostGIS--介绍

目录 1、什么是PostGIS&#xff1f;2、数据2.1 对象2.1.1 读取几何元数据信息函数2.1.2 处理点的函数2.1.3 处理线的函数2.1.4 处理面的函数2.1.5 集合 2.2 集合输入和输出2.3 shapefile文件 总结PS: 1、什么是PostGIS&#xff1f; PostGIS通过增加对空间类型、空间索引和空间…