当前位置: 首页 > news >正文

DTH11温湿度传感器

DHT11 是一款温湿度复合传感器,常用于单片机系统中进行环境温湿度的测量。以下是对 DHT11 温湿度传感器的详细讲解:

一、传感器概述

DHT11 数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。传感器包括一个电容式感湿元件和一个 NTC 测温元件,并与一个高性能 8 位单片机相连接。

二、主要特点

  1. 体积小、功耗低:适合集成到各种小型电子设备中。
  2. 数字信号输出:无需复杂的模拟信号处理,直接输出数字信号,方便与单片机进行通信。
  3. 响应速度快:能够快速准确地测量环境温湿度变化。
  4. 精度较高:温度测量范围为 0℃ - 50℃,精度为 ±2℃;湿度测量范围为 20% - 90% RH,精度为 ±5% RH。

三、工作原理

  1. 传感器通过单片机的一个 I/O 口进行通信。单片机向 DHT11 发送启动信号后,DHT11 开始采集温湿度数据。
  2. 采集完成后,DHT11 将温湿度数据转换为数字信号,并通过数据线逐位发送给单片机。
  3. 单片机接收到数据后,进行校验和处理,以确保数据的准确性。

四、通信协议

  1. 单片机与 DHT11 之间采用单总线数据格式进行通信。通信过程包括初始化、发送启动信号、接收数据等步骤。
  2. 初始化时,单片机将数据线拉低一段时间,然后释放数据线,等待 DHT11 的响应。
  3. 发送启动信号时,单片机将数据线拉低至少 18ms,然后释放数据线,等待 DHT11 的响应。
  4. DHT11 接收到启动信号后,会发送一个 80μs 的低电平响应信号,接着发送 80μs 的高电平响应信号,表示准备好发送数据。
  5. DHT11 发送的数据包括 40 位,分别为 8 位湿度整数数据、8 位湿度小数数据、8 位温度整数数据、8 位温度小数数据和 8 位校验和。数据以低位在前的方式逐位发送。
  6. 单片机接收到数据后,进行校验和计算。如果校验和正确,则表示数据接收成功;否则,需要重新进行数据采集。

五、使用方法

  1. 硬件连接:将 DHT11 的 VCC 引脚连接到单片机的电源引脚,GND 引脚连接到地,DATA 引脚连接到单片机的一个 I/O 口。
  2. 软件编程:在单片机程序中,需要实现 DHT11 的初始化、启动信号发送、数据接收和校验等功能。可以使用定时器或延时函数来满足通信协议的时序要求。

操作时序:

在这里插入图片描述

复位信号和响应信号:

被调函数(DTH11):

#include "reg52.h"
#include "delay.h"sbit dht = P3^6; // 定义连接 DHT11 传感器的引脚,这里连接到 P3.6
char datas[5]; // 用于存储从 DHT11 读取的数据/*
DHT11 的时序逻辑分析:
a : dht = 1  设置引脚为高电平。
b £ºdht = 0  将引脚拉低。
ÑÓʱ30ms  延时 30 毫秒。
c£º dht = 1  将引脚拉高。
在 60us 后读 d 点,如果 d 点是低电平(被模块拉低),说明模块存在。
*/void DH11_Star() {dht = 1; // 设置引脚为高电平dht = 0; // 将引脚拉低Delay30ms(); // 延时 30 毫秒,发送启动信号给 DHT11dht = 1; // 将引脚拉高// 卡 d 点:等待 DHT11 拉低引脚作为响应开始信号while (dht);// 卡 e 点:等待 DHT11 释放引脚(变为高电平),表示准备发送数据while (!dht);// 卡 f 点:等待 DHT11 再次拉高引脚,确认准备发送数据while (dht);
}void Read_Data() {int i; // 用于循环计数,表示读取的数据组数(这里共 5 组数据)int j; // 用于循环计数,表示每组数据中的每一位char temp; // 临时变量,用于存储每一位数据在移位过程中的值char flag; // 标志位,用于表示读取到的数据位是 1 还是 0DH11_Star(); // 调用启动 DHT11 的函数for (i = 0; i < 5; i++) {// 卡 g 点:等待 DHT11 将引脚拉低,表示开始发送一组数据while (!dht);// 有效数据都是高电平,持续时间不一样,延时 50us 后根据引脚电平判断数据是 0 还是 1for (j = 0; j < 8; j++) {while (!dht); // 等待引脚拉低,表示开始读取一位数据Delay40us(); // 延时 40 微秒,根据引脚在这个时间后的电平判断数据位if (dht == 1) {flag = 1; // 如果引脚为高电平,标志位设为 1,表示读取到的数据位是 1while (dht); // 等待引脚再次拉低,准备读取下一位数据} else {flag = 0; // 如果引脚为低电平,标志位设为 0,表示读取到的数据位是 0}temp = temp << 1; // 将 temp 左移一位,为存储下一位数据做准备temp |= flag; // 将标志位的值存入 temp,完成一位数据的读取}datas[i] = temp; // 将读取到的一组数据存储到 datas 数组中}
}

