皇冠新体育APP

IT技术之家

stm32-DHT11原理及代码解读_dht11与stm32_嵌入式小趴菜学习记录

分享时光:2023-08-24 10:29:48 嵌入式 119次 标签:单片机 stm32 嵌入式硬件
DHT11,原理及源码分析。...

目录

一、根本专业知识 1.工作:温相对湿度论文检测 2.应用范围之内 3.硬件软件电源电路进行连接 二、框架代码怎么用工作原理分析一下 1.地基内容 1.单数据总线说 2.单数据信息总线传送数据信息数据信息位表述 3.参数版式 4.检验五位数据举例 2.代碼数据分析 1.数值时序图 2.数据报告视频传输流程

一、基础知识

1.功能:温湿度检测

????????检测的条件环境室内湿度:环境室内湿度:5-95%RH????????精准度:(±5)%RH ? ? ? ? ? ? ? ? ? ? ? ? ? 高温:-20-60℃? ? ? ? 高精准度:(±2)℃

2.应用范围

????????暖通开空调、祛湿器、占农业的大部分、冷链运输仓促、验测及验测主设备、交易品、客车、主动调控、数据库纪要器、气 象站、家具家电、温度相对湿度设定器、医用、另一有关于温度相对湿度验测调控。

3.硬件电路连接

????????1.VDD 供电系统 3.3~5.5V DC ????????2.DATA 串行数据显示,单系统总线 ????????3.NC 空脚 ????????4.GND 接地极,电源适配器负极

?注意点:

????????1. 意见建议接电源长短短于 5m 时用 4.7K 上拉内阻,不小于 5m 时选择事实前提下降上拉电 阻的阻值。 ????????2. 适用 3.3V 工作电压用电局时连入线一定要短,布线延长会使得感应器器用电局不足之处,从而造成检测差值。 ????????3. 每回读出的温湿球温度参数是前一个次测量方法的結果,欲调用实时公交动态信息,需陆续性识别硬盘 2 次,但不提议陆续性很多次 识别硬盘感应器器,每回识别硬盘感应器器时间不低于 2 秒就能刷快合理的动态信息。 4. 电的部分假如起伏,会影晌到室内平均温度。如动用面板开关电纹波过大,室内平均温度会有闪动。

二、底层代码原理分析

1.基础知识

1.单总线说明

????????DHT11 元器件封装主要包括创新的单体统体统数据总线通信设备。单体统体统数据总线即唯有每根统计数据显示线,体统中的统计数据显示相互交换、操纵均由单体统体统数据总线 达成。这句话是主从空间结构,唯有服务器拨通从机时,从机就能回话。

2.单总线传送数据位定义

????????DATA 用于微处理器与 DHT11 之间的通讯和同步,采用单总线数据格式,一次传送 40 位数据,高位先出

3.数据格式

????????8bit 干内部含水率整数统计数值分析文件 + 8bit 干内部含水率小数统计数值分析文件 + 8bit 摄氏度整数统计数值分析文件 + 8bit 摄氏度小数统计数值分析文件 + 8bit 验校位。 ????????注:之中对环境湿度的小数部件为 0。

4.校验位数据定义

????????“8bit 绝对干湿度整数数值 + 8bit 绝对干湿度小数数值 + 8bit 高温整数数值 + 8bit 高温小数数值”8bit 验校位相当于 所有结论的末 8 位

2.代码分析

1.数据时序图

????????用户数虚拟电脑主机(MCU)发射两次开端预警后,DHT11 从低输出功率摸式改换到高速公路摸式,待虚拟电脑主机开端预警收尾 后,DHT11 发射回复预警,送来 40bit 的数据表格,并重置两次信采样。预警发射图甲表达。

?????????注:主机从 DHT11 读取的温湿度数据总是前一次的测量值,如两次测间隔时间很长,请连续读两次以 第二次获得的值为实时温湿度值。

2.数据传输步骤

???????????步骤一二三准备步骤即初始化。步骤四发送数据。

步骤一

????????DHT11 上电后(DHT11 上电后要等待 1S 以越过不稳定状态在此期间不能发送任何指令),测试环境 温湿度数据,并记录数据,同时 DHT11 的 DATA 数据线由上拉电阻拉高一直保持高电平;此时 DHT11 的 DATA 引脚处于输入状态,时刻检测外部信号。???????

?步骤二:

????????上图内冷水机发送给的信号:

????????微处理器的 I/O 设置为输出同时输出低电平,且低电平保持时间不能小于 18ms(最大不得超过 30ms), 然后微处理器的 I/O 设置为输入状态,由于上拉电阻,微处理器的 I/O 即 DHT11 的 DATA 数据线也随之变 ,等待 DHT11 作出回答信号,发送信号如图所示:

????????由此得到代码:

