尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
STM32学习笔记【38.DHT11实验】
文章目录模块介绍DHT11温湿度传感器1. DHT11介绍1.1 DHT11型号介绍1.2 DHT11工作参数及引脚介绍2. DHT11工作原理2.1 正常工作验证2.2 DHT11工作时序【与I2C类似】2.2.1 DHT11整体工作时序2.2.2 DHT11起始【复位】及响应信号2.2.3 读时序2.3 DHT11数据格式3. DHT11编程实战1. 搭建框架2. 填写输入输出口函数内容3. 起始信号4. 读取一个字节和所有数据的函数5. 主函数6. 代码展示7. 实验结果模块介绍DHT11温湿度传感器生活中经常使用温湿度数据比如天气预报、智能家居、智能大屏等等。这些数据可以通过温湿度传感器进行获取。在嵌入式开发中温湿度传感器是一种十分常用的传感器。1. DHT11介绍DHT11数字温湿度传感器为3或4针单排引脚封装连接方便。具有品质卓越、超快响应、抗干扰能力强、性价比高、超小体积、极低功耗的优点使其称为在测温、测湿应用在苛刻应用场合的不错选择。DHT11内置一个电阻式感湿元件和一个NTC测温元件并与一个单片机相连接DHT11内部。每个DHT11都在极为精确的湿度校验室中进行校准校准系数以程序的形式存在传感器中传感器内部在检测信号的处理过程中要调用这些校准系数。DHT11采用简易快捷的单线制串行接收方便系统集成。1.1 DHT11型号介绍DHT11有3脚和4脚两款在使用上没有差别接线都一样主要接三根四脚的款式有一脚悬空。四脚款接杜邦线会有点不稳只能插面包板上建议直接买三脚的。同样可以测量温湿度的还有DHT20、DHT22等都是大同小异。DHT11虽然可以同时测量温湿度但是测量范围没有专业测温传感器范围大。比如DS18B20专业测量温度的温度范围是-55℃~-125℃而DHT11只有0 ~ 50 ℃。1.2 DHT11工作参数及引脚介绍DHT11工作参数湿度测量范围20 ~ 90%RH湿度测量精度±5%RH温度测量范围0 ~ 50℃温度测量精度±2℃工作电压 DC 3.3V/5V接线如下正负极如果接反会烧坏传感器DHT11STM32VCC3.3V/5VDATA任意一个GPIO口GNDGNDDHT11采用单总线协议也就是使用一根DATA线进行数据的收发。DHT11的DATA线一次通讯时间4ms左右数据分整数部分、小数部分和校验位具体为8bit湿度整数数据 8bit温度小数数据 8bit校验位。2. DHT11工作原理2.1 正常工作验证上电后【电源指示灯/POWER】红灯亮表示上电成功正常工作。2.2 DHT11工作时序【与I2C类似】2.2.1 DHT11整体工作时序DHT11整体工作时序为主机发送开始信号、DHT11响应输出、主机输出40bit数据湿度数据温度数据校验值结束信号可选。具体过程如下总线空闲状态为高电平主机拉低总线等待DHT11响应主机把总线拉低必须大于18ms保证DHT11能检测到起始信号主机发送开始信号结束后拉高总线电平并延时等待20 ~ 40us后读取DHT11的响应信号DHT11接收到主机的开始信号后等待微处理器开始信号结束发送80us低电平响应信号DHT11发送80us高电平准备发送数据DHT11发送40bit数据湿度数据温度数据校验值2.2.2 DHT11起始【复位】及响应信号首先主机拉低总线至少18ms然后再拉高总线延时20 ~ 40us此时起始信号有时也叫复位信号发送完毕。DHT11检测到复位信号触发一次采样并拉低总线80us表示响应信号告诉主机数据已经准备好了。DHT11之后拉高总线80us然后开始传输数据。如果检测到响应信号为高电平则DHT11初始化失败请检查线路是否连接正常。2.2.3 读时序DHT11开始传输数据。每1 bit数据都以50us低电平开始告诉主机开始传输一位数据了。DHT11以高电平的长短定义数据位是0还是1当50us低电平过后拉高总线高电平持续26 ~ 28us表示0高电平持续70us表示数据1。当最后1 bit数据传送完毕后DHT11拉低总线50us表示数据传输完毕随后总线由上拉电阻拉高进入空闲状态。位数据0表示方式以50us低电平开始高电平持续26 ~ 28 us表示0。位数据1表示方式以50us低电平开始高电平程序70us表示1。50us时是低电平图中画的不太准。2.3 DHT11数据格式DHT11的DATA传输一次完整的数据为40bit按照高位在前低位在后的顺序传输。数据格式为8bit湿度整数数据 8bit湿度小数数据 8bit温度整数数据 8bit温度小数数据 8bit校验位一共5字节40bit数据。校验位 前面几个bit数据加起来放到校验位。正常情况下前四个字节的和刚好与校验位相等通过这种机制可以保证数据传输的准确性。判断如果前面几个bit数据加起来等于校验位说明数据传输正确。3. DHT11编程实战1. 搭建框架在串口打印功能实验基础上做在BSP文件夹下建立dht11文件夹以及.c和.h文件将dht11文件加载进来以及头文件加载。DHT11无初始化函数因为DHT11只有一个IO口既要作为输入口也要作为输出口dht11.c// 配置输入口voiddht11_gpio_input(void){}// 配置输出口voiddht11_gpio_output(void){}// 时序起始信号voiddht11_start(void){}// 读数据, 读一个字节uint8_tdht11_read_byte(void){}// 触发一次转换读取所有数据voiddht11_read(uint8_t*result){}dht11.h#defineDHT11_PORTGPIOA#defineDHT11_PINGPIO_PIN_5#defineDHT11_CLK_ENABLE()__HAL_RCC_GPIOA_CLK_ENABLE()#defineDHT11_DQ_OUT(x)do{x?\HAL_GPIO_WritePin(DHT11_PORT,DHT11_PIN,GPIO_PIN_SET):\HAL_GPIO_WritePin(DHT11_PORT,DHT11_PIN,GPIO_PIN_RESET);\}while(0)#defineDHT11_DQ_INHAL_GPIO_ReadPin(DHT11_PORT,DHT11_PIN)2. 填写输入输出口函数内容// 配置输入口voiddht11_gpio_input(void){// 打开时钟DHT11_CLK_ENABLE();引脚FHT11_PIN 模式是输入 无上拉或下拉 高速HAL_GPIO_Init(DHT11_PORT,gpio_initstruct);}// 配置输出口voiddht11_gpio_output(void){// 打开时钟DHT11_CLK_ENABLE();引脚DHT11_PIN 模式是推挽输出 无上拉或下拉 高速HAL_GPIO_Init(DHT11_PORT,gpio_initstruct);}3. 起始信号voiddht11_start(void){dht11_gpio_output();//引脚为输出模式DHT11_DQ_OUT(1/0);//表示高低电平先是高电平 拉低delay_ms(20);// 拉低至少18ms拉高但不用管20~40us// 主机拉高等待从机主动权交给从机dht11_gpio_input();// 输入模式// 等待dht11总线拉低电平while(DHT11_DQ_IN);// 等待DHT11拉高电平while(!DHT11_DQ_IN);// 等待dht11总线拉低电平while(DHT11_DQ_IN);}4. 读取一个字节和所有数据的函数逻辑上数据0从高电平拉低50us再拉高26 ~ 28 us数据1从高电平拉低50us再拉高70 us等待上升沿之后再等待50us判断是数据0还是150us是高电平表示数据1如果是低电平表示数据0chardht11_data[5]{0};uint8_tdht11_read_byte(void){uint8_ttemp0;uint8_ti0;// 定义一个数据将8位保存起来uint8_tread_data0;for(i0;i8;i){// 一个字节是8位读8次while(!DHT11_DQ_IN);delay_us(50);if(DHT11_DQ_IN1){temp1;while(DHT11_DQ_IN);}elsetemp0;// 先移位再把读到的数据插进去read_dataread_data1;read_data|temp;}returnread_data;}voiddht11_read(uint8_t*result){uint8_ti0;// 1.起始响应信号dht11_start();// 2.读数据输入模式// 3. 循环读入5个数据,40bit数据for(i0;i5;i)dht11_data[i]dht11_read_byte();// 校验读出数据是否准确if(dht11_data[0]dht11_data[1]dht11_data[2]dht11_data[3]dht11_data[4]){// 将4个字节拷贝到resultmemcpy(result,dht11_data,4);printf(湿度%d.%dRH,,dht11_data[0],dht11_data[1]);printf(温度%d.%d℃,,dht11_data[2],dht11_data[3]);}delay_ms(2000);}5. 主函数main.cuint8_tdht11_result[4];while(1){// 为了避免数据冲突数据要清空memset(dht11_result,0,4);dht11_read(dht11_result);}6. 代码展示dht11.c#includedht11.h#includedelay.h#includestring.h#includestdio.hchardht11_data[5]{0};voiddht11_gpio_input(void){GPIO_InitTypeDef gpio_initstruct;// 打开时钟DHT11_CLK_ENABLE();// 调用GPIO初始化函数gpio_initstruct.PinDHT11_PIN;gpio_initstruct.ModeGPIO_MODE_INPUT;gpio_initstruct.SpeedGPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(DHT11_PORT,gpio_initstruct);}voiddht11_gpio_output(void){GPIO_InitTypeDef gpio_initstruct;// 打开时钟DHT11_CLK_ENABLE();// 调用GPIO初始化函数gpio_initstruct.PinDHT11_PIN;gpio_initstruct.ModeGPIO_MODE_OUTPUT_PP;gpio_initstruct.SpeedGPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(DHT11_PORT,gpio_initstruct);}// 起始及响应信号voiddht11_start(void){dht11_gpio_output();DHT11_DQ_OUT(1);DHT11_DQ_OUT(0);delay_ms(20);DHT11_DQ_OUT(1);// 响应信号等待拉高/拉低dht11_gpio_input();// 输入模式while(DHT11_DQ_IN);// 等待DHT11拉低电平while(!DHT11_DQ_IN);// 等待DHT11拉高电平while(DHT11_DQ_IN);// 等待DHT11总线拉低电平}// 读时序[读取每个字节]uint8_tdht11_read_byte(void){uint8_ttemp0;uint8_ti0;// 定义一个数据将8位保存起来uint8_tread_data0;// 读时序读数据for(i0;i8;i){while(!DHT11_DQ_IN);// 期待变成上升沿delay_us(50);if(DHT11_DQ_IN1)// 如果是高电平1{temp1;// 数据1while(DHT11_DQ_IN);// 50us后等待下降沿拉低电平}elsetemp0;// 先移位再把读到的数据插进去read_dataread_data1;// 左移1位右边空出1位read_data|temp;}returnread_data;}// 读取每个数据,要有返回值接收voiddht11_read(uint8_t*result){uint8_ti0;// 1. 起始响应信号dht11_start();// 2. 读数据输入模式dht11_gpio_input();// 3. 循环读入5个数据40bit数据for(i0;i5;i)dht11_data[i]dht11_read_byte();// 校验读出数据是否准确if(dht11_data[0]dht11_data[1]dht11_data[2]dht11_data[3]dht11_data[4]){// 将4个字节拷贝到resultmemcpy(result,dht11_data,4);printf(湿度%d.%dRH,,dht11_data[0],dht11_data[1]);printf(温度%d.%d℃,,dht11_data[2],dht11_data[3]);}delay_ms(2000);}dht11.h#ifndef__DHT11_H__#define__DHT11_H__#includesys.h#defineDHT11_PORTGPIOA#defineDHT11_PINGPIO_PIN_5#defineDHT11_CLK_ENABLE()__HAL_RCC_GPIOA_CLK_ENABLE()// 输出口IO口拉高拉低#defineDHT11_DQ_OUT(x)do{x?\HAL_GPIO_WritePin(DHT11_PORT,DHT11_PIN,GPIO_PIN_SET):\HAL_GPIO_WritePin(DHT11_PORT,DHT11_PIN,GPIO_PIN_RESET);\}while(0)// 输入口#defineDHT11_DQ_INHAL_GPIO_ReadPin(DHT11_PORT,DHT11_PIN)voiddht11_read(uint8_t*result);#endifmain.c#includesys.h#includedelay.h#includeled.h#includeuart1.h#includedht11.h#includestring.huint8_ti0;intmain(void){HAL_Init();/* 初始化HAL库 */stm32_clock_init(RCC_PLL_MUL9);/* 设置时钟, 72Mhz */led_init();uart1_init(115200);printf(hello world! \r\n);uint8_tdht11_result[4];while(1){// 为了避免数据冲突数据要清空memset(dht11_result,0,4);dht11_read(dht11_result);}}7. 实验结果如果用手捂住DHT11传感器温湿度会变化。
RELATED

