十六、STM32控制DHT11采集温湿度

发布时间 2023-08-30 11:05:14作者: 稚终KINO

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 }