【STM32单片机+DHT11温度传感器】快速上手,适用于多种型号芯片

提示:DHT11温度传感器是配合着stm32c8t6


一、DHT11基本了解

1.基本信息

DHT11 数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器,简单的来讲就是一个温湿度传感器。可以用来读取环境中的温湿度。

它精度比较低,其温度测量范围为 0~ 50℃,误差在±2℃;湿度的测量范围为 20%~90%RH(Relative Humidity 相对湿度—指空气中水汽压与饱和水汽压的百分比),误差在±5%RH。

在这里插入图片描述

想要具体了解原理的朋友可以自行在网上查找,或者移步至模块数据手册
链接: 戳我(因为在这里下载文件要会员,使用在这里进入后自行下载。)

2.引脚了解

在这里插入图片描述

若要了解更多其他关于dht11的信息,可以移步至其他博客上,他们都讲解的非常详细,这里只是为了快速使用上手这个模块而写的文章。

二、开始上手

1.接线

如图所示,图中2号线接到单片机的某个IO口上,其他按照图示连接(3号线不用连接)

在这里插入图片描述

2.关键部分代码

看过我上一篇文章(到上一篇文章戳这里)的应该知道,我是看着江科大的视频来学习32的,所以有的白嫖的代码还是来自于他的视频,例如oled显示屏代码。
江科大的视频提供的oled显示屏代码可以直接使用,和原子哥提供的相比还是比较简单的。我们利用显示屏就可以将温湿度信息显示出来,当然也可以通过串口发送到上位机来显示。
这里的代码我也是参考的别人的,使用方法大概是,在keil里面新建两个文件夹,一个.h一个.c文件,将两段代码复制过去,最后直接在主函数里面调用即可。总体来说还是比较简单。
如果要修改引脚的话,在h文件里面的 “DHT11 连接引脚定义” 里面修改即可。
代码如下:

DHT11.c代码
#include "DHT_11.h"
#include "Delay.h" 
#include "stm32f10x.h"                  // Device header

uint8_t  humi_int;		//湿度的整数部分
uint8_t  humi_deci;	 	//湿度的小数部分
uint8_t  temp_int;	 	//温度的整数部分
uint8_t  temp_deci;	 	//温度的小数部分
uint8_t  check_sum;	 	//校验和
#define DHT11_DELAY_US(us)  Delay_us(us)
#define DHT11_DELAY_MS(ms)  Delay_ms(ms)

static void  DHT11_Mode_IPU  ( void );
static void  DHT11_Mode_Out_PP ( void );
static uint8_t DHT11_ReadByte(void);

//初始化dht11输出引脚
void DHT11_Init ( void )
{
	GPIO_InitTypeDef GPIO_InitStructure; //定义结构体
	
	RCC_APB2PeriphClockCmd( DHT11_Dout_GPIO_CLK, ENABLE );//开启外设时钟	 															   
  	GPIO_InitStructure.GPIO_Pin = DHT11_Dout_GPIO_PIN;//引脚
  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出    
  	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度
	
  	GPIO_Init ( DHT11_Dout_GPIO_PORT, &GPIO_InitStructure );/*调用库函数,初始化DHT11_Dout_GPIO_PORT*/		  
	DHT11_Dout_1;  // 初始状态DHT11为高电平
}

