DHT11--传输协议之始

目录

DHT11简介

DHT11使用

查看引脚编号

通讯过程

代码

实验总结

时序问题

协议优化


DHT11简介

这是一款数字温湿度传感器,可以同时测量温度和湿度,传输接口是以数字信号输出的方式进行。实物图和原理图如下:

由图可知,DHT11有四根引脚,一根接电源,一根接地,一根传输数据(单线双向),一根作为保护电路。

DHT11使用

查看引脚编号

通讯过程

数据格式

8bit湿度整数数据+8bit湿度小数数据 +8bit温度整数数据+8bit温度小数数据 +8bit校验和 。数据传送正确时校验和数据等于“8bit湿度整数数据+8bit湿度小数数据 +8bit温度整数数据+8bit温度小数数据”所得结果的末8位。

信号格式

刚开始,数据线为输出模式,用户必须主动发信号,等到DHT响应以后,转输出模式为输入模式,DHT开始传输数据

        总线空闲状态为高电平,主机把总线拉低等待DHT1 1响应,主机把总线拉低必 须大于18毫秒,保证DHT11能检测到起始信号。

        DHT11接收到主机的开始信号后, 等待主机开始信号结束,然后发送80us低电平响应信号.主机发送开始信号结束 后,延时等待20-40us后, 读取DHT11的响应信号,主机发送开始信号后,可以切换 到输入模式,或者输出高电平均可, 总线由上拉电阻拉高。

数据传输

数据0为高电平26-28us、数据1为高电平80us,以50us为间隔将数据隔离开,其真实过程中会有一丢丢误差。

代码

//Dht11.c

#include "stm32f4xx.h"                  // Device header
#include "BitBand.h"             // Component selection
#include "delay.h"
#include "stdio.h"
void Dht11_Init()
{
	//PG9  
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG,ENABLE);
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_OUT;
	GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;//协议都配推挽
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;
	GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP;
	GPIO_InitStruct.GPIO_Speed=GPIO_High_Speed;
	GPIO_Init(GPIOG,&GPIO_InitStruct);
}
void Dht11_Run()
{
	uint32_t time=0;
	uint32_t i=0;
	uint32_t j=0;
	uint32_t data[5]={0};
	//更改GPIO引脚为输出模式
		GPIO_InitTypeDef GPIO_InitStruct;
	//参数初始化
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_OUT;
	GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;//协议都配推挽
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;
	GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP;
	GPIO_InitStruct.GPIO_Speed=GPIO_High_Speed;
	GPIO_Init(GPIOG,&GPIO_InitStruct);
	//要告诉DHT11我要数据
	PGout(9)=0;//拉低电平
	delay_ms(20);//为了发送一个大于18us的低电平信号
	PGout(9)=1;//拉高电平
	
	delay_us(30);//协议规定,发送信号后续需要等20-40us,我们取中间30us
	
	//进入数据获取阶段
	//更改GPIO引脚为输入模式
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN;
	GPIO_Init(GPIOG,&GPIO_InitStruct);
	//等待回响信号,说明DHT11已经拿到了数据,准备发给你,看你还在不在?
	time=0;
	while(PGin(9)==1)//阻塞等待低电平到来,
	{
		delay_us(1);
		time++;
		if(time>=1000000)//排除没有收到发送信号情况
		{
			printf("回响信号超时");
		}
	}		
	time=0;
	while(PGin(9)==0)//协议规定需要80us的低电平
	{
		delay_us(1);
		time++;
		if(time>=100)
		{
			printf("回响信号的低电平超时\n");
		}
	}
	time=0;
	while(PGin(9)==1)//协议规定需要80us的高电平
	{
		delay_us(1);
		time++;
		if(time>=100)
		{
			printf("回响信号的高电平超时\n");
		}
	}
///?????????????此处牵扯时序问题
	//有效数据获取
	for(i=0;i<5;i++)
	{
		data[i]=0;
		for(j=0;j<8;j++)
		{
			while(PGin(9)==0);//度过间隔信号
			delay_us(40);
			if(PGin(9)==1)
			{
				data[i] |= 1<<(7-j);
				while(PGin(9)==1);
			}
		}
	}
	printf("data = %d,%d,%d,%d\n",data[0],data[1],data[2],data[3]);
}

实验总结

时序问题

    由于DHT11数据传输速度都在us级别,我们测量过程中必须十分精确,而且要考虑时序的问题,我在实验过程中为了方便查错,写了很多printf函数,结果发生了数据无法输出的错误。

    最后经过不断的测验和分析,发现了是由于多打印了一个printf而拖慢了整个数据传输的监测过程,在监测输入的数据前,我的printf打印时间超过了数据的发送时间,致使最后数据已经传输完毕我却才开始监测的错误。

协议优化

DHT11的数据传输其实就是规定了一个协议:发送获取数据信号、 DHT回响信号、间隔时间、数据传输信号(0是30us左右、1是80us左右)

这些紫色字体都是DHT11传输数据时约定好的,但是此处还存在一些可优化部分:01数据的传输是us定值,虽然已经很快了,但是当数据量达到一定大的时候,就会显得有些慢,想要优化,但是协议规定的数据传输方式又无法改变。

所以我们可以改变一点数据传输的方式,不再以us时间来做为信号,而是两个同步的电信号之间的高低电平规定来传输,例如IIC协议。

  • 16
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值