delay函数:
 

#include <intrins.h>
void Delay15ms()//@11.0592MHz
{unsigned char i, j;i = 27;j = 226;do{while (--j);} while (--i);
}void Delay5ms()		//@11.0592MHz
{unsigned char i, j;i = 9;j = 244;do{while (--j);} while (--i);
}void Delay30ms()		//@11.0592MHz
{unsigned char i, j;i = 54;j = 199;do{while (--j);} while (--i);
}void Delay40us()		//@11.0592MHz
{unsigned char i;_nop_();i = 15;while (--i);
}void Delay1000ms()		//@11.0592MHz
{unsigned char i, j, k;_nop_();i = 8;j = 1;k = 243;do{do{while (--k);} while (--j);} while (--i);
}

LCD1602:
 

#include "reg52.h"
#include <intrins.h>
#include "delay.h"#define databuffer P0 // 定义 8 位数据总线,连接到 P0 端口sbit RS = P1^0; // 寄存器选择引脚,连接到 P1.0
sbit RW = P1^1; // 读写选择引脚,连接到 P1.1
sbit EN = P1^4; // 使能引脚,连接到 P1.4/*
RS(Register Select):- P1.0- 当 RS = 0 时,选择指令寄存器;当 RS = 1 时,选择数据寄存器。
RW(Read/Write):- P1.1- 当 RW = 0 时,进行写操作;当 RW = 1 时,进行读操作。
E(Enable):- P1.4- 下降沿触发数据传输。*/void check_busy() {char temp = 0x80; // 初始化为 1000 0000,用于读取忙碌标志位databuffer = 0x80;// 当单片机给 1602 发送数据时,通过检查忙碌标志位来避免死循环。// 高电平表示忙碌,在读取时序中,此时模块不能接收命令。如果为低电平表示不忙碌。while (temp & 0x80) {// 进入读时序RS = 0; // 设置为指令寄存器RW = 1; // 设置为读操作EN = 0;_nop_(); // 空操作,可能用于延时等待稳定EN = 1;_nop_();_nop_();temp = databuffer; // 读取数据总线上的值EN = 0;_nop_();}
}// 写指令函数
void Write_Cmd_Func(char cmd) {check_busy(); // 检查忙碌状态// 根据时序图配置引脚RS = 0; // 选择指令寄存器RW = 0; // 选择写操作EN = 0;_nop_(); // 延时等待稳定databuffer = cmd; // 将指令写入数据总线_nop_(); // 延时等待稳定EN = 1;_nop_();_nop_();EN = 0;_nop_();
}// 写数据函数
void Write_data_Func(char datashow) {check_busy(); // 检查忙碌状态RS = 1; // 选择数据寄存器RW = 0; // 选择写操作EN = 0;_nop_(); // 延时等待稳定databuffer = datashow; // 将数据写入数据总线_nop_(); // 延时等待稳定EN = 1;_nop_();_nop_();EN = 0;_nop_();
}void LCD1602_Init() {//(1)延时 15msDelay15ms();//(2)写指令 38H(不检测忙碌信号) Write_Cmd_Func(0x38);//(3)延时 5msDelay5ms();//(4)以后每次写指令、读/写数据操作均需要检测忙碌信号//(5)写指令 38H:显示模式设置Write_Cmd_Func(0x38);//(6)写指令 08H:显示关闭Write_Cmd_Func(0x08);//(7)写指令 01H:显示清屏Write_Cmd_Func(0x01);//(8)写指令 06H:显示光标移动设置Write_Cmd_Func(0x06);//(9)写指令 0CH:显示开及光标设置Write_Cmd_Func(0x0c);
}
void LCD1602_showline(char row, char col, char *string) {// 根据行号设置显示地址switch (row) {case 1:// 设置第一行的显示地址Write_Cmd_Func(0x80 + col);// 循环写入字符串中的每个字符while (*string) {// 将当前字符写入数据寄存器以显示在 LCD 上Write_data_Func(*string);// 指针指向下一个字符string++;}break;case 2:// 设置第二行的显示地址Write_Cmd_Func(0x80 + 0x40 + col);while (*string) {Write_data_Func(*string);string++;}break;}
}

