时间记录: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.初始化GPIO 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); 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); } 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;//拉低至少18ms Delay_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、1 if(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]; } } if(crc == Byte5Data[4]) return 0; else return 1; }