温湿度模块DHT11(hal库)

目录

温湿度模块DHT11(hal库)

DHT11原理

代码实现


温湿度模块DHT11(hal库)

DHT11原理

1.发送起始:引脚拉低至少18ms低电平,然后再拉高20-40us的高电平。

2.等待响应信号:低电平持续80us,高电平持续80us。

3.读数据 :通过观察可以得知数据1和数据0起始部分都是50us的低电平,数据0高电平时间为26-28us之间,数据高电平时间为70us。所以这里我读的就是为高电平的40us后,如果还是高电平即为1,否则为0。

4.数据校验:8 位湿度整数数据位,8 位湿度小数数据位,8 位温度整数数据位,8 位温度小数数据位,8 位校验和数据位。

代码实现

Delay_us微秒延时函数

定时器延时us(hal库)-CSDN博客

DHT11.h

cs 复制代码
#ifndef __DHT11_h__
#define __DHT11_h__

#include "main.h"

#define DHT11       GPIO_PIN_7
#define GPIO_DHT11  GPIOB
#define DHT11_Input HAL_GPIO_ReadPin(GPIO_DHT11,DHT11)
#define DHT11_Low   HAL_GPIO_WritePin(GPIO_DHT11,DHT11,GPIO_PIN_RESET)
#define DHT11_High  HAL_GPIO_WritePin(GPIO_DHT11,DHT11,GPIO_PIN_SET)

void DHT11_Init(void);
void DHT11_Read_Out_Intput(uint8_t cmd);
uint8_t DHT11_Read_Byte(void);
uint8_t DHT11_Read_Huim_Temp(uint8_t *HuimH , uint8_t *HuimL , uint8_t *TempH , uint8_t *TempL);

#endif

DHT11.c

cs 复制代码
#include "DHT11.h"  // 包含 DHT11 传感器的驱动文件
#include "Delay_us.h" // 包含微秒延迟函数的头文件

uint32_t Time = 0; // 定义一个全局变量,用于记录时间

// 初始化 DHT11 传感器的 GPIO 引脚
void DHT11_Init(void)
{	 
	GPIO_InitTypeDef GPIO_InitStruct = {0}; // 创建 GPIO 初始化结构体,并将其清零

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOB_CLK_ENABLE(); // 使能 GPIOB 时钟

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIO_DHT11, DHT11, GPIO_PIN_RESET); // 将 DHT11 引脚电平设置为低电平

  /*Configure GPIO pins : PBPin PBPin */
  GPIO_InitStruct.Pin = DHT11; // 选择 DHT11 引脚
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 配置为推挽输出模式
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; // 配置为低速
  HAL_GPIO_Init(GPIO_DHT11, &GPIO_InitStruct); // 初始化 GPIO 引脚
} 

// 设置 DHT11 引脚为输入或输出模式
void DHT11_Read_Out_Intput(uint8_t cmd)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0}; // 创建 GPIO 初始化结构体,并将其清零
	if(cmd) // 如果 cmd 为真,设置为输出模式
	{
		GPIO_InitStruct.Pin = DHT11; // 选择 DHT11 引脚
		GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 配置为推挽输出模式
		GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; // 配置为低速
		HAL_GPIO_Init(GPIO_DHT11, &GPIO_InitStruct); // 初始化 GPIO 引脚
	}
	else // 如果 cmd 为假,设置为输入模式
	{
		GPIO_InitStruct.Pin = DHT11; // 选择 DHT11 引脚
		GPIO_InitStruct.Mode = GPIO_MODE_INPUT; // 配置为输入模式
		GPIO_InitStruct.Pull = GPIO_NOPULL; // 不使用上拉或下拉电阻
		HAL_GPIO_Init(GPIO_DHT11, &GPIO_InitStruct); // 初始化 GPIO 引脚
	}
}