主函数:

#include "reg52.h"
#include <intrins.h>
#include "delay.h"
#include "uart.h"
#include "lcd1602.h"
#include "dht11.h"
#include "config.h"// 定义用于存储温度和湿度显示字符串的字符数组
char temp[8];
char huma[8];
// 声明外部变量 datas,可能用于存储从 DHT11 传感器读取的数据
extern char datas[5];// 函数用于构建温度和湿度的显示字符串
void build_datas() {// 将湿度的标识字符 'H' 存入 huma 数组的第一个位置huma[0] = 'H';// 将 datas 数组中第一个元素(湿度整数部分的十位数字)转换为 ASCII 码存入 huma 数组的第二个位置huma[1] = datas[0]/10 + 0x30;// 将 datas 数组中第一个元素(湿度整数部分的个位数字)转换为 ASCII 码存入 huma 数组的第三个位置huma[2] = datas[0]%10 + 0x30;// 存入小数点huma[3] = '.';// 将 datas 数组中第二个元素(湿度小数部分的十位数字)转换为 ASCII 码存入 huma 数组的第四个位置huma[4] = datas[1]/10 + 0x30;// 将 datas 数组中第二个元素(湿度小数部分的个位数字)转换为 ASCII 码存入 huma 数组的第五个位置huma[5] = datas[1]%10 + 0x30;// 存入百分号huma[6] = '%';// 字符串结束标志huma[7] = '\0';// 将温度的标识字符 'T' 存入 temp 数组的第一个位置temp[0] = 'T';// 将 datas 数组中第三个元素(温度整数部分的十位数字)转换为 ASCII 码存入 temp 数组的第二个位置temp[1] = datas[2]/10 + 0x30;// 将 datas 数组中第三个元素(温度整数部分的个位数字)转换为 ASCII 码存入 temp 数组的第三个位置temp[2] = datas[2]%10 + 0x30;// 存入小数点temp[3] = '.';// 将 datas 数组中第四个元素(温度小数部分的十位数字)转换为 ASCII 码存入 temp 数组的第四个位置temp[4] = datas[3]/10 + 0x30;// 将 datas 数组中第四个元素(温度小数部分的个位数字)转换为 ASCII 码存入 temp 数组的第五个位置temp[5] = datas[3]%10 + 0x30;// 存入摄氏度符号temp[6] = 'C';// 字符串结束标志temp[7] = '\0';
}int main() {// 延时 1000 毫秒Delay1000ms();// 初始化串口UartInit();// 初始化 LCD1602LCD1602_Init();// 再次延时 1000 毫秒Delay1000ms();Delay1000ms();// 设置 ledOne 为 0,可能用于控制某个 LEDledOne = 0;while (1) {// 延时 1000 毫秒Delay1000ms();// 读取 DHT11 传感器的数据Read_Data();// 如果温度(datas[2])大于等于 24if (datas[2] >= 24) {// 设置风扇状态为关闭(fengshan 可能是一个变量用于控制风扇)fengshan = 0;} else {// 否则设置风扇状态为开启fengshan = 1;}// 构建温度和湿度的显示字符串build_datas();// 发送湿度字符串到串口sent_string(huma);// 发送回车换行符到串口sent_string("\r\n");// 发送温度字符串到串口sent_string(temp);// 发送回车换行符到串口sent_string("\r\n");// 在 LCD1602 的第一行第二列开始显示湿度字符串LCD1602_showline(1, 2, huma);// 在 LCD1602 的第二行第二列开始显示温度字符串LCD1602_showline(2, 2, temp);}
}

