Resumen STM32 (biblioteca HAL) - Sensor de temperatura DHT11 (sistema de conducción asistida de seguridad inteligente)

Introducción a DHT11

El sensor digital de temperatura y humedad DHT11 es un sensor compuesto de temperatura y humedad con salida de señal digital calibrada.Aplica tecnología de adquisición de módulo digital especial y tecnología de detección de temperatura y humedad para garantizar que el producto tenga una confiabilidad extremadamente alta y una excelente estabilidad a largo plazo. El sensor incluye un elemento sensor de humedad resistivo y un elemento de medición de temperatura NTC, y está conectado con un microcontrolador de 8 bits de alto rendimiento. Por lo tanto, el producto tiene las ventajas de una excelente calidad, una respuesta ultrarrápida, una fuerte capacidad antiinterferencias y un rendimiento de alto costo. Cada sensor DHT11 está calibrado en una cámara de calibración de humedad extremadamente precisa. Los coeficientes de calibración se almacenan en la memoria OTP en forma de programa, y ​​estos coeficientes de calibración se llaman en el sensor durante el proceso de detección del modelo. La interfaz serial de un solo cable hace que la integración del sistema sea fácil y rápida. El tamaño ultrapequeño y el consumo de energía extremadamente bajo lo convierten en la mejor opción incluso para las aplicaciones más exigentes. El producto es un paquete de pines de una sola fila de 4 pines, que es fácil de conectar.

Cómo funciona DHT11

2.1, formato de datos de datos DHT11: (byte alto primero en salir)

Una transmisión de 40 bits de datos = datos enteros de humedad de 8 bits + datos decimales de humedad de 8 bits + datos enteros de temperatura de 8 bits + datos decimales de temperatura de 8 bits + suma de comprobación de 8 bits. Cuando la transmisión de datos es correcta, los datos de suma de comprobación son iguales a los últimos 8 bits del resultado obtenido por "datos enteros de humedad de 8 bits + datos decimales de humedad de 8 bits + datos enteros de temperatura de 8 bits + datos decimales de temperatura de 8 bits ".

Después de que la MCU del usuario envía una señal de inicio, DHT11 cambia de bajo consumo de energía a modo de alta velocidad. Después de esperar a que finalice la señal de inicio del host, DHT11 envía una señal de respuesta, envía datos de 40 bits y activa una adquisición de señal. El usuario puede elija leer parte de los datos de En este modo, DHT11 recibe una señal de inicio para activar una recopilación de temperatura y humedad. Si no recibe una señal de inicio del host, DHT11 no recopilará activamente temperatura y humedad, y cambiará a modo de baja velocidad después de recopilar datos.
Diagrama de tiempo

2.2 Programación de tiempos

secuencia de inicio

El estado de inactividad del bus es de alto nivel, el host baja el bus y espera a que DHT11 responda, el host debe bajar el bus durante más de 18 milisegundos para asegurarse de que DHT11 pueda detectar la señal de inicio. Después de recibir la señal de inicio del host, DHT11 espera a que finalice la señal de inicio del host y luego envía una señal de respuesta de bajo nivel de 80us Después de que el host envía la señal de inicio, espera un retraso de 20-40us, lee la señal de respuesta de DHT11 , y el host envía una señal de inicio Después de eso, puede cambiar al modo de entrada, o salida de alto nivel, y la resistencia pull-up eleva el bus.
señal de inicio

Tiempo de recepción de datos

El bus está en un nivel bajo, lo que significa que DHT11 envía una señal de respuesta. Después de que DHT11 envía la señal de respuesta, eleva el bus durante 80 us para prepararse para enviar datos. Cada bit de datos comienza con un intervalo de tiempo de bajo nivel de 50 us. La longitud del nivel alto determina los datos. El bit es 0 o 1. El formato se muestra en la siguiente figura. Si la señal de respuesta de lectura es alta, entonces DHT11 no tiene respuesta, verifique si la línea está conectada correctamente. Cuando el último bit de datos se transmite, DHT11 baja el bus por 50us, y luego el bus es elevado por una resistencia pull-up para entrar en el estado inactivo.

Método de representación de la señal del número 0
inserte la descripción de la imagen aquí

Método de representación de señal digital 1
inserte la descripción de la imagen aquí

* Código DHT11

3. Proceso y código de comunicación DHT11
3.1 Proceso de comunicación simple

El primer paso es inicializar el puerto IO y completar la secuencia de inicio para comprobar si existe DHT11

La línea de señal del segundo host se eleva para prepararse para recibir datos, y se reciben 40 bits en secuencia

3.2 Parte principal del programa

Código parcial de dht11.c*

#include "delay.h"
#include "dht11.h"
#include "tim.h"


#define DHT11_DQ_IN HAL_GPIO_WritePin(GPIOC, DHT11_DATA_OUT_Pin, GPIO_PIN_SET)	  //输入

//初始化DHT11,同时检测是否连接上DHT11,PA11初始化
 	 