????????DHT11_IO_OUT();设置为引脚输出模式的函数,写个函数(简单)或直接宏定义寄存器操作(简洁);DHT11_IO_IN()同理;

????????DHT11_DQ_OUT();即引脚输出高电平,可以用位带操作宏定义一番;DHT11_DQ_IN();同理;

void DHT11_Rst(void)	   
{                 
	DHT11_IO_OUT(); 	//SET OUTPUT
    DHT11_DQ_OUT=0; 	//拉低DQ
    delay_ms(20);    	//拉低至少18ms
    DHT11_DQ_OUT=1; 	//DQ=1 
	delay_us(30);     	//主机拉高20~40us
    DHT11_IO_IN();
?}

步骤三:

????????DHT11 的 DATA 引脚检测到外部信号有低电平时,等待外部信号低电平结束,延迟后 DHT11 的 DATA 引脚处于输出状态,输出 83 微秒的低电平作为应答信号紧接着输出 87 微秒的高电平通知外设准备接 收数据,微处理器的 I/O 此时处于输入状态,检测到 I/O 有低电平(DHT11 回应信号)后,等待 87 微秒 的高电平后的数据接收,发送信号如 图所示:

?????????DHT11输出,主机接收所以配置输入模式。

????????由此得到代码:

????????两个while循环一个检测低电平一个检测高电平。retry其实就是高低电平时间。

//等待DHT11的回应
//返回1:未检测到DHT11的存在
//返回0:存在
u8 DHT11_Check(void) 	   
{   
	u8 retry=0;
	DHT11_IO_IN();	 
    while (DHT11_DQ_IN&&retry<100)//DHT11会拉低
	{
		retry++;
		delay_us(1);
	};	 
	if(retry>=100)return 1;
	else retry=0;
    while (!DHT11_DQ_IN&&retry<100)//DHT11拉低后会再次拉高
	{
		retry++;
		delay_us(1);
	};
	if(retry>=100)return 1;	    
	return 0;
}

步骤四:

????????由 DHT11 的 DATA 引脚的输出 40 五数字据,微整理器要根据 I/O 电平的变现吸收 40 五数字据,五数字据“0” 的格局为: 54 微秒的低电静谧 23-27 微秒的高电平,五数字据“1”的格局为: 54 微秒的低电平加 68-74 微秒的高电平。五数字据“0”、“1”格局数据信息就像文中随时

????????完成比对收获0,1有差异位于于高底电平时光

????????所以我们先等度过低电平,高电平到来然后延时40us,此时如果他是低电平,那接收到的数据就是0,如果是高电平那他就是1。

//从DHT11读取一个位
//返回值:1/0
u8 DHT11_Read_Bit(void) 			 
{
 	u8 retry=0;
	while(DHT11_DQ_IN)//等待变为低电平
	while(!DHT11_DQ_IN)//等待成为高电平
	delay_us(40);//等待40us
	if(DHT11_DQ_IN)
        return 1;
	else 
        return 0;		   
}

????????根据前文:“一次传送 40 位数据,高位先出。”我们优化代码:

u8 DHT11_Read_Byte(void)
{
    u8 dat1,dat2=0;
    for(data1=0x80;data1!=0;data1>>1)
    {

        if(DHT11_Read_Bit())
           data2|=data1;
         else
            data2&=~data1;

    }  
    return data2;  
}

步骤五:结束信号

????????DHT11 的 DATA 引脚输出 40 位数据后,继续输出低电平 54 微秒后转为输入状态,由于上拉电阻随 之变为高电平。但 DHT11 内部重测环境温湿度数据,并记录数据,等待外部信号的到来。

????????按照本文校检位格局:“8bit 绝对温湿度整数大的统计资料显示 + 8bit 绝对温湿度小数大的统计资料显示 + 8bit 温湿度整数大的统计资料显示 + 8bit 温湿度小数大的统计资料显示”8bit 校检位约等于 增值税成果的末 8 位。

????????得出代码

u8 DHT11_Read_Data(u8 *temp,u8 *humi)    
{        
 	u8 buf[5];
	u8 i;
	DHT11_Rst();
	if(DHT11_Check()==0)
	{
		for(i=0;i<5;i++)//读取40位数据
		{
			buf[i]=DHT11_Read_Byte();
		}
		if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
		{
			*humi=buf[0];
			*temp=buf[2];
		}
	}else return 1;
	return 0;	    
}

????????我们最终顺其自然的得到主函数

int main(void)
{
		u8 temper;  	    
		u8 humi;
		u8 temp;
		delay_init();
		DHT11_Init();
        oled_init();
		while(1)			
		{
			temp = DHT11_Read_Data(&temper,&humi);
			if(temp ==0)
			{
				OLED_ShowNum(10,10,humi,5,16);
                OLED_ShowNum(10,30,temper,5,16);
			}
					
		};
}