相关推荐

Ubuntu 14.04一键安装Oracle 11gR2单机实战指南

Ubuntu 14.04一键安装Oracle 11gR2单机实战指南

1. 项目概述:为什么在 Ubuntu 14.04 上“一键安装 Oracle 11gR2 单机”这件事,至今还有人反复搜索? 你点开这个标题,大概率不是为了怀旧——没人会主动选一个早已结束官方支持(2019年4月EOL)、内核版本停留…

📅 2026/8/24 2:24:04
常用 PPG 公开数据集汇总(最全、实时更新)

常用 PPG 公开数据集汇总(最全、实时更新)

脉搏波的起源是心脏的左心室收缩。每当左心室收缩时,它将血液通过主动脉快速泵入体循环,该过程产生的压力振荡沿动脉血管壁逐层传导,最终形成可在外周血管采集到的脉搏波 。光体积描记法(Photoplethysmography, PPG)便…

📅 2026/8/24 2:24:04
C/C++头文件机制详解:从声明定义分离到编译链接优化

C/C++头文件机制详解:从声明定义分离到编译链接优化

1. 项目概述:为什么头文件是C/C的基石干了这么多年C/C开发,我敢说,头文件引用是每个程序员都绕不开,但又最容易踩坑的地方。你可能觉得不就是个#include嘛,敲进去就完事了。但真到项目大了,编译报错、链接失…

