STM32外设系列—DHT11

news2024/9/29 17:26:36

文章标题

  • 一、DHT11简介
  • 二、数据手册分析
    • 2.1 接口说明
    • 2.2 串行通信说明
      • 2.2.1 单总线通信
      • 2.2.2 单总线传输数据位定义
      • 2.2.3 时序图
  • 三、DHT11程序设计
    • 3.1 初始化GPIO
    • 3.2 发送起始信号
    • 3.3 接收一个字节数据
    • 3.4 接收温湿度信息并校准
  • 四、总结

一、DHT11简介

DHT11是一款常用的数字温湿度传感器。传感器包括一个电容式感湿元件和一个 NTC 测温元件,能够测量皱纹环境的温湿度,常用于暖通空调、除湿器、农业、冷链仓储等方面。
DHT11

二、数据手册分析

2.1 接口说明

DHT11接口说明

2.2 串行通信说明

DHT11通过串行通信的方式,将采集到的环境温湿度信息传递给单片机。数据手册中,针对DHT11的串行通信做了详细介绍。

2.2.1 单总线通信

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

2.2.2 单总线传输数据位定义

DHT11的DATA引脚,用于单片机与 DHT11 之间的通讯和同步,采用单总线数据格式,一次传送 40 位数据,高位先出。数据格式

8bit 湿度整数数据 + 8bit 湿度小数数据 + 8bit 温度整数数据 + 8bit 温度小数数据 + 8bit 校验位

数据手册中写明,湿度的小数部分为0。8bit 校验位等于所得结果的末 8 位。
单总线格式定义
对于校验位,数据手册中举例说明。比如接收到的40位数据为

0011 01010000 00000001 10000000 01000101 0001
湿度高8位湿度低8位温度高8位温度低8位校验位

计算 0011 0101 + 0000 0000 + 0001 1000 + 0000 0100 + 0101 0001 = 0101 0001,与接收到的校验位相等,校验通过。如果校验不通过,则将此次接收到的数据丢弃,重新接收数据。

2.2.3 时序图

根据上面的介绍,如果单片机想要读取数据,需要先发送一个起始信号。起始信号需要拉低数据线至少18ms。
起始信号

DHT11检测到起始信号之后,等待起始信号低电平结束,然后输出应答信号。应答信号是先将数据线拉低83us,再拉高87us。

应答信号

然后DHT11就开始输出数据了,“0”和“1”的时序图如下

“0”和“1”的时序图

总时序图如下

总时序图

三、DHT11程序设计

3.1 初始化GPIO

根据上面的介绍,STM32的GPIO既需要用作输出,也需要用作输入。因此,STM32的GPIO需要有两种配置

/*
 *==============================================================================
 *函数名称:Drv_Dht11_Gpio_OutInSet
 *函数功能:DHT11引脚输出/输入设置
 *输入参数:state:OUT:输出(0);IN:输入(1)
 *返回值:无
 *备  注:无
 *==============================================================================
 */
void Drv_Dht11_Gpio_OutInSet (u8 state)
{
	// 结构体定义
 	GPIO_InitTypeDef  GPIO_InitStructure;
	
	// 开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	// 初始化GPIO结构体
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
	if (state)
	{
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   // 浮空输入
	}
	else
	{
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   // 推挽式输出
	}
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_Init(GPIOA,&GPIO_InitStructure);
}

.h文件添加下面程序

// GPIO模式
#define OUT   0   // 输出模式
#define IN    1   // 输入模式

3.2 发送起始信号

单片机的 I/O 设置为输出同时输出低电平,且低电平保持时间不能小于 18ms(最大不得超过 30ms),然后单片机的 I/O 设置为输入状态,由于上拉电阻,单片机器的 I/O 即 DHT11 的 DATA 数据线也随之变高,等待 DHT11 作出回答信号。程序设计如下

/*
 *==============================================================================
 *函数名称:Drv_Dht11_Start
 *函数功能:向DHT11发送起始信号
 *输入参数:state:OUT:输出(0);IN:输入(1)
 *返回值:无
 *备  注:无
 *==============================================================================
 */
void Drv_Dht11_Start (void)
{
	OLED_SDA_Set();   // 拉高一小段时间
	delay_us(30);
	
	Drv_Dht11_Gpio_OutInSet(OUT);   // GPIO配置为输出模式
	OLED_SDA_Clr();   // 拉低数据线
	delay_ms(20);   // 保持20ms
	
	OLED_SDA_Set();   // 拉高一小段时间
	delay_us(30);
	
	Drv_Dht11_Gpio_OutInSet(IN);   // GPIO配置为输入模式
}

3.3 接收一个字节数据

/*
 *==============================================================================
 *函数名称:Med_Dht11_ReceOneByte
 *函数功能:接收一帧数据
 *输入参数:无
 *返回值:一字节接收数据
 *备  注:无
 *==============================================================================
 */
