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 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 《STM32》——一线协议之DHT11温湿度采样 -> 正文阅读

[嵌入式]《STM32》——一线协议之DHT11温湿度采样

一、DHT11传感器介绍

1.1DHT11简介

DHT11温湿度传感器是一款含有已校准的数字信号输出的温湿度符合传感器,传感器包括一个电阻式感湿元件和一个NTC感温元件,并于一个高性能8位单片机相连接。像如下图这种都是内置了上拉电阻的,使用的时候不需要自己再接上拉电阻。
在这里插入图片描述

1.2DHT11工作原理

DHT11次啊用单总线通信。单总线即只有一根数据线,即为上图out引脚,主机对DHT11的数据交换和控制均由单总线完成。单总线通常要求外接一个约5.1k欧姆的上拉电阻,使得总线闲置时,其状态为高电平。由于它们是主从结构,只有主机呼叫从机时,从机才能应答,因此主机访问器件都必须严格遵循单总线序列,如果序列混乱,器件将不响应主机。其原理图如下:注意NC引脚是不接出来的。DHT11的供电电压为3~5.5V。传感器上电后,要等待1s以越过不稳定状态在此期间无需发送任何指令。电源引脚(VDD,GND)之间可增加一个100nF的电容,用以去耦滤波。

在这里插入图片描述

1.3DHT11通信时序

数据总时序

STM32单片机发送一次开始信号后,DHT11从低功耗模式转换到告诉模式,待主机开始信号结束后,DHT11发送响应信号,并发送出5个字节的采样数据,之后结束本次采集任务。
在这里插入图片描述

主机发送起始信号

DHT11的out(data)引脚连接单片机GPIO引脚,总线空闲状态是高电平,主机GPIO把总线拉低(>=18ms),以保证DHT11能检测到起始信号,继续延时等待20~40us,切换到输入模式,等待并读取DHT11响应。

从机应答信号

DHT11接收到主机的开始信号后,等待主机发送开始信号到结束,然后向主机发送80us低电平响应信号,之后DHT11再把总线拉高80us,告诉主机准备发送数据。

高低电平的表示

我们要知道的是主机和从机的通信最基本的单位是位(bit),0和1,8个位为一字节,一个字节可以表示一个字符。那如何表示数字0和1呢?在这里,每一bit数据都以50us低电平时隙开始,而高电平的长短决定了数据位是0还是1,格式见下图。如果主机读取响应信号为高电平,则说明DHT11没有响应,检查线路是否正常。当最后一bit数据传送完毕后,DHT11拉低总线50us,随后总线由上拉电阻拉高进入空闲状态。

数字0信号表示方法:50us低电平+26~28us高电平
在这里插入图片描述
数字1信号表示方法:50us低电平+70us高电平
在这里插入图片描述

数据传输

DHT11在传输数据时,一次传输4个字节温湿度值数据和1字节的数据校验。其数据格式为:1B湿度整数数据+1B湿度小数数据+1B温度整数数据+1B温度小数数据+1B校验。不过目前温湿度的小数都还没用到。
一次性完整的数据传输为40bit,高位先出:MSB,即大端字节序,高位数存于低地址。
数据传送正确时校验和数据等于“1B湿度整数数据+1B湿度小数数据+1B温度整数数据+1B温度小数数据”所得结果的末8位。

二、DHT11温湿度采样实现

2.1接口说明:

DHT11传感器的工作电压范围为3~5.5V,因此接3.3V和5V都可以,此外将DHT11的I/O口接到单片机的某个GPIO管脚的上(我这里时PA5) 。对于没有内置上拉电阻的DHT11传感器,建议连接线长度短于20米时用5k上拉电阻,大于20米时根据实际情况使用合适上拉电阻。注意:如果传感器上有引脚为S,则表示信号引脚。
在这里插入图片描述
硬件连接如下
在这里插入图片描述在这里插入图片描述

2.2编写DHT11源文件

创建DHT11温湿度传感器的驱动源文件dht11.c
在这里插入图片描述
dht11.c文件


/*
 * dht11.c
 *
 *  Created on: 2022年6月17日
 *      Author: 28980
 */

#include "dht11.h"
/*创建一个结构体,用来存引脚的组别和引脚号*/
typedef struct w1_gpio_S
{
	GPIO_TypeDef	*group;
	uint16_t		pin;
}w1_gpio_t;

/*结构体变量*/
static w1_gpio_t W1Dat =
{
	.group = GPIOA,//组别A
	.pin = GPIO_PIN_5,//引脚5,即PA5
};

//定义宏,将引脚设置为特定的输入模式,至于为什么没有封装成函数,是因为调用函数过程中的变量等数据需要进栈出栈,消耗大
#define W1DQ_Input()	\
{\
	GPIO_InitTypeDef GPIO_InitStruct = {0};\
 	GPIO_InitStruct.Pin = W1Dat.pin;\
 	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;\
 	GPIO_InitStruct.Pull = GPIO_PULLUP;\
 	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;\
 	HAL_GPIO_Init(W1Dat.group, &GPIO_InitStruct);\
}

