[STM32]HAL库STM32CubeMX+DHT11温湿度传感器

本文详细介绍了如何使用STM32F103C8T6微控制器通过STM32CubeMX和KeilIDE与DHT11数字温湿度传感器进行单线通信,包括DHT11的工作原理、接口说明、通讯过程和程序编写,涉及微秒级延时函数、IO口配置、数据读取等关键步骤。
摘要由CSDN通过智能技术生成

目录

所用的工具:

知识概括:

DHT11介绍:

DHT11性能说明:

接口说明

 电源引脚

串行接口  

工程创建

1、设置RCC

2、时钟设置

3、项目文件设置

4、设置IO口(DATA)

5、TIM时钟配置

6、USART配置

  程序编写:

         1、TIM3实现微秒(us)级延时函数:

2、IO口配置

3、DHT11检测起始信号(这里的DHT11_LOW,DHT11_HIGH 在下面的的第8点)

4、DHT11检测响应信号(这里的DHT11_IO_IN在下面的第8点)

5、DHT11读取一bit数据

6、DHT11读取一个Byte数据

7、DHT11读取湿度和温度的数据

8、IO口输出高、低电平以及读取IO口电平定义和需要添加的头文件

9、温度、湿度和数据缓存数组的声明,函数的声明

10、主循环,(DHT11数据的读取和串口发送)

效果展示

1、将程序下载到开发板

2、串口助手查看数据​编辑

总结 

附录(完整程序)


所用的工具:

1、芯片:STM32F103C8T6

2、软件:STM32CubeMX软件

3、IDE :   MDK_Keil软件

知识概括:

DHT11基本知识和原理

DHT11通讯方式

STM32CubeTIM和USART的配置

DHT11数据采集实现

DHT11介绍:

DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传
感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高
的可靠性与卓越的长期稳定性。

DHT11性能说明:

接口说明

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

 电源引脚

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

串行接口  

DATA 用于微处理器与 DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间4ms左右,数据分小数部分和整数部分,具体格式在下面说明,当前小数部分用于以后扩展,现读出为零.操作流程下:
           一次完整的数据传输为40bit,高位先出。
         数据格式: 8bit湿度整数数据+8bit湿度小数数据
                          +8bi温度整数数据+8bit温度小数数据
                          +8bit校验和
        数据传送正确时校验和数据等于“8bit湿度整数数据+8bit湿度小数数据 +8bi温度整数数据+8bit温度小数数据” 所得结果的末8位。
        用户MCU发送一次开始信号后,DHT11从低功耗模式转换到高速模式,等待主机开始信号结束后,DHT11发送响应信号,送出40bit的数据,并触发一次信号采集, 用户可选择读取部分数据.从模式下,DHT11接收到开始信号触发一次温湿度采集, 如果没有接收到主机发送开始信号,DHT11不会主动进行温湿度采集.采集数据后 转换到低速模式。
*接下来就是重点中的重点了!!
DHT11的通讯过程:
        

        总线空闲状态为高电平,主机把总线拉低等待DHT11响应, 主机 把总线拉低必须 大于18毫秒 ,保证DHT11能检测到起始信号。当DHT11接收到主机的起始信号之后,会拉高总线并且等待。开始信号的结束后,将DATA切换成输入模式(这里的DATA指的是那个模块上的IO口切换成输入模式),随后总线为低电平,说明 DHT11 发出 80us低电平 的响应信号,发出响应信号之后 , DHT11 再次把总线 拉高80us ,准备开始发送数据, 数据是以一bit位的方式传输 当最后一bit数据传送完毕后 DHT11 拉低总线50us,随后总线由上拉电阻拉高进入空闲态。
下面这张图的延迟时长非常重要,需要在程序中用到

         总线空闲状态为高电平, 主机 把总线拉低等待DHT11响应,主机把总线拉低必 须 大于18毫秒 ,保证DHT11能检测到起始信号。DHT11接收到主机的开始信号后, 拉高总线 20us~40us ,等待开始信号结束后, DHT11 发出 80us低电平 的响应信号,发出响应信号之后 , DHT11 再次把总线 拉高80us 并且准备输出数据。
        下面这张是DHT11数据传输的时序图:
        数字0信号表示方法如图所示:
     数字1信号表示方法如图所示:

        

         总线为低电平,说明DHT11发送响应信号,DHT11发送响应信号后,再把总线拉 高80us,准备发送数据,每一bit数据都以50us低电平时隙开始,高电平的长短定 了数据位是0还是1.格式见下面图示.如果读取响应信号为高电平,则DHT11没有 响应,请检查线路是否连接正常.当最后一bit数据传送完毕后,DHT11拉低总线 50us,随后总线由上拉电阻拉高进入空闲状态

