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

版权声明:Initdev https://blog.csdn.net/Initdev/article/details/81192904

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

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

实验环境:

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

软件:MDK5,串口助手

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

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

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

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);
	}
}

实际运行效果:

串口助手显示

OLED显示效果

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

猜你喜欢

转载自blog.csdn.net/Initdev/article/details/81192904