//配置引脚为上拉输入
static void DHT11_Mode_IPU(void)
{
 	  GPIO_InitTypeDef GPIO_InitStructure;//调用并定义库函数结构体
	
	  GPIO_InitStructure.GPIO_Pin = DHT11_Dout_GPIO_PIN;//选择引脚
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//设置引脚模式为上拉输入模式

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

//配置引脚为推挽输出模式
static void DHT11_Mode_Out_PP(void)
{
 	GPIO_InitTypeDef GPIO_InitStructure;//调用并定义库函数结构体
															   
  	GPIO_InitStructure.GPIO_Pin = DHT11_Dout_GPIO_PIN;//选择引脚	
  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//设置引脚模式为通用推挽输出
  	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度

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

//读取一个字节,高位先行
static uint8_t DHT11_ReadByte(void)
{
	uint8_t i, temp=0;//temp用来存储数据
	for(i=0;i<8;i++)    
	{	 
		while(DHT11_Dout_IN()==Bit_RESET);//每bit以50us低电平标置开始,轮询直到从机发出 的50us 低电平 结束 

		/*DHT11 以26~28us的高电平表示“0”,以70us高电平表示“1”,
		 通过检测 x us后的电平即可区别这两个状 ,x 即下面的延时  */
		DHT11_DELAY_US(40); //延时x us 这个延时需要大于数据0持续的时间即可	   	  

		if(DHT11_Dout_IN()==1)//x us后仍为高电平表示数据“1” 
		{
			while(DHT11_Dout_IN()==1);// 等待数据1的高电平结束 

			temp|=(uint8_t)(0x01<<(7-i));  //把第7-i位置1
		}
		else	 // x us后为低电平表示数据“0”
		{			   
			temp&=(uint8_t)~(0x01<<(7-i)); //把第7-i位置0
		}
	}
	return temp;
}


/*
 * 一次完整的数据传输为40bit,高位先出
 * 8bit 湿度整数 + 8bit 湿度小数 + 8bit 温度整数 + 8bit 温度小数 + 8bit 校验和 
 */
uint8_t dht11_read(DHT11_Data_TypeDef *DHT11_Data)
{  	
	DHT11_Mode_Out_PP();//主机设为输出模式
	DHT11_Dout_0;//主机拉低
	DHT11_DELAY_MS(18);//延时18ms
	DHT11_Dout_1; //总线拉高 主机延时30us
	DHT11_DELAY_US(30);//延时30us 
	DHT11_Mode_IPU();//主机设为输入模式 判断从机响应信号

	//判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行   
	if(DHT11_Dout_IN()==Bit_RESET)     
	{
		/*轮询直到从机发出 的80us 低电平 响应信号结束*/  
		while(DHT11_Dout_IN()==Bit_RESET);

		/*轮询直到从机发出的 80us 高电平 标置信号结束*/
		while(DHT11_Dout_IN()==Bit_SET);
		
		/*开始接收数据*/   
		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();//校验和
		
		DHT11_Mode_Out_PP();//读取结束,引脚改为输出模式
		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;
		else 
			return ERROR;
	}
	else
		return SUCCESS;
}
DHT11.h代码
#ifndef __DHT_11_H
#define	__DHT_11_H
#include "stm32f10x.h"
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;

/************************** DHT11 连接引脚定义********************************/
#define      DHT11_Dout_SCK_APBxClock_FUN              RCC_APB2PeriphClockCmd
#define      DHT11_Dout_GPIO_CLK                       RCC_APB2Periph_GPIOA
//在这里自行更改引脚即可
#define      DHT11_Dout_GPIO_PORT                      GPIOA
#define      DHT11_Dout_GPIO_PIN                       GPIO_Pin_0
/************************** DHT11 函数宏定义********************************/
#define      DHT11_Dout_0	        GPIO_ResetBits ( DHT11_Dout_GPIO_PORT, DHT11_Dout_GPIO_PIN ) //输出低电平
#define      DHT11_Dout_1	        GPIO_SetBits ( DHT11_Dout_GPIO_PORT, DHT11_Dout_GPIO_PIN ) //输出高电平
#define      DHT11_Dout_IN()	    GPIO_ReadInputDataBit ( DHT11_Dout_GPIO_PORT, DHT11_Dout_GPIO_PIN )//读取引脚电平 
/************************** DHT11 函数声明 ********************************/
void DHT11_Init(void );
uint8_t dht11_read(DHT11_Data_TypeDef *DHT11_Data);
#endif 

main.c
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "DHT_11.h"

char temp1,temp2,humi1,humi2;
DHT11_Data_TypeDef DHT11_Data;
int main(void)
{
	OLED_Init();
	DHT11_Init ();
	OLED_ShowString(2,1,"Temp:");
	OLED_ShowChar(2,8,'.');
	OLED_ShowString(3,1,"Humi:");
	OLED_ShowChar(3,8,'.');
	OLED_ShowString(3,12,"%RH");
	while(1)
	{	
		temp1=DHT11_Data.temp_int;
		temp2=DHT11_Data.temp_deci;
		humi1=DHT11_Data.humi_int;
		humi2=DHT11_Data.humi_deci;	
		if(dht11_read (& DHT11_Data) == SUCCESS)
		{	
			OLED_ShowString(1,5,"SUCCESS");
			OLED_ShowNum(2,6,temp1,2);
			OLED_ShowNum(2,9,temp2,2);
			OLED_ShowNum(3,6,humi1,2);
			OLED_ShowNum(3,9,humi2,2);
		}			
		else
		{
			printf("Read DHT11 ERROR!\r\n");
			OLED_ShowString(1,5," ERROR ");
		}
		Delay_ms(200);
	}
}

总结

对于dht11的使用主要在于通信协议的编写,不过也不是特别难,只需要按照时序图来编辑代码即可。这里提供的代码可以直接去使用,这里留有接口,非常方便。

  • 10
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
### 回答1: 基于STM32单片机DHT11温湿度传感器OLED显示程序可以实现以下功能: 首先,需要连接STM32单片机DHT11温湿度传感器以及OLED显示屏。 然后,编写程序读取DHT11传感器的温湿度数值。可以通过引脚连接和使用相应的库函数来实现数据读取。 接下来,使用OLED显示屏库函数将温湿度数据显示在OLED屏幕上。可以在屏幕上创建相应的文本框或者图标来显示温湿度值。可以使用合适的库函数调用,将温湿度数据转换为字符串格式并在屏幕上显示出来。 同时,可以设计一个定时器来定时更新温湿度数据的显示。可以设置一个适当的时间间隔来实现数据的定时更新,并使用相应的库函数来控制定时器的启动和停止。 此外,为了增加用户体验,还可以添加一些额外的功能,比如在某个温湿度阈值超过一定值时,显示警告信息或者触发报警器等。 最后,将编写好的程序下载到STM32单片机中进行测试。通过观察OLED显示屏是否能够正确显示温湿度数值,以及数据是否能够定时更新,来验证程序的正确性。 总体来说,基于STM32单片机DHT11温湿度传感器OLED显示程序需要通过串口和I2C总线连接硬件设备,并使用相应的库函数来读取传感器数据和控制OLED显示屏,以实现温湿度数据的实时显示。 ### 回答2: 基于STM32单片机DHT11温湿度传感器和OLED显示程序可以实现如下功能。 首先,我们需要连接DHT11温湿度传感器到STM32单片机的GPIO口。DHT11传感器的信号线接到单片机的输入GPIO口,供电线接到单片机的5V电源口,接地线接到单片机的地线。 接着,需要通过STM32的GPIO口读取DHT11传感器发送的温湿度数据。通过向DHT11传感器发送一个读取请求信号,然后在适当的时间间隔后读取传感器发送的数据,包括温度和湿度值。 接下来,我们需要将读取到的温湿度数据通过I2C或SPI协议发送到连接的OLED显示屏上显示出来。首先,需要初始化I2C或SPI接口,然后将温湿度数据传送到OLED显示屏的适当位置进行显示。可以使用相应的OLED显示屏库函数来帮助实现这一功能。 此外,为了更好地呈现温湿度数据,还可以添加一些额外的功能。例如,可以设置一个温度和湿度的阈值,当温度或湿度超过阈值时,通过OLED显示屏进行警告或提示。还可以添加一个实时钟表显示当前的时间,并将当前温湿度数据显示在时钟表上。 需要注意的是,在编写程序时,应根据单片机型号和开发环境选择相应的库函数和配置参数,确保程序正确运行。 以上是基于STM32单片机DHT11温湿度传感器和OLED显示程序的简要说明。具体的实现细节和代码可以根据具体的需求和硬件平台进行调整和开发。 ### 回答3: 基于STM32单片机DHT11温湿度传感器OLED显示程序主要实现了以下功能。 首先,我们需要通过STM32单片机DHT11传感器进行通信。我们可以通过引脚连接和编程设置来实现数据的读取。在程序中,我们需要配置引脚输入/输出模式,并通过适当的延时来与DHT11发送和接收数据。 接下来,我们需要解析从DHT11传感器接收到的数据。DHT11传感器会发送40位二进制数据,其中包含温度和湿度信息。我们可以根据协议来解析这些数据,并将其存储到相应的变量中。 然后,我们需要将解析后的数据通过OLED显示屏进行显示。在STM32单片机中,我们可以使用相应的库函数来控制OLED显示屏。我们需要将温度和湿度信息转换为字符串,并使用适当的字符函数来显示在OLED屏幕上。 最后,我们可以通过循环来实现数据的持续更新和显示。以一定的时间间隔读取DHT11传感器的数据,并将其显示在OLED屏幕上。这样,我们就实现了基于STM32单片机DHT11温湿度传感器OLED显示程序。 需要注意的是,为了确保程序的正常运行,我们还需要根据实际情况对程序进行优化和调试。这可能包括校准温湿度传感器、处理错误情况和调整程序逻辑等。
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值