欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

InitKit 开发之——DHT11温湿度传感器

程序员文章站 2022-07-13 17:15:42
...

之前画InitKit开发板都时候,画上了DHT11温湿度传感器,这样就可以实现手机APP查看环境温湿度的功能。最近刚好空了下来就写了一下关于DHT11的测试代码。

------------------------------------------------------------分割---------------------------------------------------------------------------------------

实验环境:

硬件:InitKit开发板,DHT11温湿度传感器,0.91寸OLED(IIC接口)

软件:MDK5,串口助手

PS:关于软件MDK5安装可以看这篇https://blog.csdn.net/initdev/article/details/80704205

DHT11电路原理图:(DAT脚接一个1K的上拉电阻就可以了)

InitKit 开发之——DHT11温湿度传感器

实物图:(请无视无关的连接)                                        

InitKit 开发之——DHT11温湿度传感器

PS:电路设计的时候,DHT11的数据脚连接到stm32的PB1上了。话不多说,直接上代码。

------------------------------------------------------------分割---------------------------------------------------------------------------------------

dht11.c部分

#include "dht11.h"

/*----------------------------------------------------------------------------/
/  InitKit  -  DHT11 						                 (C)Lin, 2018
/-----------------------------------------------------------------------------/
/ 本程序只供学习使用,未经作者许可,不得用于其它任何用途
/ 测试验证环境InitKit V1.0 开发板
/ RGB LED 驱动代码
/ Copyright (C) 2018, Lin, all right reserved.
/
/ * 修改日期:
/ * 版本:V1.0
/ * Copyright(C) InitDev 2018-2028
/
/-----------------------------------------------------------------------------/
修改记录
/
/---------------------------------------------------------------------------*/

uint8_t dht11Init(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(DHT11_DQ_Rcc, ENABLE);

    GPIO_InitStructure.GPIO_Pin = DHT11_DQ_Pin;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(DHT11_DQ_Port, &GPIO_InitStructure);
    GPIO_SetBits(DHT11_DQ_Port,DHT11_DQ_Pin);

    dht11Rst(); 
    
//    memset((uint8_t *)&temphumTypedef, 0, sizeof(tpTypedef_t)); 
    
    return dht11Check(); 
}
static void DHT11_IO_IN(void)
{
	 GPIO_InitTypeDef GPIO_InitStruct;
	 GPIO_InitStruct.GPIO_Pin = DHT11_DQ_Pin;
	 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
	 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
	 GPIO_Init(DHT11_DQ_Port, &GPIO_InitStruct);
}

static void DHT11_IO_OUT(void)
{
	 GPIO_InitTypeDef GPIO_InitStruct;
	 GPIO_InitStruct.GPIO_Pin = DHT11_DQ_Pin;
	 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
	 GPIO_Init(DHT11_DQ_Port, &GPIO_InitStruct);
}	

//Reset DHT11
static void dht11Rst(void)
{
    DHT11_IO_OUT(); 			            //SET OUTPUT
    DHT11_DQ_OUT=0; 			            //GPIOA.0=0
    delay_ms(20);    			            //Pull down Least 18ms
    DHT11_DQ_OUT=1; 			            //GPIOA.0=1
    delay_us(30);     			          //Pull up 20~40us
}

static uint8_t dht11Check(void)
{
    uint8_t retry=0;
    DHT11_IO_IN();                                              //SET INPUT
    while (DHT11_DQ_IN && (retry<100))                          //DHT11 Pull down 40~80us
    {
        retry++;
        delay_us(1);
    }

    if(retry >= 100)
    {
        return 1;
    }
    else
    {
        retry=0;
    }

    while (!DHT11_DQ_IN&& (retry < 100))		    //DHT11 Pull up 40~80us
    {
        retry++;
        delay_us(1);
    }

    if(retry >= 100)
    {
        return 1;	                        //check error
    }        

    return 0;
}

