【DHT11驱动】-STM32CubeMX+DHT11温湿度传感器

一、DHT11时序

采集范围:温度0-50°±2°,湿度:20-90%RH。

采用单总线双向串行通信协议,每次采集都要由单片机发起开始信号,然后DHT11会向单片机发送响应并开始传输40位数据帧,高位在前。数据格式为:8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据+8bit校验位,温湿度小数部分默认为0,即单片机采集的数据都是整数,校验位为4个字节的数据相加取结果的低8位数据作为校验和:

时序图:

 二、DHT11驱动程序编写

 

 

选择引脚

选择一个引脚,我这里选择PA5,然后生成代码。

把H文件放在对应目录,然后编译。 

 三、主要代码

main.c

#include "main.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
#include "DHT11.h"
#include "string.h"
#include "stdio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* 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 */
extern uint8_t Data[5];
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
 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_TIM1_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */

   /* USER CODE BEGIN 3 */

while (1)
{
    /* USER CODE END WHILE */
    if (DHT_Read())
    {
        char buffer[50]; 

        int temperature = Data[2]; 
        int humidity = Data[0];    

        
        snprintf(buffer, sizeof(buffer), "temp: %d, humi: %d", temperature, humidity);
		
        HAL_UART_Transmit(&huart1, (uint8_t *)buffer, strlen(buffer), HAL_MAX_DELAY);
    }
    HAL_Delay(3000);
    /* USER CODE BEGIN 3 */
}
  /* USER CODE END 3 */
}

dht11.c

#include "stm32f1xx.h"
#include "tim.h"
#include "DHT11.h"

uint8_t Data[5]={0x00,0x00,0x00,0x00,0x00};//存储温湿度

//微妙延时
void Delay_us(uint16_t us)
{
	uint16_t dif=0xffff-us-5;
	__HAL_TIM_SET_COUNTER(&htim1,dif);//设置TIM1计数器起始值
	HAL_TIM_Base_Start(&htim1);//启动
	
	while(dif<0xffff-5)
	{
		dif=__HAL_TIM_GET_COUNTER(&htim1);//查询计数
	}
	HAL_TIM_Base_Stop(&htim1);
}
void DHT_GPIO_SET_OUTPUT(void)//输出
{
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.Pin = GPIO_PIN_5;
  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 DHT_GPIO_SET_INPUT(void)//输入
{
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.Pin = GPIO_PIN_5;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  //GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

uint8_t DHT_Read_Byte(void)//读取一位信号
{
	uint8_t ReadData=0;//存放8bit数据
	uint8_t temp;			//临时存放信号电平
	uint8_t retry=0;	//
	uint8_t i;
	for(i=0;i<8;i++)//一次读取8位
	{
		while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_5)==0&&retry<100)//等待DHT11输出高电平
		{
			Delay_us(1);
			retry++;
		}
		retry=0;
		Delay_us(40);
		if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_5)==1)
		{
			temp=1;
		}
		else
			temp=0;
		while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_5)==1&&retry<100)
		{
			Delay_us(1);
			retry++;
		}
		retry=0;
		ReadData<<=1;//左移
		ReadData |=temp;
		
	}
	return ReadData;
	
}
//DHT11读取温湿度程序
uint8_t DHT_Read(void)
{
	uint8_t retry=0;
	uint8_t i;
	
	DHT_GPIO_SET_OUTPUT();//IO设置为输出模式
	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);//拉低电平18ms
	HAL_Delay(18);
	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET);//拉高电平20us
	Delay_us(20);
	
	DHT_GPIO_SET_INPUT();
	Delay_us(20);
	//如果检测到低电平,说明DHT11有响应
	if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_5)==0)
	{
		while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_5)==0&&retry<100)
		{
			Delay_us(1);
			retry++;
		}
		retry=0;
		while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_5)==1&&retry<100)
		{
			Delay_us(1);
			retry++;
		}
		retry=0;
		//一次传输40位,一次返回8位,共读取5次
		for(i=0;i<5;i++)
		{
			Data[i]=DHT_Read_Byte();
		}
		Delay_us(50);
	}

	//校验
	uint32_t sum=Data[0]+Data[1]+Data[2]+Data[3];
	 if((sum)==Data[4])    
		 return 1;  
	 else   
	 return 0;
}



 dht11.h

#ifndef __DHT11_H
#define __DHT11_H

#include "stm32f1xx.h"

void Delay_us(uint16_t us);
void DHT_GPIO_SET_OUTPUT(void);
void DHT_GPIO_SET_INPUT(void);
uint8_t DHT_Read_Byte(void);
uint8_t DHT_Read(void);
uint8_t DHT_Read_Data(uint8_t* temp , uint8_t* humi);
#endif

四、结果显示

将代码调试运行后,烧录到板子上,打开串口调试助手,结果如下:

  • 10
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值