一、DHT11模块简介
1.DHT11模块
DHT11温湿度模块是一种常用的传感器模块,用于测量环境的温度和湿度。它采用数字信号输出,并具有简单、易于使用的特点。
DHT11模块的工作原理是通过传感器内部的电阻式感温元件和湿度传感器来测量环境的温度和湿度。它将测量结果转换成数字信号,并通过单总线接口进行传输。
DHT11模块具有以下特点:
- 温湿度测量范围:温度-20°C至60°C,湿度20%RH至90%RH。
- 精度:温度精度为±2°C,湿度精度为±5%RH。
- 低成本:DHT11模块价格相对较低,适合一般的温湿度监测应用。
- 数字信号输出:DHT11模块通过单总线协议输出数字信号,无需外部ADC等额外处理电路。
- 简单易用:DHT11模块只需要连接到微控制器或其他数字输入设备的IO引脚即可读取温湿度数值。
2.DHT11数据格式
DHT11是一种数字湿温度传感器,采用单总线数据格式进行输入输出双向传输。其数据包由5个字节(40个位)组成,数据分为整数部分和小数部分。传输顺序是高位先出。
具体的数据格式为:8位湿度整数数据 + 8位湿度小数数据 + 8位温度整数数据 + 8位温度小数数据 + 8位校验和。其中,校验和数据是前四个字节的累加和。
总结:
- 数据格式: 5个字节(40个位)
- 传输顺序: 高位先出
- 数据内容: 湿度整数、湿度小数、温度整数、温度小数以及校验和
- 校验和计算方法: 前四个字节相加
3.DHT11传输时序
- 主机将数据引脚拉低至少18毫秒,以启动传输。
- 主机将数据引脚拉高,等待DHT11响应信号。DHT11检测到引脚由低电平变为高电平后,会发送一个80微秒的低电平响应信号,表明它已准备好传输数据。
- 主机开始接收数据。每个数据位的传输都遵循以下规则:
- 逻辑0的表示:DHT11会将数据引脚保持高电平50微秒,然后再拉低50微秒。
- 逻辑1的表示:DHT11会将数据引脚保持高电平70微秒,然后再拉低50微秒。
- 数据包中的每个字节(8位)由高位先出的顺序进行传输。也就是说,最高有效位先传输,最低有效位最后传输。
- 传输完成后,DHT11会拉低数据引脚至少50微秒作为结束信号。
需要注意的是,由于DHT11采用单总线数据格式,传输时序的精确性对于正确读取温湿度数据至关重要。在实际使用中,应仔细遵循DHT11的时序要求,并根据具体的主机和平台进行适当的调整和延时,以确保数据的准确性和可靠性。
二、硬件电路
三、CubeMX配置
1.时钟设置
2.tim4定时器配置
3.gpio设置
B12 初始为高速,高电平,C13初始为低速,高电平
4.接着配置调试
5.最后打开串口1,波特率,数据位,停止位,校验位配置
6.直接生成代码
四、程序设计
1.首先给串口重定向,在主函数添加
#include <stdio.h> 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博客