STM32如何连接和读取DHT11温湿度传感器数据

目录

1. DHT11简介

1.1. 连接电路 

1.2. 串行接口 (单线双向)

 2. cubeMX设置

3. 代码开发

 3.1. 实现定时函数

3.2. 打开串口调试

3.4. 测试代码实现

4. 运行效果


1. DHT11简介

1.1. 连接电路 

信息如下:

建议连接线长度短于20米时用5K上拉电阻,大于20米时根据实际情况使
用合适的上拉电阻

 DHT11的供电电压为 3-5.5V。传感器上电后,要等待 1s 以越过不稳定状态在此
期间无需发送任何指令。电源引脚(VDD,GND)之间可增加一个100nF 的电容,用以去
耦滤波。

1.2. 串行接口 (单线双向)

DATA 用于微处理器与 DHT11之间的通讯和同步,采用单总线数据格式,一次
通讯时间4ms左右,数据分小数部分和整数部分,具体格式在下面说明,当前小数
部分用于以后扩展,现读出为零.操作流程如下:
一次完整的数据传输为40bit,高位先出。
数据格式:8bit湿度整数数据+8bit湿度小数数据
+8bi温度整数数据+8bit温度小数数据
+8bit校验和
数据传送正确时校验和数据等于“8bit湿度整数数据+8bit湿度小数数据
+8bi温度整数数据+8bit温度小数数据”所得结果的末8位。

 

 

 

 2. cubeMX设置

  1. GPIOE,GPIO_PIN_6,作为DATA接口。推挽输出,上拉电阻。
  2. 打开定时器TIM6。
  3. 开启USART1。

3. 代码开发

 3.1. 实现定时函数

time.c文件:

/* USER CODE BEGIN 0 */
#include <stdio.h>
/* USER CODE END 0 */

/* USER CODE BEGIN 1 */
void delay_us(uint16_t delayValue)
{
	uint16_t delayCount=0;
	HAL_TIM_Base_Start(&htim6);
	__HAL_TIM_SetCounter(&htim6,delayCount);
	while(delayCount<delayValue)
	{
		delayCount=__HAL_TIM_GetCounter(&htim6);
	}
	HAL_TIM_Base_Stop(&htim6);
}

void delay_ms(uint16_t delayValue)
{
	for(int i=0;i<delayValue;i++)
	{
		delay_us(1000);
	}
}

/* USER CODE END 1 */

3.2. 打开串口调试

 usart.h文件:

/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */

 usart.c文件:

/* USER CODE BEGIN 1 */
int fputc(int ch,FILE *f)
{
	HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,1000);
	return ch;
}
/* USER CODE END 1 */

3.3. 实现DHT11协议

gpio.h文件:

/* USER CODE BEGIN Private defines */
typedef enum
{
	INPUT=0,OUTPUT
}IOMODE;
#define DHT_GPIO_H    HAL_GPIO_WritePin(GPIOE, GPIO_PIN_6, GPIO_PIN_SET)
#define DHT_GPIO_L    HAL_GPIO_WritePin(GPIOE, GPIO_PIN_6, GPIO_PIN_RESET)
/* USER CODE END Private defines */

/* USER CODE BEGIN Prototypes */
_Bool readDht11(void);
/* USER CODE END Prototypes */

gpio.c文件:

/* USER CODE BEGIN 0 */
#include "tim.h"
#include <stdio.h>
#include "main.h"
/* USER CODE END 0 */

/* USER CODE BEGIN 1 */
uint8_t humiAndTemp[5];
_Bool status=1;
/* USER CODE END 1 */

/* USER CODE BEGIN 2 */

void dht11IOMode(IOMODE ioMode)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	GPIO_InitStruct.Pin = GPIO_PIN_6;
	if(ioMode==INPUT)
	{
		GPIO_InitStruct.Mode=GPIO_MODE_INPUT;
		GPIO_InitStruct.Pull=GPIO_PULLUP;
		HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
	}else if(ioMode==OUTPUT)
	{
		HAL_GPIO_WritePin(GPIOE, GPIO_PIN_6, GPIO_PIN_SET);
		GPIO_InitStruct.Mode=GPIO_MODE_OUTPUT_PP;
		GPIO_InitStruct.Pull=GPIO_PULLUP;
		GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
		HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
	}
}