工程创建

1、设置RCC

2、时钟设置

 3、项目文件设置

  • 1 设置项目名称
  • 2 设置存储路径
  • 3 选择所用IDE

1、 复制所用文件的.C和.H

2、每个功能生成独立的.C和.H文件

 4、设置IO口(DATA)

第二步的Moed设置GPIO_OUTPUT和GPIO_INPUT都可以,因为DHT11是单线双向的 ,所以在编写程序时我们需要改写的它IO模式。  

5、USART配置

第二步 Mode设置为异步通信 

  程序编写:

   首先来编写函数部分:

    1、微秒(us)级延时函数:

/**
  * @brief  us级延时函数
  * @param  delay 控制延时的时长
  * @retval 无
  */
void Delay_us(uint32_t udelay)
{
  uint32_t startval,tickn,delays,wait;
 
  startval = SysTick->VAL;
  tickn = HAL_GetTick();
  delays =udelay * 72;
  if(delays > startval)
  {
      while(HAL_GetTick() == tickn)
      {
 
      }
      wait = 72000 + startval - delays;
      while(wait < SysTick->VAL)
      {
 
      }
  }
  else
  {
      wait = startval - delays;
      while(wait < SysTick->VAL && HAL_GetTick() == tickn)
     {
 
     }
  }
}

该函数用了逻辑分析仪进行了比较,示图如下:

100us:

10us:

1us:

2、IO口配置

/**
  * @brief  DATA引脚(PA7)设置为输出模式
  * @param  无
  * @retval 无
  */