成功实现:

相关文章:

DTH11温湿度传感器

DHT11 是一款温湿度复合传感器&#xff0c;常用于单片机系统中进行环境温湿度的测量。以下是对 DHT11 温湿度传感器的详细讲解&#xff1a; 一、传感器概述 DHT11 数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感…...

【Linux系列】CMA (Contiguous Memory Allocator) 简单介绍

CMA (Contiguous Memory Allocator) CMA是Linux内核中的一种内存分配机制&#xff0c;用于分配物理上连续的内存块。它主要解决了在系统运行一段时间后&#xff0c;物理内存碎片化导致难以分配大块连续物理内存的问题。 CMA的工作原理 在系统启动时&#xff0c;CMA会预留一块…...

基于单片机餐厅呼叫控制系统仿真设计

文章目录 前言资料获取设计介绍设计程序具体实现截图设计获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师&#xff0c;一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们…...

详细分析Mysql中的定时任务(Event事件)

目录 前言1. 基本知识2. Event事件3. Demo 前言 基本的知识推荐阅读&#xff1a; 详细分析Mysql触发器的基本使用&#xff08;图文解析&#xff09;详细分析SQL Server触发器的基本知识详细分析Corn表达式&#xff08;附Demo&#xff09; 特性事件定时任务触发器触发条件基于…...

SpinalHDL之语义(Semantic)(三)

