DHT11温湿度模块是一种常用的传感器模块,用于测量环境的温度和湿度。它采用数字信号输出,并具有简单、易于使用的特点。
DHT11模块的工作原理是通过传感器内部的电阻式感温元件和湿度传感器来测量环境的温度和湿度。它将测量结果转换成数字信号,并通过单总线接口进行传输。
DHT11模块具有以下特点:
DHT11是一种数字湿温度传感器,采用单总线数据格式进行输入输出双向传输。其数据包由5个字节(40个位)组成,数据分为整数部分和小数部分。传输顺序是高位先出。
具体的数据格式为:8位湿度整数数据 + 8位湿度小数数据 + 8位温度整数数据 + 8位温度小数数据 + 8位校验和。其中,校验和数据是前四个字节的累加和。
总结:
主机将数据引脚拉低至少18毫秒,以启动传输。
主机将数据引脚拉高,等待DHT11响应信号。DHT11检测到引脚由低电平变为高电平后,会发送一个80微秒的低电平响应信号,表明它已准备好传输数据。
主机开始接收数据。每个数据位的传输都遵循以下规则:
数据包中的每个字节(8位)由高位先出的顺序进行传输。也就是说,最高有效位先传输,最低有效位最后传输。
传输完成后,DHT11会拉低数据引脚至少50微秒作为结束信号。
需要注意的是,由于DHT11采用单总线数据格式,传输时序的精确性对于正确读取温湿度数据至关重要。在实际使用中,应仔细遵循DHT11的时序要求,并根据具体的主机和平台进行适当的调整和延时,以确保数据的准确性和可靠性。
B12 初始为高速,高电平,C13初始为低速,高电平
1.首先给串口重定向,在主函数添加
#include
int fputc(int ch,FILE *f)
{
HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,0xFFFF);
return ch;
}
主函数调用
DH11_Task();
printf("Temp is %d\r\n", DH11_data.temp);
printf("Humi is %d\r\n", DH11_data.humidity);
2.然后在工程中新建hardware文件并添加dht11.c 和 dht11.h代码
dht11.h
#ifndef _DH11_H_
#define _DH11_H_
#include"main.h"
#define u8 unsigned char
#define u16 unsigned short
#define u32 unsigned int
//DATA IO的定义
#define DATA_SET() HAL_GPIO_WritePin(DATA_GPIO_Port, DATA_Pin, GPIO_PIN_SET)
#define DATA_RESET() HAL_GPIO_WritePin(DATA_GPIO_Port, DATA_Pin, GPIO_PIN_RESET)
#define DATA_READ() HAL_GPIO_ReadPin(DATA_GPIO_Port,DATA_Pin)
typedef struct
{
u8 Data[5];//数据存放数组
u8 index;
u8 temp;//温度
u8 humidity;//湿度
}DH11_DATA;
extern DH11_DATA DH11_data;//DH11属性封装
void DH11_Task(void);//后台轮询调用
#define DATA_Pin GPIO_PIN_12
#define DATA_GPIO_Port GPIOB
#endif
dht11.c
#include "dht11.h"
extern TIM_HandleTypeDef htim4;
static void DATA_OUTPUT(u8 flg);//DATA输出
static u8 DATA_INPUT(void);//DATA输入
static u8 DH11_Read_Byte(void);//DH11读信号
u8 DH11_Read(void);//读取DH11温度和湿度
static void Test(void);//测试程序
DH11_DATA DH11_data;
void Delay_us(uint16_t us)
{ //微秒延时
uint16_t differ = 0xffff-us-5;
__HAL_TIM_SET_COUNTER(&htim4,differ); //设定TIM1计数器起始值
HAL_TIM_Base_Start(&htim4); //启动定时器
while(differ < 0xffff-5){ //判断
differ = __HAL_TIM_GET_COUNTER(&htim4); //查询计数器的计数值
}
HAL_TIM_Base_Stop(&htim4);
}
void DATA_OUTPUT(u8 flg)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = DATA_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(DATA_GPIO_Port, &GPIO_InitStruct);
if(flg==0)
{
DATA_RESET();
}
else
{
DATA_SET();
}
}
u8 DATA_INPUT(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
u8 flg=0;
GPIO_InitStruct.Pin = DATA_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(DATA_GPIO_Port, &GPIO_InitStruct);
if(DATA_READ()==GPIO_PIN_RESET)
{
flg=0;
}
else
{
flg=1;
}
return flg;
}
u8 DH11_Read_Byte(void)
{
u8 ReadDat=0;
u8 temp=0;
u8 retry=0;
u8 i=0;
for(i=0;i<8;i++)
{
while(DATA_READ()==0&&retry<100)//等待直到DHT11输出高电平
{
Delay_us(1);
retry++;
}
retry=0;
Delay_us(40);
if(DATA_READ()==1)
{
temp=1;
}
else
{
temp=0;
}
while(DATA_READ()==1&&retry<100)//等待直到DHT11输出低电平,表示退出。本轮1bit信号接收完毕。
{
Delay_us(1);
retry++;
}
retry=0;
ReadDat<<=1;
ReadDat|=temp;
}
return ReadDat;
}
u8 DH11_Read(void)
{
u8 retry=0;
u8 i=0;
DATA_OUTPUT(0);//设置为输出模式MCU向DH11发送信号
HAL_Delay(18);
DATA_SET();
Delay_us(20);
DATA_INPUT();//设置为输入模式DH11向MCU发送信号
Delay_us(20);
if(DATA_READ()==0)
{
while(DATA_READ()==0&&retry<100)
{
Delay_us(1);
retry=0;
}
retry=0;
while(DATA_READ()==1&&retry<100)
{
Delay_us(1);
retry++;
}
retry=0;
for(i=0;i<5;i++)//Data[0]湿度, Data[2]温度。Data[1]和Data[3]分别为0和2的小数位。Data[4]用于校验。
{
DH11_data.Data[i]=DH11_Read_Byte();
}
Delay_us(50);
}
u32 sum=DH11_data.Data[0]+DH11_data.Data[1]+DH11_data.Data[2]+DH11_data.Data[3];//校验
if((sum)==DH11_data.Data[4])
{
DH11_data.humidity=DH11_data.Data[0];//获取湿度
DH11_data.temp=DH11_data.Data[2];//获取温度
return 1;
}
else
{
return 0;
}
}
void Test(void)
{
if(DH11_Read())
{
DH11_data.index++;
if(DH11_data.index>=128)
{
DH11_data.index=0;
}
}
}
void DH11_Task(void)
{
Test();
}
添加路径
运行效果
百度网盘例程
链接:https://pan.baidu.com/s/16yQQyrO-r9fntdvruWWswg 密码:kq88
代码原文 STM32cubemx配置驱动DHT11模块-CSDN博客