DHT11

第一个传感----DHT11

通过前面的学习,你已经学会了控制IO口、延时函数、串口的收发。接下来,你就可以借助以上的知识点完成自己的第一个传感器--DHT11啦!

img

DHT11 数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。应用非常广泛,并且具有长期的稳定性。

1.引脚说明

VDD------电源 3.3-5v

GND------接地

DATA-----数据

2.数据格式

DHT11采用的是单总线进行通信,即只有一条数据线,一次传送40位的数据,高位先出。

“8bit 湿度整数数据 + 8bit 湿度小数数据 + 8bit 温度整数数据 + 8bit 温度小数数据 + 8bit 校验位”。其中,8bit的校验位是由前32位的位分别相加所得。

注:其中湿度小数部分为 0。

3.数据时序图:

注:主机从 DHT11 读取的温湿度数据总是前一次的测量值,如两次测间隔时间很长,请连续读两次以第二次获得的值为实时温湿度值。

4.读取步骤:(假设DATA 数据线的引脚接入到P22)

首先让接DHT11 中 P22空闲时保持一段时间的高电平越过不稳定状态。

(1)起始信号:

拉低P22端口22ms(这里只要在18ms-30ms就行),然后再拉高P22

(2)响应信号:

DHT11传感器会将P22引脚拉低83us,再拉高87us。

(3)40位数据:

接着DHT11传感器会连续发送40位数据,高位先出。

其中:54us低电平和23-27us的高电平表示位数据“1”

54us的低电平加上68-74us的高电平表示数据“0”

这里,我们如何用代码来实现这个操作呢?

我们可以在上升沿开始计数>40(最好是40-60之间),计数完成后判断此时P22的引脚是高电平还是低电平,若是高电平则为数据“1”,若低电平则为数据“0”。

(4)结束信号

将P22拉高即可,这里我们在前面使用空闲状态去代替了结束信号

(5)数据转换

我们所得到的初数据是八位的二进制,范围是0-255,为了能够在串口发送,我们需要将它转换为字符型,方便显示。

(6)校验位+串口发送

判断 8bit 校验位是否等于“8bit 湿度整数数据 + 8bit 湿度小数数据 + 8bit 温度整数数据 + 8bit 温度小数数据 ”,如果不相等则说明此时接收的数据有问题。如果没问题的话,就用之前UART发送字符串的方法发送给电脑,以供显示。

5.案例工程代码:(建议用逻辑分析仪看波形)

main.c