本文作为SpinalHDL学习笔记第七十一篇,介绍SpinalHDL的规则(Rules)。 目录: 1.简介(Introduction) 2.并⾏性(Concurrency) 3.以最后赋值为准(Last valid assignment wins) 4.Scala下的信号和寄存器的内在联系(Signal and register interactions with Scala)(OOP引⽤+函数…...

SpringBoot 请求和响应

1. Spring Boot 请求与响应概述 在 Spring Boot 开发中&#xff0c;客户端通过浏览器发起请求&#xff0c;后端使用内置的 Tomcat Web 服务器处理请求&#xff0c;返回响应数据。请求和响应的过程遵循 HTTP 协议。Spring Boot 的核心 Servlet 程序是 DispatcherServlet&#x…...

LQR算法核心思想

本章以倒立摆为解决目的 什么是线性二次型控制器&#xff08;LQR&#xff09; 开环系统 即状态变量的倒数 系统的状态空间矩阵A * 系统状态变量x A状态矩阵&#xff1a;描述系统本身物理特性的一个矩阵&#xff0c;它是由系统本身的机械结构、物理结构决定的&#xff0c;无法…...

AI大模型之旅-最强开源文生图工具Stable Diffusion WebUI 教程

1.1克隆 Automatic1111 的 GitHub 仓库 在你想安装 Web UI 的文件夹路径下执行 git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui 这将会克隆整个仓库到本地。 这里会默认访问 https://huggingface.co/ 下载 因此需要魔法 1.2 进入仓库目录 cd stable-di…...

WinForm程序嵌入Web网页

文章目录 前言一、三方库或控件的选择测试二、Microsoft Edge WebView2安装、使用步骤1.安装2.使用 前言 由于此项目需要winform客户端嵌入web网页并于JAVA端交互数据&#xff0c;所以研究了一下嵌入web网页这部分&#xff0c;趟了一遍雷&#xff0c;这里做下记录。 一、三方库…...

Redis string类型hash类型

string类型 类型介绍 在Redis中的所有的key都是string类型&#xff0c;而value的类型有多种。 Redis中的字符串是直接按照二进制的方式进行存储的&#xff0c;也就是不会做任何的编码转换&#xff0c;存的是什么&#xff0c;取出来的就是什么。这样一般来说&#xff0c;Redi…...

Solidity智能合约中的异常处理(error、require 和 assert)

Solidity 中的三种抛出异常方法&#xff1a;error、require 和 assert 在 Solidity 开发中&#xff0c;异常处理是确保智能合约安全性和正确性的关键步骤。Solidity 提供了三种主要方法来抛出异常&#xff1a;error、require 和 assert。本文将详细介绍这三种方法的用途、实现方…...

True NAS禁用ipv6

在 TrueNAS Scale 中&#xff0c;禁用 IPv6 的方法如下&#xff1a;12 进入 System->Advanced->Sysctl&#xff0c;设置一个 sysctl 可调整变量 net.ipv6.conf.all.disable_ipv6&#xff0c;值为 1&#xff0c;以完全禁用 IPv6。\...

笔记整理—linux进程部分(2)使用fork创建进程

为什么要创建进程&#xff0c;首先每个程序的运行都需要一个进程&#xff1b;多进程实现宏观上的并行。 fork的原理&#xff0c;是进程的分裂生长模式。如果操作系统需要一个新的进程&#xff0c;那么就会以cp的方法得到一个新的进程&#xff0c;此时老的进程是父进程&#xff…...

在Python中实现多目标优化问题(6)

在Python中实现多目标优化问题 在Python中实现多目标优化&#xff0c;除了传统的进化算法&#xff08;如NSGA-II、MOEA/D&#xff09;和一些基于机器学习的方法外&#xff0c;还有一些新的方法和技术。这些新方法通常结合了最新的研究成果&#xff0c;提供了更高效的解决方案。…...

Java EE中的编码问题及解决方案

Java EE中的编码问题及解决方案 在Java EE开发中&#xff0c;处理字符编码是确保数据正确传输和显示的重要环节。不同的编码不一致会导致乱码&#xff0c;影响用户体验。本文将总结在Java EE中可能遇到的编码问题及其解决方案。 1. 输入数据编码问题 在表单提交时&#xff0c…...

9月27日,每日信息差

第一、中国科学家团队在干细胞治疗领域取得重要突破&#xff0c;通过化学重编程技术成功制备出胰岛细胞&#xff0c;并用于移植治疗一名 1 型糖尿病患者&#xff0c;实现了临床功能性治愈。相关研究成果已发表在国际权威期刊《细胞》上。 第二、交通运输部公路局局长周荣峰在国…...

什么是 Angular 开发中的 Dumb components

Dumb components&#xff0c;在 Angular 开发中也被称为 Presentational components&#xff0c;它们的主要职责是通过展示数据和触发事件&#xff0c;把业务逻辑和 UI 表现分离开来。Dumb components 只通过 Input() 接收数据&#xff0c;Output() 向外发送事件&#xff0c;不…...

Docker 进入容器运行命令的详细指南

Docker 进入容器运行命令的详细指南 Docker 是一个开源的容器化平台&#xff0c;广泛应用于开发和生产环境中。它允许开发者打包应用程序及其依赖项到容器中&#xff0c;并能够在不同的平台上快速部署和运行。容器通常是独立且隔离的&#xff0c;但在开发、调试或维护过程中&a…...

如何禁止非真实用户的ip访问网站服务器

为了禁止非真实用户的IP访问网站服务器&#xff0c;可以采用多种技术手段和策略。以下是一些常用的方法&#xff1a; 1. 使用IP黑名单和白名单 黑名单&#xff1a;定期更新和维护一个IP黑名单&#xff0c;阻止已知的恶意IP地址或数据中心IP访问网站。白名单&#xff1a;对于特…...

探索SpringBoot:学科竞赛管理项目开发

2 相关技术简介 2.1Java技术 Java是一种非常常用的编程语言&#xff0c;在全球编程语言排行版上总是前三。在方兴未艾的计算机技术发展历程中&#xff0c;Java的身影无处不在&#xff0c;并且拥有旺盛的生命力。Java的跨平台能力十分强大&#xff0c;只需一次编译&#xff0c;任…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh&#xff1f; debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

蓝桥杯3498 01串的熵

问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798&#xff0c; 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

视觉slam十四讲实践部分记录——ch2、ch3

ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

嵌入式学习笔记DAY33(网络编程——TCP)

一、网络架构 C/S &#xff08;client/server 客户端/服务器&#xff09;&#xff1a;由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序&#xff0c;负责提供用户界面和交互逻辑 &#xff0c;接收用户输入&#xff0c;向服务器发送请求&#xff0c;并展示服务…...