GD32F4xx系列单片机之DHT22实现温度、湿度输出

话不多说,先上DHT22的时序图。

DHT22响应

在这里插入图片描述
在这里插入图片描述
1. 总线先输出低电平(至少500us),之后总线再输出高电平(20~40us)。
2. DHT22接受到信号之后,发出响应,首先拉低总线80us,之后再次拉高总线80us之后开始数据传输。

DHT22开始传输数据

在这里插入图片描述
数据传输过程如图
首先DHT22会拉低总线50us,之后开始拉高总线进行数据传输,当高电平持续70us时,代表数据“1”,26~28us时代表数据“0”,之后重复,直至数据传输完成。

DHT22数据格式

在这里插入图片描述
此时要注意的是传感器输出的温湿度值要除以10才得到真正的温湿度值

之后我们根据时序图开始编写代码

/****************************************************************
title:DHT22.h





****************************************************************/
#ifndef __DHT22_H
#define __DHT22_H 

#include "gd32f4xx.h"
#include "systick.h"

//宏定义,DHT22的GPIO口和引脚
#define DHT22_Pin    GPIO_PIN_4
#define DHT22_GPIO    GPIOA
#define DHT22_RCU    RCU_GPIOA

//DHT22作为从机发送给主机信号,所以是读取DHT11的GPIO口和引脚的输入状态
#define DHT22_Input    gpio_input_bit_get(DHT22_GPIO,DHT22_Pin)

//主机发送开始信号。拉低数据线,然后拉高数据线t2时间,然后读取DHT22的响应。
#define DHT22_Low    gpio_bit_reset(DHT22_GPIO,DHT22_Pin)
#define DHT22_High    gpio_bit_set(DHT22_GPIO,DHT22_Pin)

//初始化DHT11的IO口        
void DHT22_Init(void);
//主机需要发送开始信号,然后读取数据。
//这是配置DHT11的输入输出模式
//cmd = 1,配置为输出模式
//cmd = 0,配置为输入模式
void DHT22_Read_Out_Input(uint8_t cmd);
//复位DHT22
void DHT22_Rst(void);
//等待DHT22的回应
//返回1:未检测到DHT22的存在
//返回0:存在   出现由低到高的变化即可
uint8_t DHT22_Check(void) ;
//从DHT22读取一个位
//返回值:1/0
uint8_t DHT22_Read_Bit(void) ;
//从DHT22读取一个字节
//返回值:读到的数据
uint8_t DHT22_Read_Byte(void)  ;
//从DHT22读取一次数据
//temp:温度值(范围:-40--80°)
//humi:湿度值(范围:0%--99.9%)
//返回值:0,正常;1,读取失败
uint8_t DHT22_Read_Data(float *temp,float *humi)  ;


#endif

/***************************************************
title:DHT22.c




***************************************************/
#include "gd32f4xx.h"
#include "DHT22.h"
#include "systick.h"
   

//初始化DHT22的IO口        
void DHT22_Init(void)
{     
    rcu_periph_clock_enable(DHT22_RCU);//开启时钟
    gpio_mode_set(DHT22_GPIO,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,DHT22_Pin);
    gpio_output_options_set(DHT22_GPIO,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,DHT22_Pin);
} 

//主机需要发送开始信号,然后读取数据。
//这是配置DHT22的输入输出模式
//cmd = 1,配置为输出模式
//cmd = 0,配置为输入模式
void DHT22_Read_Out_Input(uint8_t cmd)
{    
    if(cmd == 1)
    {
        gpio_mode_set(DHT22_GPIO,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,DHT22_Pin);
        gpio_output_options_set(DHT22_GPIO,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,DHT22_Pin);
    }
    else
    {
     gpio_mode_set(DHT22_GPIO,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,DHT22_Pin);
    }
}
//复位DHT22
void DHT22_Rst(void)	   
{                 
	DHT22_Read_Out_Input(1); 	//SET OUTPUT
    DHT22_Low; 	         //拉低DQ
    delay_1ms(1);    	//拉低至少500us,此处1ms
    DHT22_High; 	    //DQ=1 
	delay_1us(30);     	//主机拉高20~40us(这里是我自定义修改的函数,原函数库中是没有1us的延时函数的)
}
//等待DHT22的回应
//返回1:未检测到DHT22的存在
//返回0:存在   出现由低到高的变化即可
uint8_t DHT22_Check(void) 	   
{   
	uint8_t retry=0;
	DHT22_Read_Out_Input(0); //SET INPUT	 
	
    while (DHT22_Input==SET&&retry<100)//DHT22会拉低80us左右
	{
		retry++;
		delay_1us(1);
	} 
	if(retry>=100)return 1;
	else retry=0;
    while (DHT22_Input==RESET&&retry<100)//DHT22拉低后会再次拉高80us左右
	{
		retry++;
		delay_1us(1);
	}
	if(retry>=100)return 1;	    
	return 0;
}

