温湿度模块DHT11(hal库)
DHT11原理
代码实现
Delay_us微秒延时函数
定时器延时us(hal库)-CSDN博客
DHT11.h
#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
#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; // 初始化数据变量为 0for(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; // 将数据变量的最低位设置为 1while((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
}