STM32CubeMX系列|DHT11温湿度传感器

DHT11温湿度传感器

1. DHT11简介

DHT11是一款温湿度一体化的数字传感器,该传感器包括一个电阻式测湿元件和一个NTC测温元件,并与一个高性能8位单片机连接。通过单片机微处理器简单的电路连接就能够实时的采集湿度和温度。DHT11与STM32之间能采用简单的单总线进行通讯,仅需一个IO口。传感器内部温度和湿度数据40个bit的数据一次性传给单片机,数据采用校验和方式进行校验,有效的保证数据传输的准确性。
DHT11采用单总线数据格式,即单个数据引脚端口完成输入输出双向传输。其数据包由5个字节(40Bit)组成。数据分小数和整数部分,一次完整的数据传输为40bit,高位先出。数据格式如下图示

在这里插入图片描述
根据以上数据,即可算出温度和湿度的值,计算方法如下:

湿度 = byte4.byte3
温度 = byte2.byte1
校验 = byte4 + byte3 + byte2 + byte1

DHT11和单片机的一次通讯最大为3ms左右,建议主机连续读取时间间隔不要小于100ms,下面是DHT11的三种时序:

  • 数据发送时序:首先主机发送开始信号,即拉低数据线保持t1(至少18ms)时间,接着拉高数据线t2(20 ~ 40us)时间;然后读取DHT11的响应,正常的话DHT11会拉低数据线并保持t3(40 ~ 50us)时间作为响应信号,接着DHT11拉高数据线并保持t4(40 ~ 50us)时间后,开始传输数据

在这里插入图片描述

  • DHT11输出0时序

在这里插入图片描述

  • DHT11输出1时序

在这里插入图片描述

2. 硬件设计

D1指示灯用来提示系统运行状态,PG11连接DHT11温湿度传感器用来检测环境温湿度,串口1用来打印温度值

  • D1指示灯
  • PG11
  • USART1
  • TIM7(提供us延时)

3. 软件设计

3.1 STM32CubeMX设置
  • RCC设置外接HSE,时钟设置为72M
  • PC0设置为GPIO推挽输出模式、上拉、高速、默认输出电平为高电平
  • USART1选择为异步通讯方式,波特率设置为115200Bits/s,传输数据长度为8Bit,无奇偶校验,1位停止位
  • PG11设置为GPIO推挽输出模式、上拉、高速
  • 激活TIM7,预分频因子设为72-1,向上计数,自动重载值为65535;因此计数器CNT_CLK = 1MHz,计数器周期为1us

在这里插入图片描述

  • 输入工程名,选择工程路径(不要有中文),选择MDK-ARM V5;勾选Generated periphera initialization as a pair of ‘.c/.h’ files per IP ;点击GENERATE CODE,生成工程代码
3.2 MDK-ARM编程
  • 在tim.c文件下实现微秒延时(us)函数
void delay_us(uint16_t us){
    
    
	uint16_t differ = 0xffff-us-5;				
	__HAL_TIM_SET_COUNTER(&htim7,differ);	//设定TIM7计数器起始值
	HAL_TIM_Base_Start(&htim7);		//启动定时器	
	
	while(differ < 0xffff-5){
    
    	//判断
		differ = __HAL_TIM_GET_COUNTER(&htim7);		//查询计数器的计数值
	}
	HAL_TIM_Base_Stop(&htim7);
}
  • 创建按键驱动文件DHT11.c 和相关头文件DHT11.h
void DHT11_IO_IN(void){
    
    		//IO口方向设置为输入
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.Pin = GPIO_PIN_11;
	GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
	HAL_GPIO_Init(GPIOG,&GPIO_InitStructure);
}

void DHT11_IO_OUT(void){
    
    	//IO口方向设置为输出
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.Pin = GPIO_PIN_11;
	GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(GPIOG,&GPIO_InitStructure);
}

void DHT11_Rst(void){
    
                     
	DHT11_IO_OUT(); 	//设置为输出
	DHT11_DQ_OUT_LOW; 	//拉低
	HAL_Delay(20);    	//至少18ms
	DHT11_DQ_OUT_HIGH; 	//拉高 
	delay_us(30);     	//至少20~40us
}

uint8_t DHT11_Check(void){
    
       
	uint8_t retry=0;
	DHT11_IO_IN();      
	while (DHT11_DQ_IN&&retry<100){
    
    	//拉低40~80us
		retry++;
		delay_us(1);
	};	 
	if(retry>=100)return 1;
	else retry=0;
	while (!DHT11_DQ_IN&&retry<100){
    
     //拉高40~80us
		retry++;
		delay_us(1);
	};
	if(retry>=100)return 1;	    
	return 0;	//检测到DHT11返回0
}

uint8_t DHT11_Read_Bit(void){
    
    
 	uint8_t retry=0;
	while(DHT11_DQ_IN&&retry<100){
    
    	//等待变为低电平
		retry++;
		delay_us(1);
	}
	retry=0;
	while(!DHT11_DQ_IN&&retry<100){
    
    	//等待变为高电平
		retry++;
		delay_us(1);
	}
	delay_us(40);	//等待40us
	if(DHT11_DQ_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(uint16_t *temp,uint16_t *humi){
    
            
 	uint8_t buf[5];
	uint8_t i;
	DHT11_Rst();
	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]<<8) + buf[1];
			*temp=(buf[2]<<8) + buf[3];
		}
	}else return 1;
	return 0;	    
}
  	 
uint8_t DHT11_Init(void){
    
    
    GPIO_InitTypeDef GPIO_Initure;	//PG11的初始化已经在cubemx中完成,可以忽略此段初始化代码
    __HAL_RCC_GPIOG_CLK_ENABLE();			
    GPIO_Initure.Pin=GPIO_PIN_11;           
    GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  
    GPIO_Initure.Pull=GPIO_PULLUP;         
    GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOG,&GPIO_Initure);    
    DHT11_Rst();
	return DHT11_Check();
}
  • 在main.c文件下编写DHT11测试代码
int main(void){
    
    
  /* USER CODE BEGIN 1 */
  uint16_t temperature;
  uint16_t humidity;
  /* USER CODE END 1 */
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_TIM7_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  while(DHT11_Init()){
    
    
	printf("DHT11 Checked failed!!!\r\n");
	HAL_Delay(500);
  }
  printf("DHT11 Checked Sucess!!!\r\n");
  /* USER CODE END 2 */
  while (1){
    
    
    DHT11_Read_Data(&temperature,&humidity);
	printf("DHT11 Temperature = %d.%d degree\r\n",temperature>>8,temperature&0xff);
	printf("DHT11 Humidity = %d.%d%%\r\n",humidity>>8,humidity&0xff);		
	HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);
	HAL_Delay(500);
  }
}

4. 下载验证

编译无误下载到开发板后,可以看到D1指示灯不断闪烁,串口不断打印出当前温湿度值。串口输出如下信息:

DHT11 Checked Sucess!!!
DHT11 Temperature = 28.20 degree
DHT11 Humidity = 30.21%

关注我的公众号,在公众号里发如下消息,即可获取相应的工程源代码:

玩转STM32CubeMX | DHT11温湿度传感器

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Chuangke_Andy/article/details/108848485