u8 Med_Dht11_ReceOneByte (void)
{
	u8 tempVar = 0;   // 临时循环变量
	u8 receData = 0;   // 接收数据
	
	for (tempVar = 0;tempVar < 8;tempVar ++)
	{
		while (!DHT11_SDA_DATA);   // 等待54us的低电平过去
		delay_us(30);   // 延时30us之后判断是0还是1
		
		// 如果30us之后依旧为高电平
		if (DHT11_SDA_DATA)
		{
			receData |= 1;   // 接收数据为1
		}
		while (DHT11_SDA_DATA);   // 等待高电平过去
		
		receData <<= 1;   // 左移
	}
	
	return receData;
}

3.4 接收温湿度信息并校准

/*
 *==============================================================================
 *函数名称:App_Dht11_Result_Process
 *函数功能:处理接收结果,得出正确的温湿度信息
 *输入参数:无
 *返回值:无
 *备  注:无
 *==============================================================================
 */
u8 receData[4];   // 存储温湿度结果
void App_Dht11_Result_Process (void)
{
	u8 receCheck = 0;   // 接收到的校验码
	u8 tempCal = 0;   // 临时计算变量
	
	Drv_Dht11_Start();   // 发送一个起始信号
	DHT11_SDA_Set();   // 拉高SDA
	
	// 等待应答信号
	if (!DHT11_SDA_DATA)
	{
		while (!DHT11_SDA_DATA);   // 等待83us低电平结束
		while (DHT11_SDA_DATA);   // 等待87us高电平结束
		
		// 开始接收数据
		receData[0] = Med_Dht11_ReceOneByte();   // 湿度整数
		receData[1] = Med_Dht11_ReceOneByte();   // 湿度小数
		receData[2] = Med_Dht11_ReceOneByte();   // 温度整数
		receData[3] = Med_Dht11_ReceOneByte();   // 温度小数
		receCheck = Med_Dht11_ReceOneByte();   // 校验码
		
		tempCal = receData[0] + receData[1] + receData[2] + receData[3];
		
		// 如果校验失败
		if (tempCal != receCheck)
		{
			// 清空接收
			receData[0] = receData[1] = receData[2] = receData[3] = 0;
		}
	}
}

四、总结

实际上面的程序设计有一些不足,比如某些地方不需要再拉高SDA线,在等到时使用了while语句但是没有超时检测。但是由于博主的DHT11坏了,目前买的新的还没到,无法继续调试,因此这里说明一下。后续会修改完善程序,补充应用实例。——2023年6月26日

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

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

相关文章

Qt生成安卓工程运行闪退分析

提示找不到库 jin目录下库是存在的 提示下列库没有找到 libopencv_java4.so libtiff.so libboost_filesystem.so.1.71.0 libboost_chrono.so.1.71.0 libboost_regex.so.1.71.0 导致无法加载符号 最终导致应用无法启动&#xff0c;而退出 重新编译为静态库,并以静态库方式链…

技术管理第三板斧招聘与解聘-升级汰换

1.开除人“心要慈&#xff0c;刀要快” No Surprise&#xff1a; 不要突然Fire一个人&#xff08;离职一定不是一个突发行为&#xff09;&#xff0c;没有任何征兆告诉员工 A“你被开除了”&#xff0c;这是典型的管理失职。如果A存在问题&#xff0c;你应该先告知&#xff0…

数据结构--顺序表的基本操作--插入 and 删除

数据结构–顺序表的基本操作–插入 顺序表的插入操作 实现目标 ListInsert(&L,i,e):插入操作。在表L中的第i个位置上插入指定元素e。 typedef struct {int data[MaxSize];int len; }Sqlist;代码实现&#xff1a; #include <stdio.h> #include <stdlib.h> …

前端JavaScript入门-day03

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 1、循环-for 1. for 循环-基本使用 1. for循环语法 2. 退出循环 2. for 循环嵌套 2、数组 1 数组是…

易点易动设备管理平台:为制药厂提升设备管理效率保驾护航

在高度竞争的制药行业中&#xff0c;设备管理对企业的生产效率和产品质量起着至关重要的作用。如何在保证设备安全、高效运行的同时&#xff0c;降低成本和提高设备利用率呢&#xff1f;易点易动设备管理平台为您提供了完美的解决方案。本文将详细阐述易点易动设备管理平台如何…

Linux搭建sqli-labs(sql注入实战)

目录 一、安装phpstudy 二、更改配置文件 三、加载数据库 一、安装phpstudy 需要php、mysql、httpd环境&#xff0c;phpstudy可以做到快速部署。 cd /opt yum install -y wget wget -O install.sh https://notdocker.xp.cn/install.sh && sudo bash install.sh wget…

Podman安装nacos使用(默认最新版)

一,命令熟悉 --name : 命名容器的名称. -d:表示在后台运行容器. -p:指定端口映射。如: 左边的8848是宿主机的端口,右边的8848是nacos容器内部的端口。 docker.io/nacos/nacos-server:表示根据docker.io/nacos/nacos-server镜像运行容器。 --restart=always 表示启…

【MySQL】看完这篇不信你学不会如何使用数据处理函数

&#x1f3ac; 博客主页&#xff1a;博主链接 &#x1f3a5; 本文由 M malloc 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f384; 学习专栏推荐&#xff1a;LeetCode刷题集&#xff01; &#x1f3c5; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指…

