历史上的今天
今天是:2025年08月14日(星期四)
2019年08月14日 | stm32驱动DHT11温湿度模块使用方法和问题小结
2019-08-14 来源:eefocus
最近在总结做过的几个项目,今天小结一下DHT11模块的使用。
对DHT11的使用,就是编写时序和stm32进行通信。
DHT11和stm32是通过一根线进行通信的,双方通过这根线上的电平变化来识别各种信号。
DHT11每次传输数据会输出40bit的数据,即5个字节,它们的含义如下:

每一位bit是0还是1是通过高电平的持续时间来判断的,如下两张图所示,‘0’和
‘1’都是先持续50us的低电平,而后持续一段时间高电平,‘0’的高电平会持续26-28us,‘1’的电平会持续70us,因此你在判断每位数据是’0’还是’1’时,有两种方法,一种是看持续时间,显然高电平持续时间超过28us的就是’1’;另一种方法是选取一个时间点,比如在高电平开始40us后如果仍然是高电平,那就是‘1’,我用的第二种方式,因为即使是在40us后来检查电平,对数据是’0’的情况也很好判断,因为下一位数据’0’的持续时间是50us。


代码的话我贴几个比较重要的
stm32发出的开始信号,使引脚从高电平变为低电平,低电平持续20ms后再拉高电平,高电平持续40us等待DHT11发个响应信号,注意此时引脚应设为输入模式。
//主机拉低20ms
int retry=0;
set_out_high();
delay_ms(5);
set_out_low();
delay_ms(20);
set_in_high();
delay_us(40);
等待拉低代码如下,在编写时序时要检测到电平的变化可以使用下面的方法,使用while循环去检测,可以加上一个延时超时时间,我加的是100us,如果超过100us没有拉低就出错返回。
while(((GPIOB->IDR & (1<<0))==1) && retry <100)//等待拉低
{
delay_us(1);
retry++;
}
if(retry>= 100)
{
printf("time out1rn");
retry=0;
return ;
}else{
retry = 0;
}
等待拉高如下,功能同等待拉低相似
while(((GPIOB->IDR & (1<<0))==0) && retry <100)//等待拉高
{
delay_us(1);
retry++;
}
if(retry>= 100)
{
printf("time out2rn");
retry = 0;
return ;
}else{
retry = 0;
}
读取一个字节
for(j=0;j<8;j++)
{
while(((GPIOB->IDR & (1<<0))==0) && retry <100)//等待拉高
{
delay_us(1);
retry++;
}
if(retry>= 100)
{
printf("time out4rn");
retry = 0;
return ;
}else{
retry = 0;
}
delay_us(40);
if((GPIOB->IDR & (1<<0))==0)
{
h1->humi_int &= ~(1<<(7-j));
}else{
h1->humi_int |= 1<<(7-j);
while(((GPIOB->IDR & (1<<0))==1) && retry <100)//等待拉低
{
delay_us(1);
retry++;
}
if(retry>= 100)
{
printf("time out5rn");
retry = 0;
return ;
}else{
retry = 0;
}
}
}
判断’0’还是’1’的逻辑代码上面已经说了,可以结合代码看一看。
校验和的话,我没有使用,因为数据还是狠准确地。
在实际应用时遇到个问题,我是采用循环读的,如下
while(1)
{
//清除之前的数据
h1.humi_dec=0;
h1.humi_int=0;
h1.ture_dec=0;
h1.ture_int=0;
//得到数据
humiture_get(&h1);
//打印数据
printf("humi:%d.%drn",h1.humi_int,h1.humi_dec);
printf("ture:%d.%drn",h1.ture_int,h1.ture_dec);
}
结果每次开发板复位后只有第一次能成功读取,之后每次读取都会在发出开始信号阶段就超时返回。一开始以为是时序的问题,但由于最开始可以成功读出一次数据,表明时序是可以正常工作的,之后根据数据手册的时序图又检查了一遍,发现没有写结束信号,时序图中的结束信号是由主机主动拉高的,因此我加上了主动拉高的代码,并延时500ms,但问题依旧没有解决,最后我重头到尾看了一遍数据手册发现了这个

发现了左下角的注:采样周期间隔不得低于1秒钟。
所以我在数据采样结束后主动拉高电平并延时1.5秒,成功解决问题!
史海拾趣
|
本帖最后由 jameswangsynnex 于 2015-3-3 20:01 编辑 自从西方工业革命以来,蒸汽机成为第一代推动西方整个工业行业的真正动力,科技的迅速发展至今,各行各业已经变得丰富多彩。电子产品的出现更是令现代世界更加绚烂多姿,成为装饰现代生活的重 ...… 查看全部问答> |
|
应用系统利用指纹识别技术可以分为两类,即验证(Verification)和辨识(Identification)。验证就是通过把一个现场采集到的指纹与一个己经登记的指纹进行一对一的比对(one-to-one matching),来确认身份的过程。 作为验证的前提条件,他或她的 ...… 查看全部问答> |
|
本帖最后由 paulhyde 于 2014-9-15 09:38 编辑 全国大学生电子设计竞赛自2009年起正式冠名为NEC电子杯全国大学生电子设计竞赛 全国大学生电子设计竞赛,英文简称NUEDC,是由教育部高等教育司和工业信息化部人教司(前身为信息产业部人事司)共同 ...… 查看全部问答> |
|
大家应该都有一些了解,对于无线Mesh网络。它是一种具有多跳性和传统无线性能的结合体,是一种新的无线网络。它的诞生,给我们的无线带来了新的理念。那么它具体是新在哪里呢?本文主要针对的是无线Mesh网络结构进行的具体介绍。希望通过此文,能让 ...… 查看全部问答> |
|
现在用AD9286做采样,信号20MHz至100MHz,目前使用的是手册上推荐的RF变压器做前端信号处理。麻烦各位高人指点一下:是不是有更适合我用的前端电路,谢谢!… 查看全部问答> |




