时间记录:2024/1/29
一、DHT11引脚介绍
(1)VCC:电源引脚,3.3-5.5V
(2)DATA:数据输入输出引脚
(3)NC:保留引脚,悬空即可
(4)GND:电源地引脚
二、数据格式介绍
(1)一次完整的数据传输为40bit,高位先传
(2)40bit数据介绍:8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据+8bit校验数据,前四byte数据值相加之和等于校验值
三、通讯过程
(1)空闲状态下,数据线处于高电平
(2)MCU拉低总线发出起始信号,保持至少18ms(18-30ms),然后释放总线,将总线拉高20-40us,然后DHT11便会发出响应(拉低总线80us,然后拉高总线80us),响应完毕后开始40bit数据的传输
(3)40bit数据介绍:DHT11拉低总线50us,然后拉高总线,高电平保持时间在26-28us表示数据“0”,保持时间在70us表示数据“1”
四、示例代码
(1)头文件
#ifndef __DHT11_H__
#define __DHT11_H__
#include "stm32f10x.h"
#include "delay.h"
#include "sys.h"#define DHT11_OUT PAout(11)
#define DHT11_IN PAin(11)//初始化
void vDHT11Init(void);
//获取温湿度
u8 xDHT11Get(u8* temp,u8* humi);#endif
(2)源文件
#include "dht11.h"static u8 Byte5Data[5];//Program Size: Code=2028 RO-data=268 RW-data=40 ZI-data=1632 void vDHT11Init(void)
{//1.使能时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//2.初始化GPIOGPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);GPIO_SetBits(GPIOA,GPIO_Pin_11);Delay_Init();Delay_Ms(1000);//DHT11上电启动时间
}static void vLineOut(void)
{GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);GPIO_SetBits(GPIOA,GPIO_Pin_11);//默认高电平
}static void vLineIn(void)
{GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;//上拉输入GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);
}static void vStart(void)
{vLineOut();//启动过程DHT11_OUT=0;//拉低至少18msDelay_Ms(20);DHT11_OUT=1;//释放总线等待20-40us等待DHT11响应Delay_Us(40);vLineIn();
}static u8 xGetOneByte(void)
{u8 temp=0;for(int i=0;i<8;i++){while(!DHT11_IN);//等待50us拉低响应结束temp <<= 1;Delay_Us(40);//延时40us根据高电平时长判断0、1if(DHT11_IN){temp |= 0x01;}while(DHT11_IN);//等待高电平结束}return temp;
}u8 xDHT11Get(u8* temp,u8* humi)
{u8 crc=0;vStart();if(!DHT11_IN){while(!DHT11_IN);//等待80us拉低响应结束while(DHT11_IN);//等待80us拉高响应结束//数据接收for(int i=0;i<5;i++){Byte5Data[i]=xGetOneByte();}*temp=Byte5Data[2];*humi=Byte5Data[0];//温度湿度相加计算校验和for(int i=0;i<4;i++){crc+=Byte5Data[i];}}vLineOut();//恢复总线空闲状态if(crc == Byte5Data[4])return 0;elsereturn 1;
}