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
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值