static uint8_t dht11ReadBit(void)
{
    uint8_t retry=0;
    while(DHT11_DQ_IN && (retry<100))                           //wait become Low level
    {
        retry++;
        delay_us(1);
    }

    retry = 0;
    while(!DHT11_DQ_IN && (retry < 100))		    //wait become High level
    {
        retry++;
        delay_us(1);
    }

    delay_us(30);//wait 40us

    if(DHT11_DQ_IN)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

static uint8_t dht11ReadByte(void)
{
    uint8_t i,dat;
    dat=0;
    for (i=0; i<8; i++)
    {
        dat<<=1;
        dat |= dht11ReadBit();
    }

    return dat;
}

//
//返回0有效,1无效
uint8_t dht11Read(uint8_t *temperature, uint8_t *humidity)
{
    uint8_t buf[5];
    uint8_t i;
    dht11Rst(); 
    if(0 == dht11Check()) 
    {
        for(i=0; i<5; i++)
        {
            buf[i] = dht11ReadByte();
        }
        if(buf[4] == (buf[0]+buf[1]+buf[2]+buf[3]))//根据校验位判断数据有效性
        {
             *humidity = buf[0];
            *temperature = buf[2];
        }
    }
    else
    {
        return 1;
    }
    return 0;
}

下面是dht11.h部分

#ifndef __DHT11_H
#define __DHT11_H

#include "main.h"

/*----------------------------------------------------------------------------/
/  InitKit  -  DHT11 						                 (C)Lin, 2018
/-----------------------------------------------------------------------------/
/ 本程序只供学习使用,未经作者许可,不得用于其它任何用途
/ 测试验证环境InitKit V1.0 开发板
/ RGB LED 驱动代码
/ Copyright (C) 2018, Lin, all right reserved.
/
/ * 修改日期:
/ * 版本:V1.0
/ * Copyright(C) InitDev 2018-2028
/
/-----------------------------------------------------------------------------/
修改记录
/
/---------------------------------------------------------------------------*/

/* DHT11端口与管脚定义 */
#define DHT11_DQ_Port	GPIOB
#define DHT11_DQ_Rcc	RCC_APB2Periph_GPIOB
#define DHT11_DQ_Pin	GPIO_Pin_1
									 
#define	DHT11_DQ_OUT  PBout(1) 
#define	DHT11_DQ_IN   PBin(1)   

/* Function declaration */
uint8_t dht11Init(void); //Init DHT11
uint8_t dht11Read(uint8_t *temperature, uint8_t *humidity);

static uint8_t dht11ReadByte(void);//Read One Byte
static uint8_t dht11ReadBit(void);//Read One Bit
static uint8_t dht11Check(void);//Chack DHT11
static void dht11Rst(void);//Reset DHT11    

#endif

使用时,在dht11.h中的DHT11管脚定义部分即可使用。当然,头文件需要支持uint8_t,PBout(x)之类的定义。

下面贴出部分示例代码,方便大家熟悉如何使用。

int main()
{
	delay_init();  	  //时钟初始化
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断分组配置
	UART1_Init(115200);
//	Esp_Uart_Init();
	OLED_Init();
	delay_ms(1);
	printf("//*********** InitKit V1.0 ************/\r\n");
	printf("/**** Usart1 port bound: 115200 ******/\r\n");
	printf("/**** Usart3 port bound: 115200 ******/\r\n");
	printf("/**** by linjianbo  time: 20180724 ***/\r\n");
	printf("start test.............................\r\n");
//TEST
	while(dht11Init());
//TEST	
	OLED_ShowString(0,0,"Temp:",8);
	OLED_ShowString(0,2,"Humi:",8);
	while(1)
	{
		while(dht11Read(&Systemp,&Syshumidity)==1);
		sep_send_buff[0] = Systemp/100+0x30;
		sep_send_buff[1] = Systemp%100/10+0x30;
		sep_send_buff[2] = Systemp%10+0x30;
		sep_send_buff[3] = 'C';
		printf("Tempture:%s\r\n",sep_send_buff);
		OLED_ShowString(5*8,0,sep_send_buff,8);
		
		sep_send_buff[0] = Syshumidity/100+0x30;
		sep_send_buff[1] = Syshumidity%100/10+0x30;
		sep_send_buff[2] = Syshumidity%10+0x30;
		sep_send_buff[3] = '%';
		printf("humidity:%s\r\n",sep_send_buff);
		OLED_ShowString(5*8,2,sep_send_buff,8);
		delay_ms(500);
	}
}

实际运行效果:

串口助手显示InitKit 开发之——DHT11温湿度传感器

OLED显示效果

InitKit 开发之——DHT11温湿度传感器

有问题的或者对这方面感兴趣的小伙伴欢迎关注的公众号,一起学习,一起进步。

InitKit 开发之——DHT11温湿度传感器