/****************************数据类型******************************
unsigned char   uchar   8   0~255
signed   char   char    8   -128~127
unsignec int    uint    16  0~65535
signed   int    int     16  -32768~32767
******************************************************************/
#include "main.h"
/************************函数声明*************************************/
void STC8H_IOinit(void);            //STC15W单片机引脚初始化函数
/*===========================================================*/
/*函数:void STC32G_IOinit(void)
/*功能:STC18H单片机引脚初始化函数
/*说明:统一将单片机所有引脚初始化为准双向口工作模式
/*修改日期:2023.10.16
/*===========================================================*/
void STC8H_IOinit(void)
{P0M1 = 0;   P0M0 = 0;   //设置为准双向口   参考用户手册387页P1M1 = 0;   P1M0 = 0;   //设置为准双向口   参考用户手册387页P2M1 = 0;   P2M0 = 0;   //设置为准双向口   参考用户手册387页P3M1 = 0;   P3M0 = 0;   //设置为准双向口   参考用户手册387页P4M1 = 0;   P4M0 = 0;   //设置为准双向口   参考用户手册387页P5M1 = 0;   P5M0 = 0;   //设置为准双向口   参考用户手册387页P6M1 = 0;   P6M0 = 0;   //设置为准双向口   参考用户手册387页P7M1 = 0;   P7M0 = 0;   //设置为准双向口   参考用户手册387页  P0 = 0XFF;  P1 = 0XFF;  P2 = 0XFF; P3 = 0XFF;  P4 = 0XFF;  P5 = 0XFF; P6 = 0XFF;  P7 = 0XFF;                      //设置P0~P7所有I/O口为高电平
}
​
​
​
/****************************************************************************************************
/*函数:void main()
/*功能:40MHZ
/*说明:主函数
/*修改日期:
/****************************************************************************************************/
void main() 
{DHT11_ObjectTypedef hDHT11; STC8H_IOinit();DHT11_Init(hDHT11.rdata);while(1) {if(DHT11_Read(hDHT11.rdata)){if (hDHT11.rdata[0]+hDHT11.rdata[1]+hDHT11.rdata[2]+hDHT11.rdata[3]==hDHT11.rdata[4]) {SendString("湿度:");SendString(intToStr(hDHT11.rdata[0]));SendString(".");SendString(intToStr(hDHT11.rdata[1]));SendString("% ");SendString("温度:");SendString(intToStr(hDHT11.rdata[2]));SendString(".");SendString(intToStr(hDHT11.rdata[3]));SendString("C");}}Delay_ms(500);//40MHZ}
}

main.h

#ifndef __MAIN_H__
#define __MAIN_H__
​
#include "STC8H.h"  //单片机头文件(包含单片机的特殊功能寄存器的定义)  
#include "intrins.h"//nop头文件
#include "DHT11.h"  
#include "UART.h"   
#include "Delay.h"  
​
​
typedef unsigned char u8;
typedef unsigned int    u16;
typedef unsigned long u32;
​
#endif

DHT11.C

#include "main.h"
​
void DHT11_Init(unsigned char* arr)
{   unsigned char i;for(i=0;i<5;i++){arr[i]=0;}
}
//该DHT11在40MHZ运行
unsigned char DHT11_Read(unsigned char* arr)
{unsigned char out,i=0,j=0,rdata=0;
​//空闲状态P22 = 1;Delay_us(2);// 起始信号    P22 = 0;//拉低P22Delay_ms(22); //延时22ms               P22 = 1;   
​// 应答信号Delay_30us(1);out=0;while(!P22)//等待传感器拉低P22{Delay_us(1);        if(out++ > 100) //while内部用于计时,如果超过100us则判断应答失败,应该重新发送起始信号return 0;}out = 0;while(P22) //等待传感器拉高P22{Delay_us(1);        if(out++>100) //while内部用于计时,如果超过100us则判断应答失败,应该重新发送起始信号return 0;}
​// 读取数据for(j=0;j<5;j++)//读取5个字节{rdata=0;//暂存8位的变量for(i=0;i<8;i++)//读取8位 {      out=0;while(!P22)//等待P22拉高{Delay_us(1);        if (out++>100)//while内部用于计时,如果超过100us则判断应答失败,应该重新发送起始信号return 0;}Delay_us(40);rdata<<=1;    if(P22)//如果此时P22为高电平,则判断为数据为“1” {rdata|=0x01;}out=0;while(P22)//等待P22拉低,以读取下一个位 {Delay_us(1);        if(out++ > 100)//while内部用于计时,如果超过100us则判断应答失败,应该重新发送起始信号return 0;}}arr[j]=rdata;//将暂存的(1字节)数据分别放入数组中}return 1;
}
​
char* intToStr(unsigned char num) {static char str[4]; int i=3;str[i]='\0';//结尾符i--;
​if (num==0) {str[i]='0';i--;} else {while (num>0) {str[i]='0'+(num%10);num/=10;i--;}}return &str[i+1];//从下标0开始
}

DHT11.h

#ifndef __DHT11_H__
#define __DHT11_H__
​
typedef struct Dht11
{unsigned char rdata[5];//数据位+校验位40位数据}DHT11_ObjectTypedef;
​
void DHT11_Init(unsigned char* rdata);
//该DHT11在40MHZ运行
unsigned char DHT11_Read(unsigned char* rdata);
char* intToStr(unsigned char num);
​
#endif

UART.C

#include "main.h"
​
//串口发送一个字符
void SendChar(char dat)
{unsigned char i;//起始信号P31=0;Pote(1);
​//发送8bitfor(i=0; i<8; i++) {P31 = dat & 0x01;Pote(1);dat >>= 1;}//结束信号P31=1;Pote(1);
}
​
//串口发送字符串
void SendString(char *s)
{while (*s) {SendChar(*s);  s++;                            }
}

UART.H

#ifndef __UART_H__
#define __UART_H__
​
​
​
//串口发送一个字符
void SendChar(char dat);
//串口发送字符串
void SendString(char *s);
#endif

Delay.c

#include "main.h"
​
void Pote(unsigned int time)//40mhz
{unsigned int i;unsigned int j;for(j=0;j<time;j++){for(i=0;i<462;i++){_nop_();}}
}
​
void Delay_ms(unsigned int time)//40mhz
{unsigned int i;unsigned int j;for(j=0;j<time;j++){for(i=0;i<4973;i++){_nop_();}}
}
​
​
void Delay_us(unsigned int time)//40mhz
​
{unsigned int i;unsigned int j;for(j=0;j<time;j++){for(i=0;i<1;i++){_nop_();}}
}
​
void Delay_30us(unsigned int time)//40mhz
{unsigned int i;unsigned int j;for(j=0;j<time;j++){for(i=0;i<107;i++){_nop_();}}
}
​

Delay.h

#ifndef __DELAY_H__
#define __DELAY_H__
​
void Pote(unsigned int time);//40mhz
void Delay_ms(unsigned int time);//40mhz
void Delay_us(unsigned int time);//40mhz
void Delay_30us(unsigned int time);//40mhz
​
#endif
​
6.结果展示

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

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

相关文章

【ai】tx2 nx : fix pip升级警告

jetson 环境同样出现:【原创】pip3 使用报警问题在对 Ubuntu 18.04 上的 pip3 9.0.1 版本使用 pip install -U pip 的方式进行升级后,再使用 pip 就会出现一堆警告信息。这个警告信息目前不影响使用,但从警告信息来看,会在未来版本中出现失败风险。 当前系统中存在了两个不…

【浅学】大模型(科普向_持续更新中)

【读者福利】大模型全套教程&#xff0c;微信扫码领取~ 1. 大模型概述 大模型是指具有数千万甚至数亿参数的深度学习模型。 当我们提及大模型时&#xff0c;通常指的是大语言模型&#xff08;Large Language Model&#xff0c;简称LLM&#xff09;&#xff0c;即文字问答模型…

RAID详解及配置实战

目录 一、RAID磁盘阵列及详解 1.1 了解RAID 1.1.1 简单理解 1.1.2 对比了解 1.2 RAID磁盘阵列介绍 1.3 RAID功能实现 1.4 RAID实现的方式 1.5 RAID级别详解 1.5.1 RAID -0 1.5.2 RAID -1 1.5.3 RAID -5 1.5.4 RAID -10&#xff08;RAID 10&#xff09; 1.6 阵列卡…

数据驭王: PostgreSQL教程指南解密

PostgreSQL教程大纲 一、介绍1.1 什么是PostgreSQL&#xff1f;1.2 PostgreSQL的历史和发展1.3 为什么选择PostgreSQL&#xff1f; 二、安装和设置2.1 下载和安装PostgreSQL2.2 配置PostgreSQL2.3 测试PostgreSQL 三、基本操作3.1 连接到PostgreSQL数据库步骤一&#xff1a;安装…

如何实现灌区闸门控制自动化?宏电“灌区哨兵”为灌区闸门控制添“智慧”动能

闸门控制站是节水灌溉工程中的重要组成部分。随着科技的不断进步和农田水利现代化的发展&#xff0c;传统的闸门控制和管理手段已经不能满足现代农业的发展要求。以宏电“灌区哨兵”为核心的闸门自动化控制系统&#xff0c;能有效解决灌区闸门距离远、数量多、不易操作、不好监…

ApolloClient GraphQL 与 ReactNative

要在 React Native 应用程序中设置使用 GraphQL 的简单示例&#xff0c;您需要遵循以下步骤&#xff1a; 设置一个 React Native 项目。安装 GraphQL 必要的依赖项。创建一个基本的 GraphQL 服务器&#xff08;或使用公共 GraphQL 端点&#xff09;。从 React Native 应用中的…

CST软件中滤波器中外部耦合偏小怎么办

在电磁仿真领域&#xff0c;CST Studio Suite&#xff08;CST 工作室套装&#xff09;软件以其强大的功能和易用性而广受工程师和科研人员的青睐。然而&#xff0c;在使用CST软件进行滤波器设计时&#xff0c;有时会遇到外部耦合偏小的问题&#xff0c;这可能导致滤波器的性能不…

避开常见的坑,快速制作一个免费、交互式景区导游地图

目录 1 前言 2 注册登录 3 增加景区&#xff0c;注意设置地图中心点和级别 3.1 确定地图位置和缩放级别 3.2 新增景区&#xff0c;输入几个文本项目 3.3 可以继续调整地图位置和级别 4 增加景点 4.1 点击景点跳转错误 5 新增景区和景点介绍帖子&#xff0c;需要催一下…

系统架构师考点--计算机网络

大家好。今天我来总结一下计算机网络的相关考点。本部分分值占3-5分&#xff0c;基本上都出现在上午场的选择题。 一、网络功能和分类 计算机网络是计算机技术与通信技术相结合的产物&#xff0c;它实现了远程通信、远程信息处理和资源共享。 计算机网络的功能&#xff1a;数…

无限制数字(仅仅int类型)的大小的自然排序算法

直接上代码&#xff1a; #include <iostream> #include <vector> #include <string> #include <algorithm> #include <cctype>// Function to compare two strings in a natural way bool naturalCompare(const std::string& a, const std:…

java版本ERP管理系统源码 Spring Cloud erp系统-更专业的ERP管理系统

ERP&#xff08;Enterprise Resource Planning&#xff0c;企业资源计划&#xff09;软件是一种集成的管理平台&#xff0c;它将企业的所有业务流程&#xff0c;包括采购、销售、库存、财务等&#xff0c;整合到一个统一的系统中。这种整合不仅提高了工作效率&#xff0c;还增强…

电脑硬盘数据恢复,4个方法,轻松恢复数据

在数字化时代的浪潮中&#xff0c;电脑硬盘不仅是存储数据的仓库&#xff0c;更是我们生活、工作、学习的记忆宫殿。然而&#xff0c;当这个宫殿中的一部分珍贵记忆突然消失&#xff0c;仿佛历史的片段被无情地抹去&#xff0c;我们不禁会感到焦虑和恐慌。此时&#xff0c;电脑…

【播客笔记】摸着大佬入门!把〖AI+能源〗〖AI+硬件〗两个热门话题彻底聊透! | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; 1. 硅谷101 | 科技巨头们开始抢电&#xff1f;聊聊AI用电荒和核聚变创业热 播客链接 → https://www.xiaoyuzhoufm.com/episode/663035780571efa80f8…

基于springboot在线考试报名系统-计算机毕业设计源码031706

摘 要 随着计算机技术的迅猛发展&#xff0c;学校教学和管理的信息化发展也有长足的进步&#xff0c;考试也是一样。与传统的考试方式相比&#xff0c;网络考试报名系统极大地提高了考试的灵活性&#xff0c;并在许多领域已经有了广泛的应用。网上考试报名系统的最大优点是可以…

视频文件太大怎么压缩?十大视频压缩软件可解决您的问题

您是否已经受够了无法上传视频文件&#xff0c;因为它们太大了&#xff1f;如果您正在积极寻找免费下载的视频压缩软件&#xff0c;下面概述了目前在线提供的 10 个功能更强大的软件。 我们建议您在决定下载之前先通读一下这个简短的介绍。我们不希望您随意点击一个选项&#…

2024年JCR分区,将发生重大变化

科睿唯安官方微信发布消息&#xff0c;指出今年的期刊排名及相应JCR分区将发生重大变化。 原文比较长&#xff0c;不熟悉相关规则的朋友也不太容易读懂。因此&#xff0c;我们今天做一个详细的解读。 首先明确几个基本概念&#xff1a; &#xff08;1&#xff09;2024年发布2…

基于PHP+MySql的留言管理系统的设计与实现

功能概述 网页留言板管理系统&#xff0c;用户层面分为普通用户和管理员&#xff0c;并设权限&#xff08;即后台留言管理系统普通用户不能访问&#xff0c;别人的留言自己不可以修改删除&#xff0c;未登录不能使用留言功能&#xff09;&#xff0c;功能包括用户登录注册、留…

阿里云+Halo个人博客搭建

前言 本文将介绍使用阿里云Halo搭建一个个人网站&#xff0c;过程极其简单&#xff0c;不需要什么计算机基础&#xff0c;操作电脑跟着步骤做就行。 在开始之前&#xff0c;还需要做一些前置准备 购买好服务器&#xff0c;本文使用阿里云&#xff0c;系统选择CentOS 7.6 64位…

Ollama:一个在本地部署、运行LLM大型语言模型的工具

Ollama部署、运行大型语言模型 概述 Ollama是一个专为在本地机器上便捷部署和运行大型语言模型&#xff08;LLM&#xff09;而设计的工具。 官方网站&#xff1a;https://ollama.com/ Github&#xff1a;https://github.com/ollama/ollama 安装 Ollama支持macOS、Linux和Win…

[吃瓜教程]南瓜书第3章对数几率回归

第三章 对数几率回归 3.1 算法原理 对数几率回归&#xff08;Logistic Regression&#xff09;是一种统计方法&#xff0c;主要用于二分类问题。它通过拟合一个对数几率函数&#xff08;logit function&#xff09;&#xff0c;即对数几率&#xff08;log-odds&#xff09;与…