数字温湿度传感器 --- DHT11 ---- STM32F10通讯----温湿度数据采集详解

数字温湿度传感器 — DHT11 ---- 温湿度数据采集详解

引脚接口说明

  1. 建议连接线长度短于20米时用5K上拉电阻,大于20米时根据实际情况使用合适的上拉电阻 。

  2. DHT11的供电电压为 3-5.5V

  3. 传感器上电后, 要等待 1s 以越过不稳定状态在此期间无需发送任何指令。 (给传感器反应一段时间

  4. 电源引脚(VDD, GND) 之间可增加一个100nF 的电容, 用以去耦滤波
    在这里插入图片描述

通讯方式(串行接口 (单线双向))

  1. DATA 用于微处理器与 DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间4ms左右,数据分小数部分和整数部分 。

  2. 一次完整的数据传输为40bit,高位先出 。

  3. 用户MCU发送一次开始信号后,DHT11从低功耗模式转换到高速模式,等待主机开始信号结束后,DHT11发送响应信号,送出40bit的数据,并触发一次信号采集,用户可选择读取部分数据.从模式下,DHT11接收到开始信号触发一次温湿度采集,如果没有接收到主机发送开始信号,DHT11不会主动进行温湿度采集.采集数据后转换到低速模式。

    • 通讯过程。如下图
      在这里插入图片描述

    • 总线空闲状态为高电平,主机把总线拉低等待DHT11响应,主机把总线拉低必须大于18毫秒,保证DHT11能检测到起始信号。 DHT11接收到主机的开始信号后,等待主机开始信号结束,然后发送80us低电平响应信号.主机发送开始信号结束后,延时等待20-40us后, 读取DHT11的响应信号,主机发送开始信号后,可以切换到输入模式,或者输出高电平均可, 总线由上拉电阻拉高

    • 主机发送起始信号,从机响应。如下图
      在这里插入图片描述

    • 总线为低电平,说明DHT11发送响应信号,DHT11发送响应信号后,再把总线拉高80us,准备发送数据,每一bit数据都以50us低电平时隙开始,高电平的长短定了数据位是0还是1.格式见下面图示.如果读取响应信号为高电平,则DHT11没有响应,请检查线路是否连接正常.当最后一bit数据传送完毕后, DHT11拉低总线50us,随后总线由上拉电阻拉高进入空闲状态 。

    • 数据0,序列方式
      在这里插入图片描述

    • 数据1,序列方式
      在这里插入图片描述
      重要:单击查看单总线详解

DHT11.c驱动代码

#include "dht11.h"

/****************************单总线输出引脚配置*******************************/
void DHT11_IO_OUT (void){ //端口变为输出
	GPIO_InitTypeDef  GPIO_InitStructure; 	
    GPIO_InitStructure.GPIO_Pin = DHT11_IO; //选择端口号(0~15或all)                        
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //模式推挽输出     
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO接口速度(2/10/50MHz)    
	GPIO_Init(DHT11PORT, &GPIO_InitStructure);
}
/****************************单总线输入引脚配置*******************************/
void DHT11_IO_IN (void){ //端口变为输入
	GPIO_InitTypeDef  GPIO_InitStructure; 	
    GPIO_InitStructure.GPIO_Pin = DHT11_IO; //选择端口号(0~15或all)                        
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入    
	GPIO_Init(DHT11PORT, &GPIO_InitStructure);
}
/*****************************DHT11初始化(主机的开始信号)******************************/
void DHT11_RST (void){ //DHT11端口复位,发出起始信号(IO发送)
	DHT11_IO_OUT();		//单总线切换为输出模式
	GPIO_ResetBits(DHT11PORT,DHT11_IO); //拉低总线	
	Delay_ms(20); //拉低至少18ms						
	GPIO_SetBits(DHT11PORT,DHT11_IO); //拉高总线							
	Delay_us(30); //主机拉高20~40us
}
/*****************************等待DHT11回应,返回1:未检测到DHT11,返回0:成功(IO接收)******************************/
u8 Dht11_Check(void){    
    u8 retry=0;		//定义1个DHT11响应超时变量
    DHT11_IO_IN();//总线切换到输入状态	 
    while (GPIO_ReadInputDataBit(DHT11PORT,DHT11_IO)&&retry<100){//等待DHT11拉低40~80us
        retry++;
        Delay_us(1);
    }	 
/******************************如果超时返回1,否则将超时变量清零为下次准备*****************************/
    if(retry>=100)return 1; else retry=0;
    while (!GPIO_ReadInputDataBit(DHT11PORT,DHT11_IO)&&retry<100){//等待DHT11拉低后会再次拉高40~80us
        retry++;
        Delay_us(1);
    }
    if(retry>=100)return 1;	    
    return 0;
}
/******************************从DHT11读取一个位 返回值:1/0*****************************/
u8 Dht11_ReadBit(void){ 
    u8 retry=0;		//定义1个DHT11响应超时变量
    while(GPIO_ReadInputDataBit(DHT11PORT,DHT11_IO)&&retry<100){//等待变为低电平
        retry++;
        Delay_us(1);
    }
    retry=0;
    while(!GPIO_ReadInputDataBit(DHT11PORT,DHT11_IO)&&retry<100){//等待变高电平
        retry++;
        Delay_us(1);
    }
    Delay_us(40);//等待40us检测电平状态	//用于判断高低电平,即数据1或0
	/*****************************如果为低则为0,为高则为1,并且返回数据0/1******************************/
    if(GPIO_ReadInputDataBit(DHT11PORT,DHT11_IO))return 1; else return 0;		   
}
/*****************************从DHT11读取一个字节  返回值:读到的数据******************************/
u8 Dht11_ReadByte(void){  
    u8 i,dat;//定义一个循环变量和一个接收8位数据的变量
    dat=0;	//初识值为0000 0000
    for (i=0;i<8;i++){ 
        dat<<=1; 	//提前移动一次没有作用,(移动7次就行)
        dat|=Dht11_ReadBit();//0或上0为0,或上1为1
    }						    
    return dat;
}
/******************************DHT11初始化*****************************/
u8 DHT11_Init (void){	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //APB2外设时钟使能      
	DHT11_RST();//DHT11端口复位,发出起始信号
	return Dht11_Check(); //等待DHT11回应
}
/****************************读取数据,储存在指针所指的地址处*******************************/
u8 DHT11_ReadData(u8 *h){ //读取一次数据//湿度值(十进制,范围:20%~90%) ,温度值(十进制,范围:0~50°),返回值:0,正常;1,失败 
    u8 buf[5];//存放40bit数据
    u8 i;
    DHT11_RST();//DHT11端口复位,发出起始信号
    if(Dht11_Check()==0){ //等待DHT11回应
        for(i=0;i<5;i++){//读取5位数据
            buf[i]=Dht11_ReadByte(); //读出数据
        }
        if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]){	//数据校验
            *h=buf[0]; //将湿度值放入指针1
			h++;
            *h=buf[2]; //将温度值放入指针2
        }
    }
	else return 1;
    return 0;	    
}


DHT11.h驱动代码

#ifndef __DHT11_H
#define __DHT11_H	 
#include "sys.h"
#include "delay.h"

#define DHT11PORT	GPIOA	//定义IO接口
#define DHT11_IO	GPIO_Pin_15	//定义IO接口


void DHT11_IO_OUT (void);
void DHT11_IO_IN (void);
void DHT11_RST (void);
u8 Dht11_Check(void); 	   
u8 Dht11_ReadBit(void); 
u8 Dht11_ReadByte(void); 


u8 DHT11_Init (void);
u8 DHT11_ReadData(u8 *h);
		 				    
#endif

Delay_ms(1000);//初始化后的必要的延时(不得小于1秒)

  • 29
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

领悟电子界

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值