📅 2026/8/24 2:24:12
MORE NEWS

更多资讯

📰

Carbon 语言包声明语法统一提案解读:`package`/`library` 声明中 `impl` 修饰符前置与 `api` 关键字移除

Carbon 语言包声明语法统一提案解读:package/library 声明中 impl 修饰符前置与 api 关键字移除 【免费下载链接】carbon-lang Carbon Languages main repository: documents, design, implementation, and related tools. (NOTE: Carbon Language is experimental;…

📰

H5仿翻书效果实战:turn.js生产级兼容方案

简介:本资源是一套开箱即用的H5仿翻书效果实现方案,面向前端开发者及交互设计学习者,解决电子杂志、在线图书、产品展示等场景中沉浸式翻页体验的技术落地问题。压缩包共17个文件,含8张页面PNG素材(用于模拟书页内容&a…

📰

WordPress块主题架构与开发实践解析

1. WordPress块主题架构解析在WordPress 5.9版本引入的FSE(全站编辑)架构中,块主题(Block Theme)彻底改变了传统主题的开发模式。以Twenty Twenty-Five为代表的官方块主题,其目录结构和加载机制体现了WordP…

📰

comprehensive-rust 课程深度解析:Lifetime Elision 生命周期省略规则实战指南

comprehensive-rust 课程深度解析:Lifetime Elision 生命周期省略规则实战指南 【免费下载链接】comprehensive-rust This is the Rust course used by the Android team at Google. It provides you the material to quickly teach Rust. 项目地址: https://gitc…

📰

基于Playwright的短视频矩阵自动发布系统实践

简介:短视频矩阵内容分发系统设计资源包,面向正在做课程设计、期末大作业或毕业设计的计算机相关专业学生,也适合有一定编程基础、希望研究浏览器自动化与多平台内容分发的技术爱好者。资源瞄准视频多平台分发的典型痛点,围绕Play…

📰

OpenClaw服务参数校验错误分析与解决方案

1. 问题现象与初步定位 最近在调试OpenClaw服务时遇到了一个典型的参数校验错误。具体报错信息如下&#xff1a; 400 <400> InternalError.Algo.InvalidParameter: Range of input leng这个错误表面看起来是参数长度问题&#xff0c;但实际排查过程中发现情况比预想的复…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