STM32
直播中

独当一面

11年用户 877经验值
擅长:可编程逻辑
私信 关注
[问答]

stm32与DHT11模块建立通讯的过程是怎样的

STM32与DHT11模块建立通讯的过程是怎样的?
stm32单片机如何从DHT11获取到温湿度的呢?

回帖(1)

张楠

2021-12-15 13:44:31
stm32获取DHT11模块温湿度数据原理解析

stm32单片机如何从DHT11获取到温湿度的呢?
首先可以通过DHT11手册了解一下DHT11模块,掌握该温湿度模块的通讯过程




简单分析stm32与模块建立通讯的过程:通过高低电平的持续时间和切换来控制模块开始采集和传输数据。
首先了解如何控制该模块,分析时序图:





假设连接该模块的引脚为A,那么与模块建立通讯需按照一下步骤:
1.A为输出模式并且输出低电平持续大于等于18ms(根据图中主机至少拉低18ms)
2.A输出高电平持续20-40μs(图示主机拉高20-40μs)
3.A改变为输入模式并且接收到DHT响应信号80μs(图中DHT响应信号80μs)
4.A接收到高电平持续80μs,为DHT11发送的响应信号(图中DHT拉高80μs)
与DHT11模块建立通讯完成。
  接下来主要解析如何接收DHT11温湿度模块返回的温湿度数据
阅读DTH11手册得知,该模块温湿度数据传输为40bit,高位先出,传输格式如下:
8bit湿度整数数据+8bit湿度小数数据
+8bi温度整数数据+8bit温度小数数据
+8bit校验和
那么如何传输这40bit的数据呢?
建立通讯后,模块进入高速模式,并且触发一次数据采集,送出40bit的数据
40bit数据以二进制的形式通过波形传播
该模块会返回两种波形,一种波形代表数字 0 ,另一种代表数字 1 ,一共返回 40 个波形,每个波形代表一位二进制数( 0 或 1 ),每 8 个波形为一组,一共五组,每一组组成一个 8 位的二进制数分别代表湿度整数部分、小数部分 和 温度整数部分、小数部分,最后是校验和
接下来看下返回的两种波形
图一,表示数字 0,图二表示数字 1 ,如下图所示
  图一:





  图二:




  对原理有一定的了解之后
就可以根据温湿度模块输出的波形进行解码得到温湿度数据
初始化配置代码就不一一列出了
主要编写的是如何对模块返回的波形进行解码,最后得到温湿度数据
经过引脚的高低电平和输入输出模式转换后
模块返回波形,以下为解码波形的核心代码(仅适用于理解)
假设PG9引脚与该模块连接,完成通讯后处于输入模式
ui


uint8_t p[5];                //定义一个数组用于存储温湿度数据
uint32_t t=0;                //定义变量t用于超时处理的时间计算
int32_t i=0,j=0;        //定义变量 i j 用于逻辑预算
uint8_t d=0;                //定义变量 d 用于波形转二进制数的解码运算
uint8_t check_sum=0;//用于数据检验




//接收五个字节
for(j=0; j<5; j++)
{
        d=0;
        //每个字节由八位二进制数字组成
        for(i=7; i>=0; i--)
        {
                //测量低电平持续的时间,添加超时处理
                t=0;
                while(PGin(9)==0)
                {
                        t++;
                        delay_us(1);       
                        //需编写延时函数,延时100μs                       
                        if(t >=100)  
                        {
                                return -1;
                        }                          
                }       
                                       
                //延时40us
                delay_us(40);
               
                //判断是否由高电平产生
                if(PGin(9))
                {
                        d|=1<                         //测量高电平持续的时间,添加超时处理
                        t=0;
                        while(PGin(9))
                        {
                                t++;
                                delay_us(1);       
                                if(t >=100)
                                {
                                        return -2;
                                }                  
                        }               
                }               
        }
        p[j]=d;
}


//延时100us,通信结束
delay_us(100);


//进行数据校验
check_sum=p[0]+p[1]+p[2]+p[3];
举报

更多回帖

发帖
×
20
完善资料,
赚取积分