IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> DHT11温湿度传感器 -> 正文阅读

[嵌入式]DHT11温湿度传感器


前言

本文记录的温湿度传感器的学习过程。
实验平台:野火指南者stm32f103vet6
模块:DHT11温湿度传感器


一、编程前期工作

1.原理图引脚

有原理图可以知道DHT11的数据线接在板子的PE6引脚
在这里插入图片描述
编程的时候,要配置并初始化PE6。

2.工作方式

DHT11只有一条数据线与MCU连接,是单总线串行通信,系统中的数据交换、控制均由单总线完成。

设备(主机或从机)通过一个漏极开路或三态端口连至该数据线,以允许设备在不发送数据时能够释放总线,而让其它设备使用总线;单总线通常要求外接一个约4.7kΩ的上拉电阻,这样,当总线闲置时,其状态为高电平。由于它们是主从结构,只有主机呼叫从机时,从机才能应答,因此主机访问器
件都必须严格遵循单总线序列,如果出现序列混乱,器件将不响应主机。

3.数据格式

8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据+8bit校验位。

数据传送正确时校验和数据等于“8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据”所得结果的末8位。
注意:高位先出。一次传送40位数据。其中湿度小数部分为0。

4.通信过程和时序

通信过程:用户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的代码。

main.c

代码如下(示例):

#include "stm32f10x.h"   // 相当于51单片机中的  #include <reg51.h>
#include "bsp_led.h"
#include "bsp_usart.h"
#include "bsp_dht11.h"
#include "./systick/bsp_SysTick.h"

void Delay(unsigned int n) {
    unsigned int i,j;
    for(j = 0; j<5000; j++)
    {
        for(i = 0;i<n;i++);
    }
		return ;
}

int main(void) {
	DHT11_Data_TypeDef	DHT11_Data;
	SysTick_Init();		/* 初始化系统定时器 */
	USART_Config();		/* 初始化串口配置 */
	DHT11_Init();			/* 初始化DTT11的引脚 */
	
	printf("DHT11温湿度传感器实验\n\r");
	
	while(1) {
		if( DHT11_Read_TempAndHumidity(&DHT11_Data) == SUCCESS) {
			printf("读取成功!\n\r温度:%d.%d ℃, 湿度:%d.%d \n", \
			DHT11_Data.temp_int, DHT11_Data.temp_deci, DHT11_Data.humi_int, DHT11_Data.humi_deci);
		} else {
			printf("读取温湿度失败!\n");
		}
		
		Delay(5000);
	}
	
}
/*************************************END OF FILE******************************/

bsp_dht11.c

代码如下(示例):

#include "bsp_dht11.h"
#include "bsp_usart.h"

/* static函数声明 */
static void DHT11_GPIO_Config(void);
static void DHT11_Mode_Out_PP(void);
static void DHT11_Mode_IPU(void);
static uint8_t DHT11_ReadByte(void);

void DHT11_Init(void) {
	DHT11_GPIO_Config();	//输出模式

	DHT11_Dout_1;	// 一开始拉高PE6

	return ;
}

/* 配置DHT11的I/O口 为通用推挽输出模式 */
static void DHT11_GPIO_Config(void) {
	GPIO_InitTypeDef GPIO_InitStructure;

	// 打开串口GPIO的时钟
	DHT11_Dout_SCK_APBxClkCmd(DHT11_Dout_GPIO_CLK, ENABLE);

	/*选择要控制的DHT11_Dout_GPIO_PORT引脚*/	
	GPIO_InitStructure.GPIO_Pin = DHT11_Dout_GPIO_PIN;
	
	/*设置引脚模式为通用推挽输出*/
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	
	/*设置引脚速率为50MHz */   
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	
	/* 初始化GPIOE */
	GPIO_Init(DHT11_Dout_GPIO_PORT, &GPIO_InitStructure);
  
	return ;
}

static void DHT11_Mode_Out_PP(void) {
 	GPIO_InitTypeDef GPIO_InitStructure;

	 	/*选择要控制的DHT11_Dout_GPIO_PORT引脚*/															   
  	GPIO_InitStructure.GPIO_Pin = DHT11_Dout_GPIO_PIN;	

	/*设置引脚模式为通用推挽输出*/
  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   

	/*设置引脚速率为50MHz */   
  	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

	/*调用库函数,初始化DHT11_Dout_GPIO_PORT*/
  	GPIO_Init(DHT11_Dout_GPIO_PORT, &GPIO_InitStructure);	 	 
	
}

/* 配置DHT11的I/O口 为浮空输入模式 */
static void DHT11_Mode_IPU(void) {
	GPIO_InitTypeDef GPIO_InitStructure;

	// 打开串口GPIO的时钟
	DHT11_Dout_SCK_APBxClkCmd(DHT11_Dout_GPIO_CLK, ENABLE);

	GPIO_InitStructure.GPIO_Pin = DHT11_Dout_GPIO_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;					// 将DHT11的GPIO配置为浮空输入模式
	
	/* 初始化GPIOE */
	GPIO_Init(DHT11_Dout_GPIO_PORT, &GPIO_InitStructure);
  
	return ;
}