void DHT11_OUT(void)
{
	GPIO_InitTypeDef  GPIO_InitStruct = {0};

	GPIO_InitStruct.Pin = GPIO_PIN_7;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
/**
  * @brief  DATA引脚(PA7)设置为输入模式
  * @param  无
  * @retval	无 
  */
void DHT11_IN(void)
{
	GPIO_InitTypeDef  GPIO_InitStruct = {0};

	GPIO_InitStruct.Pin  = GPIO_PIN_7;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

3、DHT11检测起始信号(这里的DHT11_LOW,DHT11_HIGH 在下面的的第8点

/**
  * @brief  DHT11检测起始信号
  * @param  无
  * @retval 无
  */
void DHT11_Strat(void)
{
	DHT11_OUT();   //PA7设置为输出模式
	DHT11_LOW;     //主机拉低总线
	HAL_Delay(20); //延迟必须大于18ms ; 
	DHT11_HIGH;    //主机拉高总线等待DHT11响应
	Delay_us(30);   
}

4、DHT11检测响应信号(这里的DHT11_IO_IN在下面的第8点

/**
  * @brief  DHT11发送响应信号
  * @param  无
  * @retval 返回值0/1  0:响应成功 1:响应失败
  */
uint8_t DHT11_Check(void)
{
	uint8_t retry = 0 ;
	DHT11_IN();
	//采用while循环的方式检测响应信号
	while(DHT11_IO_IN && retry <100) // DHT11会拉低 40us ~80us
	{
		retry++;
		Delay_us(1);//1us
	}
	if(retry>=100) //判断当DHT11延迟超过80us时return 1 , 说明响应失败
	{return  1;}
	else retry =  0 ;
		
	while(!DHT11_IO_IN && retry<100)// // DHT11拉低之后会拉高 40us ~80us
	{
		retry++;
		Delay_us(1);//1us
	}
		
	if(retry>=100)
	{return 1;}
	return 0 ;
}

5、DHT11读取一bit数据

/**
  * @brief  DHT11读取一位数据
  * @param  无
  * @retval 返回值0/1  1:读取成功 0:读取失败
  */
uint8_t DHT11_Read_Bit(void)
{
	uint8_t retry = 0 ;
	while(DHT11_IO_IN && retry <100)//同上采用while循环的方式去采集数据
	{
		retry++;
		Delay_us(1);
	}
	retry = 0 ;
	while(!DHT11_IO_IN && retry<100)
	{
		retry++;
		Delay_us(1);
	}

	Delay_us(40);              //结束信号,延时40us 
	if(DHT11_IO_IN) return 1;  //结束信号后,总线会被拉高 则返回1表示读取成功
	else 
	return 0 ;
}

6、DHT11读取一个Byte数据

/**
  * @brief  DHT11读取一个字节数据
  * @param  无
  * @retval 返回值:dat 将采集到的一个字节的数据返回
  */
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 ; 
}

7、DHT11读取湿度和温度的数据

/**
  * @brief  DHT11读取数据
  * @param  temp:温度值 humi :湿度值
  * @retval 返回值0/1 0:读取数据成功 1:读取数据失败
  */
uint8_t DHT11_Read_Data(uint8_t* temp , uint8_t* humi)
{
	uint8_t buf[5];        //储存五位数据
    uint8_t i;    
	DHT11_Strat();         //起始信号
	if(DHT11_Check() == 0) //响应信号
    {
		for(i=0; i<5; i++)
		{
			buf[i] = DHT11_Read_Byte();
		}
		if(buf[0]+buf[1]+buf[2]+buf[3] == buf[4]) //校验数据
		{
		    *humi = buf[0]; // 湿度
			*temp = buf[2]; // 温度
		}
	}else return 1;
	
   return 0 ;
}

以上就是需要用到的函数部分的编写,接下来是一些声明和定义:

8、IO口输出高、低电平以及读取IO口电平定义和需要添加的头文件

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define DHT11_HIGH     HAL_GPIO_WritePin(GPIOA, DHT11_Pin,	GPIO_PIN_SET) //输出高电平
#define DHT11_LOW      HAL_GPIO_WritePin(GPIOA, DHT11_Pin, GPIO_PIN_RESET)//输出低电平

#define DHT11_IO_IN      HAL_GPIO_ReadPin(GPIOA, DHT11_Pin)//读取IO口电平

/* USER CODE END PD */
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include	"stdio.h"
#include  "string.h"

/* USER CODE END Includes */

9、温度、湿度和数据缓存数组的声明,函数的声明


  /* USER CODE BEGIN 1 */
     uint8_t temperature = 1;  //温度

	 uint8_t humidity = 1;     //湿度

	 uint8_t aTXbuf[32];       //串口发送缓存数组
     
     DHT11_Strat(void);

  /* USER CODE END 1 */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);

void Delay_us(uint16_t delay);                //us级延时函数

//DHT11_DATA ,IO口设置为输出模式(这里的IO口指的是STM32CubeMX中配置的IO口)
void DHT11_OUT(void);	
												
void DHT11_IN(void);                          //DHT11_Data IO设置为输入模式
void DHT11_Strat(void);				          //主机发出起始信号
uint8_t DHT11_Check(void);                    //DHT11发送响应信号
uint8_t DHT11_Read_Bit(void);                 //读取DHT11一个BIT的数据
uint8_t DHT11_Read_Byte(void);                //读取DHT11一个Byte的数据
uint8_t DHT11_Read_Data(uint8_t* temp , uint8_t* humi);  //读取DHT11湿度和温度的数据

/* USER CODE BEGIN PFP */

10、主循环,(DHT11数据的读取和串口发送)

  while (1)
  {
	//接收DHT11的温度和湿度的值
	DHT11_Read_Data(&temperature , &humidity);  
    //将数据存放到aTXbuf这个数组当中去。 不了解"sprintf"用法的可以去查一下...       
	sprintf((char*)aTXbuf,"温度:%d℃,湿度: %d %%\r\n" ,temperature ,humidity);
    //将数据通过串口发送到主机上的串口助手
	HAL_UART_Transmit(&huart1, aTXbuf, strlen((const char*)aTXbuf), 200); 
    //延时500ms
	HAL_Delay(500);   

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }

到这里DHT11的程序就编写完了 ,下面就来看看效果吧 

效果展示

1、将程序下载到开发板

 2、串口助手查看数据

总结 

通过本次DHT11温湿度传感器的学习,掌握了单线双向的数据通信方式DHT11和主机之间数据通讯过程,而且在此过程中要注意延时函数的把控精度,在编写程序中DHT11数据读取方式,数据传输方式和数据存储方式,以及微秒级延迟函数的编写,本设计参考正点原子探索者开发板教程STM32Cube高效开发指南(高级篇)

附录(完整程序)

/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include	"stdio.h"
#include  "string.h"

/* USER CODE END Includes */

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

/* USER CODE END PTD */

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

#define DHT11_HIGH     HAL_GPIO_WritePin(GPIOA, DHT11_Pin,	GPIO_PIN_SET)
#define DHT11_LOW      HAL_GPIO_WritePin(GPIOA, DHT11_Pin, GPIO_PIN_RESET)

#define DHT11_IO_IN      HAL_GPIO_ReadPin(GPIOA, DHT11_Pin)

/* 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);

void Delay_us(uint16_t delay);              
void DHT11_OUT(void);													
void DHT11_IN(void);                          
void DHT11_Strat(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);        

/* 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 */

    uint8_t temperature = 1 ; 
	uint8_t humidity = 1;
	uint8_t aTXbuf[32] ;

  /* 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_USART1_UART_Init();
  MX_TIM3_Init();
  /* USER CODE BEGIN 2 */
  DHT11_Strat();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		
	 DHT11_Read_Data(&temperature , &humidity);
	 sprintf((char*)aTXbuf,"温度:%d℃ , 湿度:%d %% \r\n" ,temperature ,humidity);
	 HAL_UART_Transmit(&huart1, aTXbuf, strlen((const char*)aTXbuf), 200);
	 HAL_Delay(500);

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* 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 CPU, AHB and APB busses clocks 
  */
  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 busses 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 */

void Delay_us(uint16_t delay)
{
	__HAL_TIM_DISABLE(&htim3);
	__HAL_TIM_SET_COUNTER(&htim3,0);
	__HAL_TIM_ENABLE(&htim3);
	uint16_t curCnt=0;
	while(1)
	{
		curCnt=__HAL_TIM_GET_COUNTER(&htim3);
		if(curCnt>=delay)
			break;
	}
	__HAL_TIM_DISABLE(&htim3);
}

void DHT11_OUT(void)
{
	GPIO_InitTypeDef  GPIO_InitStruct = {0};

	GPIO_InitStruct.Pin = GPIO_PIN_7;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

void DHT11_IN(void)
{
	GPIO_InitTypeDef  GPIO_InitStruct = {0};

	GPIO_InitStruct.Pin  = GPIO_PIN_7;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}


void DHT11_Strat(void)
{
	DHT11_OUT();
	DHT11_LOW;
	HAL_Delay(20);
	DHT11_HIGH;
	Delay_us(30);
}


uint8_t DHT11_Check(void)
{
	uint8_t retry = 0 ;
	DHT11_IN();
		
	while(DHT11_IO_IN && retry <100) 
	{
		retry++;
		Delay_us(1);//1us
	}
	if(retry>=100) 
	{return  1;}
	 else retry =  0 ;
		
	while(!DHT11_IO_IN && retry<100)
	{
		retry++;
		Delay_us(1);//1us
	}
		
	if(retry>=100)
	{return 1;}
	return 0 ;
}


uint8_t DHT11_Read_Bit(void)
{
	uint8_t retry = 0 ;
	while(DHT11_IO_IN && retry <100)
	{
		retry++;
		Delay_us(1);
	}
		retry = 0 ;
	while(!DHT11_IO_IN && retry<100)
	{
		retry++;
		Delay_us(1);
	}
	Delay_us(40);
	if(DHT11_IO_IN) 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 ; 
}


uint8_t DHT11_Read_Data(uint8_t* temp , uint8_t* humi)
{
	uint8_t buf[5];
	uint8_t i;
	DHT11_Strat();
    if(DHT11_Check() == 0)
	{
		for(i=0; i<5; i++)
		{
			buf[i] = DHT11_Read_Byte();
		}
		if(buf[0]+buf[1]+buf[2]+buf[3] == buf[4])
		{
			*humi = buf[0];
			*temp = buf[2];
		}
	}else return 1;
	
   return 0 ;
}

/* USER CODE END 4 */

### 回答1: DHT11湿度传感器是一种数字式传感器,它可以测量环境的度和相对湿度。在STM32中使用HAL库读取DHT11传感器数据的步骤如下: 1.配置引脚 DHT11传感器有一个数据引脚,将其连接到STM32的GPIO引脚。然后使用HAL库初始化GPIO引脚。 2.发送起始信号 向DHT11传感器发送起始信号,该信号包括一个50微秒的低电平和一个20微秒的高电平。 3.接收数据 DHT11传感器将发送40位数据,其中包括16位湿度数据、16位度数据和8位校验和。在接收数据期间,STM32将读取引脚状态并将其转换为二进制数据。 4.解码数据 将接收到的数据解码为湿度和度值,并验证校验和以确保数据的正确性。 以下是一个示例代码,演示如何使用HAL库读取DHT11传感器数据: ```c #include "stm32f4xx_hal.h" #define DHT11_PIN GPIO_PIN_0 #define DHT11_PORT GPIOA uint8_t data[5]; void DHT11_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOA_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(DHT11_PORT, DHT11_PIN, GPIO_PIN_RESET); /*Configure GPIO pin as output */ GPIO_InitStruct.Pin = DHT11_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(DHT11_PORT, &GPIO_InitStruct); } void DHT11_Start(void) { /* set pin to output */ GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = DHT11_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(DHT11_PORT, &GPIO_InitStruct); /* send start signal */ HAL_GPIO_WritePin(DHT11_PORT, DHT11_PIN, GPIO_PIN_RESET); HAL_Delay(20); HAL_GPIO_WritePin(DHT11_PORT, DHT11_PIN, GPIO_PIN_SET); HAL_Delay(20); /* set pin to input */ GPIO_InitStruct.Pin = DHT11_PIN; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(DHT11_PORT, &GPIO_InitStruct); } uint8_t DHT11_Check_Response(void) { uint8_t response = 0; uint16_t timeout = 10000; while (HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN) == GPIO_PIN_RESET) { if (--timeout == 0) { return 0; } } timeout = 10000; while (HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN) == GPIO_PIN_SET) { if (--timeout == 0) { return 0; } } return 1; } uint8_t DHT11_Read_Byte(void) { uint8_t value = 0; for (int i = 0; i < 8; i++) { while (HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN) == GPIO_PIN_RESET) ; HAL_Delay(40); if (HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN) == GPIO_PIN_SET) { value |= (1 << (7 - i)); } while (HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN) == GPIO_PIN_SET) ; } return value; } void DHT11_Read_Data(void) { uint8_t checksum = 0; DHT11_Start(); if (DHT11_Check_Response()) { data[0] = DHT11_Read_Byte(); data[1] = DHT11_Read_Byte(); data[2] = DHT11_Read_Byte(); data[3] = DHT11_Read_Byte(); checksum = DHT11_Read_Byte(); if (checksum == (data[0] + data[1] + data[2] + data[3])) { /* data is valid */ } else { /* data is invalid */ } } else { /* no response from DHT11 */ } } ``` 在上面的代码中,DHT11_Init()函数用于初始化引脚,DHT11_Start()函数用于发送起始信号,DHT11_Check_Response()函数用于检查传感器是否响应,DHT11_Read_Byte()函数用于读取8位数据,DHT11_Read_Data()函数用于读取40位数据并验证校验和。 ### 回答2: DHT11湿度传感器是一种常用的数字湿度传感器,适用于STM32单片机STM32 HAL库STM32官方提供的一种软件库,用于简化STM32单片机的开发过程。 使用DHT11湿度传感器需要先连接好硬件电路,将传感器的引脚与STM32单片机的引脚相连接,并给传感器提供电源。然后在STM32单片机上编写程序,调用HAL库中提供的相关函数,即可读取传感器的湿度数据。 首先,在程序中需要定义一个GPIO引脚和一个变量,用于存储传感器读取到的数据。然后使用HAL库中的相关函数,对GPIO引脚进行配置,以及初始化DHT11传感器。 接下来,使用HAL库中的延时函数,延时一段时间,让传感器完成数据采集。然后调用HAL库中的函数,读取传感器的数据,并将数据存入之前定义的变量中。 最后,通过串口等方式,将读取到的湿度数据进行显示或者传输。 需要注意的是,使用DHT11传感器时,其通讯采用的是一种简单的串行通信协议,需要根据协议要求对传感器进行初始化和数据读取。 总的来说,通过使用STM32 HAL库,我们可以方便地读取DHT11湿度传感器的数据,并在STM32单片机上进行后续的处理和应用。 ### 回答3: DHT11湿度传感器是一种常用的数字式传感器,可以测量当前环境的度和湿度。STM32是一种微控制器,它可以通过HAL库来与不同的外设进行通信和控制。 在使用DHT11湿度传感器时,首先需要将其与STM32连接。使用HAL库的GPIO模块,可以根据DHT11的引脚定义连接到STM32的相应引脚上。例如,将DHT11的数据引脚连接到STM32的GPIO引脚上,以实现数据的输入和输出。 通过HAL库的定时器模块,可以在STM32中设置适当的时间间隔来进行数据的采集。DHT11湿度传感器的数据采集需要一定的时间,通过定时器的设置,可以保证数据的稳定性和准确性。在采集数据之后,可以使用HAL库的串口模块,将数据发送到计算机或其他设备进行处理和显示。 在HAL库的使用过程中,可以根据需要修改一些参数,例如数据采集的频率、传输数据的格式等。通过仔细阅读HAL库的开发文档和示例代码,可以更好地理解和掌握DHT11湿度传感器STM32中的使用方法。 总之,DHT11湿度传感器可以通过STM32HAL库进行连接和控制。通过合理的设置和使用,可以方便地获取当前环境的度和湿度数据,并且可以根据需求进行相应的处理和显示。
评论 47
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值