十六、STM32控制DHT11采集温湿度
1.介绍
引脚图VCC-3-5.5V,NC-悬空引脚,DATA-数据输入输出引脚
2.数据格式:
(1)一次完整的数据传输为40bit,高位先出
(2)8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据+8bit校验
3.通讯过程
空闲状态下总线处于高电平,MCU拉低总线发出起始信号,至少18ms(18-30ms)保证DHT11能够检测到起始信号,然后释放总线,由上拉电阻将总线拉高20-40us等待DHT11响应,DHT11响应完毕后便开始传送数据。
每一bit数据都是以50us低电平开始,26-28us的高电平表示数据“0”,70us的高电平表示数据“1”。
数据“0”
数据“1”
4.示例代码
.h文件
1 #ifndef __DHT11_H__ 2 #define __DHT11_H__ 3 #include "stm32f10x.h" 4 #include "delay.h" 5 #include "sys.h" 6 7 #define DHT11_OUT PAout(11) //位带操作端口 8 #define DHT11_IN PAin(11) 9 10 //初始化 11 void DHT11_Init(void); 12 //获取温湿度 13 u8 DHT11_Get(u8* temp,u8* humi); 14 15 #endif
.c文件
1 #include "dht11.h" 2 3 static u8 Data[5]; //40bit数据缓存 4 5 void DHT11_Init(void) 6 { 7 //1.使能时钟 8 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); 9 10 //2.初始化GPIO 11 GPIO_InitTypeDef GPIO_InitStruct; 12 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11; 13 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; 14 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; 15 GPIO_Init(GPIOA,&GPIO_InitStruct); 16 17 GPIO_SetBits(GPIOA,GPIO_Pin_11); 18 19 Delay_Init(); 20 Delay_Ms(1000); 21 } 22 23 static void LineOut(void) 24 { 25 GPIO_InitTypeDef GPIO_InitStruct; 26 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11; 27 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出 28 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; 29 GPIO_Init(GPIOA,&GPIO_InitStruct); 30 } 31 32 static void LineIn(void) 33 { 34 GPIO_InitTypeDef GPIO_InitStruct; 35 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11; 36 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;//上拉输入 37 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; 38 GPIO_Init(GPIOA,&GPIO_InitStruct); 39 } 40 41 static void Start(void) 42 { 43 LineOut(); 44 //启动过程 45 DHT11_OUT=0;//拉低至少18ms 46 Delay_Ms(20); 47 DHT11_OUT=1;//释放总线等待20-40us等待DHT11响应 48 Delay_Us(40); 49 LineIn(); 50 } 51 52 static u8 GetByte(void) //获取1字节数据 53 { 54 u8 temp=0; 55 for(int i=0;i<8;i++){ 56 while(!DHT11_IN);//等待50us拉低响应结束 57 temp <<= 1; 58 Delay_Us(40);//延时40us根据高电平时长判断0、1 59 if(DHT11_IN){ 60 temp |= 0x01; 61 } 62 while(DHT11_IN);//等待高电平结束 63 } 64 return temp; 65 } 66 67 u8 DHT11_Get(u8* temp,u8* humi) 68 { 69 u8 temps=0; 70 Start(); 71 if(!DHT11_IN){ 72 while(!DHT11_IN);//等待80us拉低响应结束 73 while(DHT11_IN);//等待80us拉高响应结束 74 75 //数据接收 76 for(int i=0;i<5;i++){ 77 Data[i]=GetByte(); 78 } 79 80 *temp=Data[2]; 81 *humi=Data[0]; 82 83 //温度湿度相加计算校验和 84 for(int i=0;i<4;i++){ 85 temps+=Data[i]; 86 } 87 } 88 if(temps == Data[4]) 89 return 0; 90 else 91 return 1; 92 }