/* 从DHT11读取一个字节:高位先行 */
static uint8_t DHT11_ReadByte(void) {
	uint8_t i, dht11_onebyte_data = 0;

	/* 循环8次读取一个字节的数据 */
	for(i = 0; i < 8; i++) {
		//每1bit都需要延时50us才能开始读
		while( 0 == DHT11_Dout_IN() );

		//26~28us为0,70us为1。取50us的时候读取电平
		DHT11_DELAY_US(50);
		
		if( 1 == DHT11_Dout_IN() ) {		//如果为高电平
			dht11_onebyte_data |= (uint8_t)(1 << 0);		//置1 
			while( 1 == DHT11_Dout_IN() );		
		} else {
			dht11_onebyte_data &= (uint8_t)~(1 << 0);	//置0   
			
		}
		
		if(i == 7) {
			break;
		}
		//每读完一个bit,dht11_onebyte_data左移一位
		dht11_onebyte_data = dht11_onebyte_data << 1;
		
	}

	return dht11_onebyte_data;
}





/* 读取温湿度40bits的数据 */
uint8_t DHT11_Read_TempAndHumidity(DHT11_Data_TypeDef* DHT11_Data) {
	//总线空闲状态为高电平
	DHT11_Mode_Out_PP();
	//DHT11_Dout_1;
	
	//主机开始发送起始信号(拉低)
	DHT11_Dout_0;
	
	//主机至少延时18ms
	DHT11_DELAY_MS(18);
	
	//主机拉高20~40us
	DHT11_Dout_1;
	DHT11_DELAY_US(30);

	/*主机设为输入模式 等待DHT11发出响应信号*/ 
	DHT11_Mode_IPU();
	
	//如果DHT11发出响应信号(低电平信号)
	if( 0 == DHT11_Dout_IN() ) {
		//等待DHT11的响应信号(80us)结束,结束后,将会发出高电平
		while(DHT11_Dout_IN() == 0);
		
		//等待DHT11拉高80us结束
		while(DHT11_Dout_IN() == 1);
		
		//开始读数据 
		DHT11_Data->humi_int = DHT11_ReadByte();
		DHT11_Data->humi_deci = DHT11_ReadByte();
		DHT11_Data->temp_int = DHT11_ReadByte();
		DHT11_Data->temp_deci = DHT11_ReadByte();
		DHT11_Data->check_sum = DHT11_ReadByte();
	} 
	
	//数据传送结束时,从机拉低50us
	DHT11_DELAY_US(50);

	//GPIO设置输出模式,并拉高电平,释放总线
	DHT11_GPIO_Config();
	DHT11_Dout_1;
	
	/*检查读取的数据是否正确*/
	if(DHT11_Data->check_sum == DHT11_Data->humi_int + DHT11_Data->humi_deci + DHT11_Data->temp_int+ DHT11_Data->temp_deci) {
		return SUCCESS;	//成功读取温湿度数据则返回0
	} else {
		printf("读取温湿度数据不正确!!!\n");
		return ERROR;	//读取失败
	}
	
	
} 

/*************************************END OF FILE******************************/

bsp_dht11.h

代码如下(示例):

#ifndef __BSP_DHT11_H__
#define __BSP_DHT11_H__

#include "stm32f10x.h"
#include "./dwt_delay/core_delay.h" 

/************************** DHT11 数据类型定义********************************/
typedef struct {
	uint8_t  humi_int;		//湿度的整数部分
	uint8_t  humi_deci;	 	//湿度的小数部分
	uint8_t  temp_int;	 	//温度的整数部分
	uint8_t  temp_deci;	 	//温度的小数部分
	uint8_t  check_sum;	 	//校验和
	
} DHT11_Data_TypeDef;


/************************** 延时********************************/
#define DHT11_DELAY_US(us)  CPU_TS_Tmr_Delay_US(us)	//1us
#define DHT11_DELAY_MS(ms)  CPU_TS_Tmr_Delay_MS(ms)	//1ms

/************************** DHT11 连接引脚定义********************************/
#define      DHT11_Dout_GPIO_PORT                      GPIOE
#define      DHT11_Dout_GPIO_PIN                       GPIO_Pin_6

#define      DHT11_Dout_SCK_APBxClkCmd              	 RCC_APB2PeriphClockCmd
#define      DHT11_Dout_GPIO_CLK                       RCC_APB2Periph_GPIOE


/************************** DHT11 函数宏定义********************************/
#define      DHT11_Dout_0					GPIO_ResetBits(DHT11_Dout_GPIO_PORT, DHT11_Dout_GPIO_PIN)	//置PE6为0
#define      DHT11_Dout_1					GPIO_SetBits(DHT11_Dout_GPIO_PORT, DHT11_Dout_GPIO_PIN)		//置PE6为1
#define			 DHT11_Dout_IN()			GPIO_ReadInputDataBit(DHT11_Dout_GPIO_PORT, DHT11_Dout_GPIO_PIN)									//读取PE6的电平




/************************** 函数声明********************************/
void DHT11_Init(void);
uint8_t DHT11_Read_TempAndHumidity(DHT11_Data_TypeDef* DHT11_Data);

#endif /* __BSP_DHT11_H__ */

结果

结果如图所示:
在这里插入图片描述


总结

重点还是要学会看时序图,而且总的时序图尤为重要,先有大局观,再抓其中细节的部分。
如写完程序,对照总时序图看看,有没有哪些地方是错漏的。
在这里插入图片描述

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-03-08 22:42:39  更:2022-03-08 22:42:58 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 8:38:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码