//定义宏,将引脚设置为特定的输出模式
#define W1DQ_Output()	\
{\
	GPIO_InitTypeDef GPIO_InitStruct = {0};\
 	GPIO_InitStruct.Pin = W1Dat.pin;\
 	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;\
 	GPIO_InitStruct.Pull = GPIO_NOPULL;\
 	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;\
 	HAL_GPIO_Init(W1Dat.group, &GPIO_InitStruct);\
}

/*运用了三目运算符,如果x为1,则HAL_GPIO_WritePin的第三个参数level为GPIO_PIN_SET(1) ,否则为GPIO_PIN_RESET(0),*/
#define W1DQ_Write(x)	HAL_GPIO_WritePin(W1Dat.group, W1Dat.pin,\
		(x==1)?GPIO_PIN_SET : GPIO_PIN_RESET)
		
/*用于读取引脚的电平*/
#define W1DQ_Read()	HAL_GPIO_ReadPin(W1Dat.group, W1Dat.pin)

/*向主机发送起始信号*/
static void DHT11_StartSignal(void)
{
	W1DQ_Output();//设置引脚为输出模式

	W1DQ_Write(0);//输出20ms低电平
	HAL_Delay(20);
	
	W1DQ_Write(1);//输出30us高电平
	delay_us(30);

	W1DQ_Input();//设置引脚为输入模式
}

/*主机检测从机应答信号*/
uint8_t DHT11_RespondSignal(void)
{
	uint8_t retry = 0;//用于判断是否超市

	/*读取引脚状态,如果是高电平,则说明从机DHT11还没有发送低电平信号给主机,将一直循环,直到retry==100*/
	while(W1DQ_Read() && retry < 100)
	{
		retry++;
		delay_us(1);
	}
	
	/*retry>=100时,说明从机DHT11没有响应主机*/
	if(retry >= 100)
	{
		printf("The host receives no response signal!\r\n");
		return 1;
	}

	retry = 0;

	while(!W1DQ_Read() && retry < 100)
	{
		retry++;
		delay_us(1);
	}

	if(retry >= 100)
	{
		printf("DHT11 has not received a start signal!\r\n");
		return 1;
	}

	return 0;
}

/*读取一个位的数据,即为高电平或低电平*/
uint8_t DHT11_ReadBit(void)
{
	uint8_t retry = 0;
	
	/*如果是低电平,则跳过这个while循环*/
	while(W1DQ_Read() && (retry < 100))
	{
		retry++;
		delay_us(1);
	}

	retry = 0;
	while( !W1DQ_Read() && retry < 100)
	{
		retry++;
		delay_us(1);
	}

	delay_us(40);
	if(W1DQ_Read())
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

/*读取一个字节的数据*/
uint8_t DHT11_ReadByte(void)
{
	uint8_t i, dat;

	dat = 0;
	for(i=0; i<8; i++)
	{
		dat <<=1;//大端字节序,每循环一次左移一位,将最新的一位数据放到最右一位
		dat |= DHT11_ReadBit();
	}

	return dat;
}

/*一次采样*/
int DHT11_SampleData(float *temperature, float *humidity)
{
		uint8_t humi_H8bit;
		uint8_t humi_L8bit;
		uint8_t temp_H8bit;
		uint8_t temp_L8bit;
		uint8_t check_sum;

		if(!temperature || !humidity)
			return -1;

		DHT11_StartSignal();

		if(0 != DHT11_RespondSignal())
			return -2;

		humi_H8bit = DHT11_ReadByte();//湿度整数
		humi_L8bit = DHT11_ReadByte();//湿度小数
		temp_H8bit = DHT11_ReadByte();//温度整数
		temp_L8bit = DHT11_ReadByte();//温度小数
		check_sum  = DHT11_ReadByte();//校验和

		if((humi_H8bit + humi_L8bit + temp_H8bit + temp_L8bit) != check_sum)
			return -3;

		*humidity = (humi_H8bit*1000 + humi_L8bit)/1000;//湿度,整数+小数(保留三位小数)
		*temperature = (temp_H8bit*1000 + temp_L8bit)/1000;

		return 0;
}

dht11.h文件

/*
 * dht11.h
 *
 *  Created on: 2022年6月17日
 *      Author: 28980
 */

#ifndef INC_DHT11_H_
#define INC_DHT11_H_

#include "main.h"

extern int DHT11_SampleData(float *temperature, float *humidity);

#endif /* INC_DHT11_H_ */

main.h文件需要在main()里面添加的代码

while(1)
{
	  int flag = DHT11_SampleData(&temperature, &humidity);

	  if( flag < 0 )
	  {
	  printf("ERROR: DHT11 Sample Data failure:%d\r\n", flag);
	  }
	  else
	  {
	  printf("DHT11 Sample Temperature: %.3f	Relative Humidity: %.3f\r\n", temperature,humidity);
	  }

	  HAL_Delay(3000);
}
  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-06-25 18:19:04  更:2022-06-25 18:19:37 
 
开发: 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 0:56:11-

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