_Bool dht11Start(void)
{
	dht11IOMode(OUTPUT);
	DHT_GPIO_L;
	delay_ms(20);
	dht11IOMode(INPUT);
	delay_us(30);
	
	uint16_t count;
	for(count=0;count<60;count++)
	{
		if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_6)==GPIO_PIN_RESET)
			break;
		delay_us(2);
	}
	if(count>=59)
	{
		LOG("dht11 start fail\n");
		return 0;
	}
	while(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_6)==GPIO_PIN_RESET);
	while(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_6)==GPIO_PIN_SET);
	return 1;
}

uint8_t readDht11Byte(void)
{
	uint8_t value=0;
	uint8_t count=0;
	for(uint8_t i=0;i<8;i++)
	{
		value<<=1;
		count=0;
		while(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_6)==GPIO_PIN_RESET)
		{
			count++;
			if(count>=35)
			{
				status=0;
				return 0;
			}
			delay_us(2);
		}
		delay_us(38);
		if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_6)==GPIO_PIN_SET)
		{
			value|=1;
		}else{
			value|=0;
		}
		count=0;
		while(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_6)==GPIO_PIN_SET)
		{
			count++;
			if(count>=35)
			{
				status=0;
				return 0;
			}
			delay_us(2);
		}
	}
	status=1;
	return value;
}

_Bool readDht11(void)
{
	uint8_t check_value=0;
	if(dht11Start()==0)
	{
		LOG("dht11 start fail\n");
		return 0;
		
	}
	for(uint8_t i=0;i<5;i++)
	{
		humiAndTemp[i]=readDht11Byte();
		if(status==0)
		{
			LOG("humiAndTemp[%d] fail\n",i);
			return 0;
			
		}
		status=1;
		if(i!=4)
		{
			check_value+=humiAndTemp[i];
		}
	}
	
	if(check_value==humiAndTemp[4])
	{
		LOG("check_value success,check_value:%d,humiAndTemp[4]:%d\n",check_value,humiAndTemp[4]);
		return 1;
	}else{
		LOG("check_value fail,check_value:%d,humiAndTemp[4]:%d\n",check_value,humiAndTemp[4]);
		return 0;
		
	}
}

/* USER CODE END 2 */

3.4. 测试代码实现

main.h文件:

/* USER CODE BEGIN Private defines */
#define OPENLOG
#ifdef OPENLOG
#define LOG(fmt, ...)          printf("<%s:%s>:"fmt"\r\n", __FILE__, __FUNCTION__, ##__VA_ARGS__)
#else
#define LOG(fmt, ...)
#endif
/* USER CODE END Private defines */

main.c文件:

  /* USER CODE BEGIN 2 */
	HAL_Delay(1000);
  /* USER CODE END 2 */

/* USER CODE BEGIN WHILE */
  while (1)
  {
		printf("hello world\n");
		if(readDht11())
		{
			printf("readDht11 success\n");
			printf("humiAndTemp[0]:%d\n",humiAndTemp[0]);
			printf("humiAndTemp[1]:%d\n",humiAndTemp[1]);
			printf("humiAndTemp[2]:%d\n",humiAndTemp[2]);
			printf("humiAndTemp[3]:%d\n",humiAndTemp[3]);
			printf("humiAndTemp[4]:%d\n",humiAndTemp[4]);

			uint16_t humi=(humiAndTemp[0]<<8) + humiAndTemp[1];
			uint16_t temp=(humiAndTemp[2]<<8) + humiAndTemp[3];
			printf("temp:%d.%d\n",temp>>8,temp&0xff);
			printf("humi:%d.%d\n",humi>>8,humi&0xff);
		}
		else
		{
			printf("readDht11 fail\n");
		}

		delay_ms(5000);
    /* USER CODE END WHILE */
    }

4. 运行效果

 

物联沃分享整理
物联沃-IOTWORD物联网 » STM32如何连接和读取DHT11温湿度传感器数据

发表评论