uint8_t DHT11_Init(void)
{
    
    	 
  GPIO_InitTypeDef GPIO_InitStruct = {
    
    0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();


  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOC, DHT11_DATA_OUT_Pin, GPIO_PIN_SET);

  /*Configure GPIO pin : PtPin */
  GPIO_InitStruct.Pin = DHT11_DATA_OUT_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(DHT11_DATA_OUT_GPIO_Port, &GPIO_InitStruct);	

	DHT11_Rst();  
	return DHT11_Check();
}      
//复位DHT11
void DHT11_Rst(void)	   
{
    
                     
	DHT11_IO_OUT(); 	//SET OUTPUT
	HAL_GPIO_WritePin(GPIOC, DHT11_DATA_OUT_Pin, GPIO_PIN_RESET); 	//拉低
	DelayXms(20);    	//拉低延时至少18ms
	HAL_GPIO_WritePin(GPIOC, DHT11_DATA_OUT_Pin, GPIO_PIN_SET); 	//DQ=1,拉高 
	DelayUs(30);     	//拉高延时至少20~40us
}
 
//检测回应
//返回1:检测错误
//返回0:检测成功
uint8_t DHT11_Check(void) 	   
{
    
       
	uint8_t retry=0;
	DHT11_IO_IN();//SET INPUT	 
    while (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_0)&&retry<100)//DHT11拉低40~80us
	{
    
    
		retry++;
		DelayUs(1);
	};	 
	if(retry>=100)return 1;
	else retry=0;
    while (!HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_0)&&retry<100)//DHT11再次拉高40~80us
	{
    
    
		retry++;
		DelayUs(1);
	};
	if(retry>=100)return 1;	    
	return 0;
}
 
//读取一个位Bit
//返回1或0
uint8_t DHT11_Read_Bit(void) 			 
{
    
    
 	uint8_t retry=0;
	while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_0)&&retry<100)//等待变低电平
	{
    
    
		retry++;
		DelayUs(1);
	}
	retry=0;
	while(!HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_0)&&retry<100)//等待变高电平
	{
    
    
		retry++;
		DelayUs(1);
	}
	DelayUs(40);//等待40us
	if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_0))return 1;
	else return 0;		   
}
 
//读取一个字节
//返回读到的数据
uint8_t DHT11_Read_Byte(void)    
{
    
            
	uint8_t i,dat;
	dat=0;
	for (i=0;i<8;i++) 
	{
    
    
		dat<<=1; 
		dat|=DHT11_Read_Bit();
	}						    
	return dat;
}
 
//DHT11读取一次数据
//temp:温度(范围:0~50°)
//humi:湿度(范围:20%~90%)
//tem:温度小数位
//hum:湿度小数位
uint8_t DHT11_Read_Data(uint8_t *temp,uint8_t *humi,uint8_t *tem,uint8_t *hum)    
{
    
            
 	uint8_t buf[5];
	uint8_t i;
	DHT11_Rst();
	if(DHT11_Check()==0)
	{
    
    
		for(i=0;i<5;i++)//读取40位字节
		{
    
    
			buf[i]=DHT11_Read_Byte();
		}
		if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
		{
    
    
			*humi=buf[0];
			*hum=buf[1];
			*temp=buf[2];
			*tem=buf[3];
		}
	}
	else return 1;
	return 0;	    
}
 

//DHT11输出模式配置
void DHT11_IO_OUT()	
{
    
    
  GPIO_InitTypeDef GPIO_InitStruct = {
    
    0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();


  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOC, DHT11_DATA_OUT_Pin, GPIO_PIN_SET);

  /*Configure GPIO pin : PtPin */
  GPIO_InitStruct.Pin = DHT11_DATA_OUT_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(DHT11_DATA_OUT_GPIO_Port, &GPIO_InitStruct);
}
 
//DHT11输入模式配置
void DHT11_IO_IN(void)	
{
    
    
  GPIO_InitTypeDef GPIO_InitStruct = {
    
    0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  /*Configure GPIO pin : PC0 */
  GPIO_InitStruct.Pin = GPIO_PIN_0;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}
dht11.h部分代码

```c
#ifndef _DHT11_H_
#define _DHT11_H_
#include "main.h"
#define DHT11_DATA_OUT_Pin GPIO_PIN_0
#define DHT11_DATA_OUT_GPIO_Port GPIOC

void DHT11_Rst(void);
uint8_t DHT11_Check(void);
uint8_t DHT11_Read_Bit(void);
uint8_t DHT11_Read_Byte(void);
uint8_t DHT11_Read_Data(uint8_t *temp,uint8_t *humi,uint8_t *tem,uint8_t *hum);
uint8_t DHT11_Init(void);
void DHT11_IO_IN(void);
void DHT11_IO_OUT();
#endif

mian.c代码

```c
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "dht11.h"
#include "delay.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM6_Init();
  MX_TIM7_Init();
  MX_USART1_UART_Init();
  MX_USART2_UART_Init();
  MX_USART3_UART_Init();
  /* USER CODE BEGIN 2 */
	Delay_Init();
	uint8_t temperature;         
	uint8_t humidity; 
	uint8_t temp;         
	uint8_t humi; 
	uint8_t rx_buf[5];
	DHT11_Init();                         //DHT11初始化      引脚PA4PA6-MISO PA7-MOSI 


  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		DHT11_Read_Data(&temperature,&humidity,&temp,&humi);
		rx_buf[0]=temperature;
		rx_buf[1]=humidity;
    printf("temp=%d,humi=%d\r\n",rx_buf[0],rx_buf[1]);		  
		DelayXms(5000);
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
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.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  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_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

Documento de referencia de la dirección del enlace de descarga del archivo

Supongo que te gusta

Origin blog.csdn.net/qq_47128755/article/details/122571514
Recomendado
Clasificación