【STM32】DHT11温湿度模块传感器详解&代码

一、DHT11产品介绍

DHT11是数字温湿度传感器,测量范围:湿度20%-95%,温度0-50℃,广泛应用于加湿器、温湿度计、空调、汽车等领域。

二、典型应用电路

在这里插入图片描述
如上图DATA引脚用于MCU与DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间4ms左右(超时时间的判断)。一次完整的数据传输为40bit,高位先出(MSB最高有效位有线传输)
数据传送正确时校验和数据等于:8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据,所得结果的末8位。
如:
湿度:60.5% 60 05
温度:26.7℃ 26 07
60+5+26+7=98
98&0xFF=98=1001 1000

三、DHT11温湿度模块的通信过程

在这里插入图片描述
四、示例代码
显示室内温度和湿度
效果图:
在这里插入图片描述

1、DHT11初始化

void dht11_init(void)
{
	//打开端口G的硬件时钟,就是供电
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG,ENABLE);


	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9; 	//9号引脚
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;	//输出模式
	GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;	//开漏
	GPIO_InitStructure.GPIO_Speed = GPIO_High_Speed;//高速,速度越高,响应越快,但是功耗会更高
	GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;//不使能上下拉电阻
	GPIO_Init(GPIOG,&GPIO_InitStructure);

	//只要有输出模式,肯定会有初始电平的状态,看连接设备的说明书
	PGout(9)=1;

}

2、

int32_t dht11_read(uint8_t *buf)
{
	uint32_t t=0;
	int32_t i=0,j=0;
	uint8_t d=0;
	uint8_t *p=buf;
	uint8_t check_sum=0;
	
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9; 	//9号引脚
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;	//输出模式
	GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;	//开漏
	GPIO_InitStructure.GPIO_Speed = GPIO_High_Speed;//高速,速度越高,响应越快,但是功耗会更高
	GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;//不使能上下拉电阻
	GPIO_Init(GPIOG,&GPIO_InitStructure);	
	
	PGout(9)=0;
	delay_ms(18);
	
	PGout(9)=1;
	delay_us(30);
	
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9; 	//9号引脚
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN;	//输入模式
	GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;	//开漏
	GPIO_InitStructure.GPIO_Speed = GPIO_High_Speed;//高速,速度越高,响应越快,但是功耗会更高
	GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;//不使能上下拉电阻
	GPIO_Init(GPIOG,&GPIO_InitStructure);
	
	//等待低电平出现
	t=0;
	while(PGin(9))
	{
		t++;
		delay_us(1);
		
		if(t >= 4000)
			return -1;
	}

	//用超时检测的方法测量低电平的合法性
	t=0;
	while(PGin(9)==0)
	{
		t++;
		delay_us(1);
		
		if(t >= 100)
			return -2;
	}	
	
	//用超时检测的方法测量高电平的合法性
	t=0;
	while(PGin(9))
	{
		t++;
		delay_us(1);
		
		if(t >= 100)
			return -3;
	}	
	
	for(j=0; j<5; j++)
	{
		//接收一个字节的数据
		for(d=0,i=7; i>=0; i--)
		{
			//用超时检测的方法测量低电平的合法性
			t=0;
			while(PGin(9)==0)
			{
				t++;
				delay_us(1);
				
				if(t >= 100)
					return -4;
			}

			//延时40us (延时时间在28us ~ 70us)
			delay_us(40);
			
			if(PGin(9))
			{
				d|=1<<i;	//将d变量对应的bit置1
				
				//等待高电平持续完毕
				t=0;
				while(PGin(9))
				{
					t++;
					delay_us(1);
					
					if(t >= 100)
						return -5;
				}			
			}
		}	
		p[j]=d;
	}
	
	//延时50us,可以忽略通讯结束的低电平
	delay_us(50);
	
	//计算校验和,检查接收到的数据是否准确
	check_sum = (p[0]+p[1]+p[2]+p[3])&0xFF;
	
	if(check_sum == p[4])
		return 0;
	
	return -6;
}

3、main函数实现

int main(void)
{
	uint8_t buf[5];
	int32_t rt;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
	
	/* 初始化串口1波特率为115200bps,若发送/接收数据有乱码,请检查PLL */
	usart1_init(115200);
	
	dht11_init();

	printf("this is dht11 test\r\n");
	
	printf("1<<6=%X \r\n",1<<6);	
	printf("1<<3=%X \r\n",1<<3);		
	
	while(1)
	{
		rt = dht11_read(buf);
		
		if( rt == 0)
		{
			printf("T:%d.%d H:%d.%d\r\n",buf[2],buf[3],buf[0],buf[1]);
		
		}
		else
		{
			printf("dht11 read error code is %d\r\n",rt);
		}

		//官方要求,每6秒
		delay_ms(6000);
	}
}
  • 30
    点赞
  • 205
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
以下是一个基于STM32DHT11温湿度传感器的示例代码,使用STM32CubeIDE进行开发。 ```c #include "main.h" #include "dht11.h" #include <stdio.h> UART_HandleTypeDef huart2; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_USART2_UART_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART2_UART_Init(); uint8_t data[5]; while (1) { if (DHT11_ReadData(data) == DHT11_OK) { float temperature = data[2] + ((float)data[3] / 10.0f); float humidity = data[0] + ((float)data[1] / 10.0f); char message[50]; sprintf(message, "Temperature: %.1f C, Humidity: %.1f %%\r\n", temperature, humidity); HAL_UART_Transmit(&huart2, (uint8_t *)message, strlen(message), HAL_MAX_DELAY); } HAL_Delay(2000); } } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 8; RCC_OscInitStruct.PLL.PLLN = 336; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 7; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) { Error_Handler(); } } static void MX_USART2_UART_Init(void) { huart2.Instance = USART2; huart2.Init.BaudRate = 115200; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart2) != HAL_OK) { Error_Handler(); } } static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOA_CLK_ENABLE(); /*Configure GPIO pin : PA1 */ GPIO_InitStruct.Pin = GPIO_PIN_1; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } void HAL_Delay(uint32_t Delay) { uint32_t tickstart = HAL_GetTick(); uint32_t wait = Delay; if (wait < HAL_MAX_DELAY) { wait += (uint32_t)(uwTickFreq); } while ((HAL_GetTick() - tickstart) < wait) { } } void Error_Handler(void) { __disable_irq(); while (1) { } } ``` 注意:这是一个仅供参考的示例代码,使用前请根据具体情况进行适当修改。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

邢饱饱

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

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

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

打赏作者

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

抵扣说明:

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

余额充值