// 读取 DHT11 传感器中的一个字节数据
uint8_t DHT11_Read_Byte(void)
{
	uint8_t Data = 0; // 初始化数据变量为 0
	
	for(uint8_t i=0; i<8; i++) // 读取 8 位数据
	{
		DHT11_Read_Out_Intput(0); // 设置为输入模式
		while((DHT11_Input == RESET) && (++Time < 1000)); // 等待引脚电平变为高,并计时
		Time = 0; // 重置计时器
		
		Data <<= 1; // 左移 1 位,为下一位数据做准备
		Delay_us(40); // 延迟 40 微秒
		if(DHT11_Input == SET) // 如果读取到的数据位为 1
		{
			Data |= 0x01; // 将数据变量的最低位设置为 1
			while((DHT11_Input == SET) && (++Time < 1000)); // 等待引脚电平变为低,并计时
		}
	}
	return Data; // 返回读取到的字节数据
}

// 读取 DHT11 传感器的湿度和温度数据
uint8_t DHT11_Read_Huim_Temp(uint8_t *HuimH , uint8_t *HuimL , uint8_t *TempH , uint8_t *TempL)
{
	uint8_t Data[5]; // 定义一个数据数组,用于存储读取到的 5 字节数据
	
	DHT11_Read_Out_Intput(1); // 设置为输出模式
	DHT11_Low; // 设置引脚电平为低,开始数据传输
	HAL_Delay(20); // 延迟 20 毫秒
	DHT11_High; // 设置引脚电平为高,结束初始化
	Delay_us(40); // 延迟 40 微秒
	
	DHT11_Read_Out_Intput(0); // 设置为输入模式
	while((DHT11_Input == RESET) && (++Time < 1000)); // 等待引脚电平变为高,并计时
	Time = 0; // 重置计时器
	while((DHT11_Input == SET) && (++Time < 1000)); // 等待引脚电平变为低,并计时
	Time = 0; // 重置计时器
	
	for(uint8_t i=0; i<5; i++) // 读取 5 字节数据
	{
		Data[i]=DHT11_Read_Byte(); // 调用读取字节函数
	}
	HAL_Delay(1); // 延迟 1 毫秒
	if(Data[0] + Data[1] + Data[2] + Data[3] == Data[4]) // 校验数据的校验和
	{
		*HuimH = Data[0]; // 将湿度高字节赋值给 HuimH
		*HuimL = Data[1]; // 将湿度低字节赋值给 HuimL
		*TempH = Data[2]; // 将温度高字节赋值给 TempH
		*TempL = Data[3]; // 将温度低字节赋值给 TempL
	}
	else 
	{
		return 0; // 校验和错误,返回 0
	}
	return 1; // 数据读取成功,返回 1
}
相关推荐
无脑学c++24 分钟前
Windows 上使用 VSCode + SDCC 开发 51 单片机完整教程
vscode·单片机·嵌入式
黎雁·泠崖1 小时前
C 语言文件操作高阶:读取结束判定 + 缓冲区原理 + 常见错误
c语言·开发语言·缓存
搁浅小泽1 小时前
什么是退磁电流?
stm32·单片机·嵌入式硬件
黎雁·泠崖1 小时前
C 语言预处理核心(上):预定义符号 + #define 常量与宏全解析
c语言·开发语言
-Excalibur-1 小时前
ARP RIP OSPF BGP DHCP以及其他计算机网络当中的通信过程和广播帧单播帧的整理
c语言·网络·python·学习·tcp/ip·算法·智能路由器
刃神太酷啦1 小时前
Linux 底层核心精讲:环境变量、命令行参数与程序地址空间全解析----《Hello Linux!》(7)
linux·运维·服务器·c语言·c++·chrome·算法
秦苒&1 小时前
【C语言】字符函数和字符串函数:字符分类函数 、字符转换函数 、 strlen 、strcpy、 strcat、strcmp的使用和模拟实现
c语言·开发语言
-Excalibur-1 小时前
关于计算机网络当中的各种计时器
java·c语言·网络·c++·笔记·python·计算机网络
枫叶丹43 小时前
【Qt开发】Qt系统(一)-> 定时器 QTimerEvent 和 QTimer
c语言·开发语言·数据库·c++·qt·系统架构
d111111111d4 小时前
STM32 GPIO输出模式配置详解:从寄存器层面理解引脚控制
笔记·stm32·单片机·嵌入式硬件·学习