//从DHT22读取一个位
//返回值:1/0
uint8_t DHT22_Read_Bit(void) 			 
{
 	uint8_t retry=0;
	while(DHT22_Input==SET&&retry<100)//等待变为低电平
	{
		retry++;
		delay_1us(1);
	}
	retry=0;
	while(DHT22_Input==RESET&&retry<100)//等待变高电平
	{
		retry++;
		delay_1us(1);
	}
	delay_1us(40);//等待40us
	if(DHT22_Input==SET)return 1;
	else return 0;		   
}

//从DHT22读取一个字节
//返回值:读到的数据
uint8_t DHT22_Read_Byte(void)    
{        
    uint8_t i,dat;
    dat=0;
   for (i=0;i<8;i++) 
  {
      dat<<=1; 
     dat|=DHT22_Read_Bit();
    }				    
    return dat;
}


//从DHT22读取一次数据
//temp:温度值(范围:-40--80°)
//humi:湿度值(范围:0%--99.9%)
//返回值:0,正常;1,读取失败
uint8_t DHT22_Read_Data(float *temp,float *humi)  
{        
 	uint8_t buf[5];
	uint8_t i;
	DHT22_Rst();
	if(DHT22_Check()==0)
	{
		for(i=0;i<5;i++)//读取40位数据
		{
			buf[i]=DHT22_Read_Byte();
		}
		if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
		{
			*humi=((float)((buf[0]<<8)+buf[1]))/10;
			*temp=((float)((buf[2]<<8)+buf[3]))/10;
		}
	}else return 1;
	return 0;	    
}



/***********************************************
title:main.c


*********************************************************/
/*!
    \file    main.c
    \brief   led spark with systick

    \version 2016-08-15, V1.0.0, firmware for GD32F4xx
    \version 2018-12-12, V2.0.0, firmware for GD32F4xx
    \version 2020-09-30, V2.1.0, firmware for GD32F4xx
    \version 2022-03-09, V3.0.0, firmware for GD32F4xx
*/

/*
    Copyright (c) 2022, GigaDevice Semiconductor Inc.

    Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

    1. Redistributions of source code must retain the above copyright notice, this
       list of conditions and the following disclaimer.
    2. Redistributions in binary form must reproduce the above copyright notice,
       this list of conditions and the following disclaimer in the documentation
       and/or other materials provided with the distribution.
    3. Neither the name of the copyright holder nor the names of its contributors
       may be used to endorse or promote products derived from this software without
       specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
*/

#include "gd32f4xx.h"
#include "systick.h"
#include <stdio.h>
#include "main.h"
#include "sys.h"
#include "bsp_usart.h"
#include "DHT22.h"

/*!
    \brief    main function
    \param[in]  none
    \param[out] none
    \retval     none
*/

int main(void)
{
float temp,humi;
    systick_config();//滴答定时器分频
    led_gpio_config();//led初始化	
    usart_gpio_config(9600);//串口初始化,并且设置波特率为9600
	DHT22_Init();//DHT22初始化
	DHT22_Rst();//DHT22复位
    delay_1ms(1000);
	
while(1)
{
	if(DHT22_Read_Data(&temp,&humi)==0)
	{
	printf("temp=%.2f,humi=%.2f/n",temp,humi);
	}
}
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于STM32单片机的DHT11温度湿度测量是一种将STM32单片机与DHT11传感器进行连接,通过编写相应的程序实现温度湿度的测量的方法。 首先,需要将DHT11传感器与STM32单片机进行连接。将DHT11的VCC引脚接到STM32单片机的VCC引脚,将DHT11的GND引脚接到STM32单片机的GND引脚,将DHT11的数据引脚接到STM32单片机的GPIO引脚。然后,在STM32单片机上编写程序,通过GPIO引脚与DHT11进行数据的交互和读取。 编写程序时,可以使用STM32单片机的GPIO库函数,通过配置GPIO引脚为输入模式,读取DHT11传感器的数据。在读取数据之前,需要向DHT11发送开始信号,并等待一段时间。然后,通过读取GPIO引脚的电平变化来获取DHT11传感器的温度湿度数据。 根据DHT11传感器的协议,温度湿度数据的格式是特定的,需要进行数据的解析和计算。通过解析数据,可以得到温度湿度的数值。接下来,可以将这些数值显示在液晶显示屏或通过串口发送到计算机进行进一步处理。 在程序的实现过程中,需要注意时序的控制和数据的正确解析。同时,还需考虑程序的健壮性和稳定性,例如在读取数据时加入错误处理和校验,以提高测量的准确性和可靠性。 总之,基于STM32单片机的DHT11温度湿度测量是一种通过连接硬件和编写程序实现的方法,能够实时地获取环境的温度湿度信息,并具有广泛的应用领域,如智能家居、气象站等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值