DHT11温湿度数据获取

本文详细介绍了使用DHT11传感器获取温湿度数据的过程,包括硬件连接、单总线通信原理、CubeMx配置步骤以及获取数据的时序控制和代码实现。
摘要由CSDN通过智能技术生成

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


一、硬件原理图

DHT11是通过单总线(PB5)与主机进行数据传输的。单片机发送一次复位信号后,DHT11 从低功耗模式转换到高速模式,等待主机复位结束后,DHT11 发送响应信号,并拉高总线准备传输数据。一次完整的数据为 40bit,按照高位在前,低位在后的顺序传输。

数据格式为:8bit 湿度整数数据+8bit 湿度小数数据+8bit 温度整数数据+8bit 温度小数数据+8bit 校验和,一共 5 字节(40bit)数据。由于 DHT11 分辨率只能精确到个位,所以小数部分是数据全为 0。校验和为前 4 个字节数据相加,校验的目的是为了保证数据传输的准确性。
在这里插入图片描述

二、CubeMx配置

配置PB5为开漏输出模式,在该模式下主机和从机均可以获取该数据线的控制权。
在这里插入图片描述

三、获取温湿度数据

本来使用的时序图来自于博文https://blog.csdn.net/m0_55849362/article/details/126426768?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170945072816800184177593%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=170945072816800184177593&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-126426768-null-null.142^v99^pc_search_result_base8&utm_term=DHT11&spm=1018.2226.3001.4187

操作时序

在这里插入图片描述

主机发送起始信号

在这里插入图片描述

DHT11 只有在接收到开始信号后才触发一次温湿度采集,如果没有接收到主机发送复位信号,DHT11 不主动进行温湿度采集。当数据采集完毕且无开始信号后,DHT11 自动切换到低速模式。

主机接收响应信号并且接受数据

DHT11 在拉高总线 80us 后开始传输数据。每 1bit 数据都以 50us 低电平时隙开始,告诉主机开始传输一位数据了。DHT11 以高电平的长短定义数据位是 0 还是 1,当 50us 低电平时隙过后拉高总线,高电平持续 26~28us 表示数据“0”;持续 70us 表示数据“1”。
当 最后 1bit 数据传送完毕后,DHT11 拉低总线 50us,表示数据传输完毕,随后总线由上拉电阻拉高进入空闲状态。
在这里插入图片描述

代码实现

#include "libs.h"
#include "gpio.h"
#include "drivers.h"
#include <stdio.h>
static int DHT11Read(DHT11_s *dht11Dev);
#define MYDHT11				\
{							\
	.temperature = 0,		\
	.humidity = 0,			\
	.Read = DHT11Read,      \
}							\

DHT11_s DHT11Dev = MYDHT11;
static void UDelay(uint32_t us){
	us = us * 45;
	while(us--);
}
/*
 *描述:主机给DHT11发送复位信号,让DHT11采集温湿度数据
 *参数:无
 *返回值:ESUCCESS 成功
 * 		  OTHER	   失败
 */
static int DHT11Start(void){
    DHT11DATAHIGH;
    UDelay(2);
	//拉低至少18ms
	DHT11DATALOW;
	MDelay(20);
	//拉高20-40us
	DHT11DATAHIGH;
    
	return ESUCCESS;
}

/*
 *描述:主机接受DHT11发送的一个字节数据
 *参数:无
 *返回值:data 接收的数据
 */
static int DHT11RecvByte(void){
	uint8_t data = 0;
	uint8_t newbit = 0; 
	int timeout = 0;
	for(uint8_t i = 0;i < 8; i++){	
		//等待从机拉低 发送数据
		timeout = 100;
	    while(DHT11DATA && timeout){ 
	        timeout--;
	        UDelay(1);
	    }

	    if(DHT11DATA && (timeout <= 0) ){
			LogDebug("Timeout\r\n");
	        return -EIO;
	    }
		
		//等待50us低电平过去
		timeout = 100;
	    while(!DHT11DATA && timeout){ 
	        timeout--;
	        UDelay(1);
	    }

		if(!DHT11DATA && (timeout <= 0) ){
			LogDebug("Timeout\r\n");
	        return -EIO;
	    }
		//延时40us
		UDelay(50);
		data = data << 1;
		if(DHT11DATA){
			newbit = 1;
		}else{
			newbit = 0;
			}
		data = data + newbit;  
	}

	return data;
}

static int DHT11Read(DHT11_s *dht11Dev){
    uint8_t data[5] = {0};
    
    DHT11Start();
    
    int timeout = 50;
    //等待从机拉低
    while(DHT11DATA && timeout){ 
        timeout--;
        UDelay(1);
    }

    if(DHT11DATA && (timeout <= 0) ){
		LogDebug("Timeout\r\n");
        return -EIO;
    }

	timeout = 100;
    //发送响应信号
    while(!DHT11DATA && timeout){ 
        timeout--;
        UDelay(1);
    }

	if(!DHT11DATA && (timeout <= 0) ){
		LogDebug("Timeout\r\n");
        return -EIO;
    }
    UDelay(80);
    data[0] = DHT11RecvByte();
    data[1] = DHT11RecvByte();
    data[2] = DHT11RecvByte();
    data[3] = DHT11RecvByte();
    data[4] = DHT11RecvByte();
    if(data[4] == (data[3]+data[2]+data[1]+data[0])){
        dht11Dev->humidity = data[0];
        dht11Dev->humidity = (dht11Dev->humidity<<8)+data[1];
        dht11Dev->temperature = data[2];
        dht11Dev->temperature = (dht11Dev->temperature<<8)+data[3];

        LogDebug("humidity is %2d.%2d,temperature is %2d.%2d\r\n",(dht11Dev->humidity>>8),(dht11Dev->humidity&0x00FF),(dht11Dev->temperature>>8),(dht11Dev->temperature&0x00FF));
        return ESUCCESS;
    }

	return -EIO;
}

  • 15
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

葛霸霸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值