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

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

文章目录

  • 一、DHT11基本了解
    • 1.基本信息
    • 2.引脚了解
  • 二、开始上手
    • 1.接线
    • 2.关键部分代码
        • DHT11.c代码
        • DHT11.h代码
        • main.c
  • 总结


一、DHT11基本了解

1.基本信息

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

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

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

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

2.引脚了解

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

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

二、开始上手

1.接线

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

【STM32单片机+DHT11温度传感器】快速上手,适用于多种型号芯片_第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的使用主要在于通信协议的编写,不过也不是特别难,只需要按照时序图来编辑代码即可。这里提供的代码可以直接去使用,这里留有接口,非常方便。

你可能感兴趣的:(stm32学习,c语言,stm32)