JDK的生成keytool证书

JDK的生成keytool证书 首先安装jdk环境 地址: https://www.oracle.com/downloads/ 点击页面下方的java 选择Java (JDK) for Developers 选择你的环境安装包&#xff0c;我的电脑是windows64位&#xff0c;选择x64 MSI Installer 下载完成后安装 进入jdk根路径执行命令 keytoo…

PaddleOCR #使用PaddleOCR进行光学字符识别 - OCR模型对比

PaddleOCR 在其工具包中提供了多种模型&#xff0c;并且非常易于应用。根据准确性和速度比较模型始终是一个好习惯。在本节中&#xff0c;我们将比较 PaddleOCR 提供的四种模型&#xff0c;即 SRN、PP-OCRv2、PP-OCRv3 和 NRTR。比较将在 COCO-text 数据集上进行&#xff0c;该…

【每日编程Day30】最难的问题 因子个数

目录 一、选择题 二、编程题 1、最难的问题 2、因子个数 一、选择题 &#xff08;1&#xff09;当包装类与基本数据类型比较&#xff0c;包装类会自动茶香变为基本数据类型再比较&#xff1b; &#xff08;2&#xff09;包装数据类直接赋值&#xff0c;默认调用其对用的val…

项目经理提高影响力的6大原则

在很多临时组建的项目团队中&#xff0c;项目经理往往处于权、责、利不匹配的尴尬状态&#xff0c;即有责无权。项目经理既需要对项目目标的实现负责&#xff0c;又没有相匹配的权利。 在这种情况下&#xff0c;项目经理不能通过权利进行团队管理&#xff0c;只能通过个人影响力…

cmd 108个常用命令,看看你知道多少

背景 一、CMD是什么 在不同的操作系统环境下&#xff0c;命令提示符各不相同&#xff0c;在Windows环境下&#xff0c;命令行程序为cmd.exe&#xff0c;是一个32 位的命令行程序。 cmd是指命令提示符&#xff0c;是在操作系统中&#xff0c;提示进行命令输入的一种工作提示符…

SpringBoot处理实际开发中常见的七种全局异常详解(全面详细+Gitee源码)

前言&#xff1a;在日常的开发工作中&#xff0c;项目在运行过程中多多少少是避免不了报错的&#xff0c;对于报错信息肯定不可以把全部信息都抛给客户端去显示&#xff0c;这里就需要我们对常见的七种异常情况统一进行处理&#xff0c;让整个项目更加优雅。 目录 一、基本介绍…

别迷茫!电子与通信相关专业,详细就业方向!

一、通信领域 1、算法工程师 算法工程师对我们来说&#xff0c;有两种可选择的方向&#xff0c;一种是通信算法工程师&#xff0c;一种是信号处理算法工程师。 通信算法工程师&#xff1a;需要对通信目标、干扰、杂波和信道模拟进行算法研究与数学仿真。了解4G和5G的相关技术。…

【Logback技术专题】「入门到精通系列教程」深入探索Logback日志框架的原理分析和开发实战技术指南(中篇)

深入探索Logback日志框架的原理分析和开发实战技术指南&#xff08;下篇&#xff09; Logback日志框架slf4j和logback的关系slf4jSlf4j的核心代码getLogger方法LoggerFactory的bind()方法 slf4j logback配置 log4j和logback的关系Logback的配置文件配置文件读取顺序 Logback配置…

告别StringUtil:使用Java 全新String API优化你的代码

前言 Java 编程语言的每一次重要更新&#xff0c;都引入了许多新功能和改进。 并且在String 类中引入了一些新的方法&#xff0c;能够更好地满足开发的需求&#xff0c;提高编程效率。 repeat(int count)&#xff1a;返回一个新的字符串&#xff0c;该字符串是由原字符串重复指…

MySQL数据库基础 16

第十六章 变量、流程控制与游标 1. 变量1.1 系统变量1.1.1 系统变量分类1.1.2 查看系统变量 1.2 用户变量1.2.1 用户变量分类1.2.2 会话用户变量1.2.3 局部变量1.2.4 对比会话用户变量与局部变量 2. 定义条件与处理程序2.1 案例分析2.2 定义条件2.3 定义处理程序2.4 案例解决 3…

灵魂组件Lifecycle的生命周期机制详解

作者&#xff1a;苏火火 前言 在早期 Andorid 架构中&#xff0c;生命周期的事件监听和状态查询&#xff0c;我们需要自定义一套提供侦测功能的 Activity/Fragment 基类及回调接口&#xff0c;在 Activity/Fragment 的生命周期方法中实现依赖组件的操作&#xff0c;在外部进行…

【并发编程】多线程安全问题,如何避免死锁

文章目录 概念进程线程对比 代码使用进程线程 线程创建方式线程的生命周期和状态停止线程方法介绍sleep() / wait()为什么 wait() 不被定义在 Thread 中&#xff1f;sleep() 定义在 Thread 中&#xff1f;run()/start() 为什么使用多线程&#xff1f;线程安全问题线程死锁如何避…