esp32利用DHT11实现温湿度测量

//头文件:新建头文件以#include <DHT11.h>命名

#include <stdio.h>

#include "esp_system.h"

//#include "esp_spi_flash.h"

#include"spi_flash_mmap.h"

#include "esp_wifi.h"

#include "esp_event.h"

#include "esp_log.h"

#include "esp_err.h"

#include "nvs_flash.h"

#include "freertos/FreeRTOS.h"

#include "freertos/task.h"

#include "driver/ledc.h"

#include "driver/uart.h"

#include "driver/gpio.h"

#include "string.h"





#include <DHT11.h>

#define DHT11_PIN   15          //定义DHT11的引脚

#define uchar  unsigned char    //无符号字符型(8位)
#define uint8  unsigned char    //无符号字符型(8位)
#define uint16 unsigned short   //无符号短整型(16位)

//温湿度定义
uchar ucharFLAG;//电平标志位
uchar uchartemp;//位或运算中读取的校验位情况
uchar Humi,Humi_small,Temp,Temp_small;//温度、湿度两个量的整数位和小数位(输出变量)
//40bit每次,温湿度高低位为4*8=32bit,最后8个bit为校验位
uchar ucharT_data_H,ucharT_data_L,ucharRH_data_H,ucharRH_data_L,ucharcheckdata;//分别定义温湿度高位和低位以及校验位
uchar ucharT_data_H_temp,ucharT_data_L_temp,ucharRH_data_H_temp,ucharRH_data_L_temp,ucharcheckdata_temp;//(存储空间定义)
uchar ucharcomdata;//通过温湿度的四个字节算出的校验位

static void InputInitial(void)//设置端口为输入
{
  esp_rom_gpio_pad_select_gpio(DHT11_PIN);
  gpio_set_direction(DHT11_PIN, GPIO_MODE_INPUT);
}

static void OutputHigh(void)//设置函数输出1
{
  esp_rom_gpio_pad_select_gpio(DHT11_PIN);
  gpio_set_direction(DHT11_PIN, GPIO_MODE_OUTPUT);
  gpio_set_level(DHT11_PIN, 1);
}

static void OutputLow(void)//设置函数输出0
{
  esp_rom_gpio_pad_select_gpio(DHT11_PIN);
  gpio_set_direction(DHT11_PIN, GPIO_MODE_OUTPUT);
  gpio_set_level(DHT11_PIN, 0);
}

static uint8 getData()   //获取端口电平状态
{
	return gpio_get_level(DHT11_PIN);
}




static void COM(void)    // 温湿写入
{
    uchar i;
    for(i=0;i<8;i++)
    {
        ucharFLAG=2;
        //等待IO口变低,变低后,通过延时去判断是0还是1
        while((getData()==0)&&ucharFLAG++)
        esp_rom_delay_us(10);
        esp_rom_delay_us(35);//延时35us
        uchartemp=0;

        //如果这个位是1,35us后,还是1,否则为0
        if(getData()==1)
        {
    	uchartemp=1;
        ucharFLAG=2;
        }


        //等待IO口变高,变高后,表示可以读取下一位
        while((getData()==1)&&ucharFLAG++)
        esp_rom_delay_us(10);
        if(ucharFLAG==1)
          break;
        ucharcomdata<<=1;//左移1位为新位腾出空间
        ucharcomdata|=uchartemp;//位或操作存储新的位
    }
}


//
//static void COM(void)    //读取一个字节数据
//{
//    uchar i;
//    for(i=0;i<8;i++)
//    {
//        ucharFLAG=2;
//        //等待IO口变低,变低后,通过延时去判断是0还是1
//        while(getData()==0)//
//        esp_rom_delay_us(10);
//        esp_rom_delay_us(30);//延时30us
//        uchartemp=0;
//
//        //如果这个位是1,30us后,还是1,否则为0
//        if(getData()==1)
//        {
//         uchartemp=1;
//         ucharFLAG=2;
//        }
//
        else
        {
         uchartemp=0;
         ucharFLAG=2;
        }
//        //等待IO口变高,变高后,表示可以读取下一位
//        while(getData()==1)
//        esp_rom_delay_us(10);
//        if(ucharFLAG==1)
//          break;
//        ucharcomdata<<=1;//左移1位为新位腾出空间
//        ucharcomdata|=uchartemp;//位或操作存储新的位
//    }
//}


void Delay_ms(uint16 ms)//us级的精度循环延时达到ms级
{
	int i=0;
	for(i=0; i<ms; i++)//ms表示要延迟的毫秒数
	{
		esp_rom_delay_us(1000);
	}
}
//**************DHT11传感器启动***************
void DHT11(void)
{
    OutputLow();   //默认上拉为高电平
    Delay_ms(19);  //>18ms
    OutputHigh();
    InputInitial(); //输入
    esp_rom_delay_us(30);

    if(!getData())//表示传感器拉低总线
    {
        ucharFLAG=2;
        //等待总线被传感器拉高
        while((!getData())&&ucharFLAG++)
          esp_rom_delay_us(10);
        ucharFLAG=2;
        //等待总线被传感器拉低
        while((getData())&&ucharFLAG++)
          esp_rom_delay_us(10);
        COM();//读取第1字节,
        ucharRH_data_H_temp=ucharcomdata;
        COM();//读取第2字节,
        ucharRH_data_L_temp=ucharcomdata;
        COM();//读取第3字节,
        ucharT_data_H_temp=ucharcomdata;
        COM();//读取第4字节,
        ucharT_data_L_temp=ucharcomdata;
        COM();//读取第5字节,
        ucharcheckdata_temp=ucharcomdata;
        OutputHigh();
        //判断校验和是否一致
        uchartemp=(ucharT_data_H_temp + ucharT_data_L_temp + ucharRH_data_H_temp + ucharRH_data_L_temp);
        if(uchartemp==ucharcheckdata_temp)
        {
            //校验和一致,将对应温湿度值赋给存储变量
            ucharRH_data_H=ucharRH_data_H_temp;
            ucharRH_data_L=ucharRH_data_L_temp;
            ucharT_data_H=ucharT_data_H_temp;
            ucharT_data_L=ucharT_data_L_temp;
            ucharcheckdata=ucharcheckdata_temp;
            //保存温度和湿度
            Humi=ucharRH_data_H;
            Humi_small=ucharRH_data_L;
            Temp=ucharT_data_H;
            Temp_small=ucharT_data_L;
        }
        else//校验和不一致时:
        {
          Humi=100;
          Temp=100;
        }
    }
    else //没成功读取,返回0
    {
    	Humi=0,
    	Temp=0;
    }

    OutputHigh(); //输出,默认上拉恢复为原来的高电平
}
//将获取到的温湿度情况打印到屏幕上:
void app_main()
{
    //char dht11_buff[50]={0};

    while(1)
    {
      DHT11(); //读取温湿度
      printf("Temperature=%d.%d    RH=%d.%d%% \r\n", Temp,Temp_small,Humi,Humi_small);
      vTaskDelay(100);  //延时100毫秒
    }
}

DHT11在测温湿度的过程中精度不是很高,相比ds8b20测温度,精度在小数点后1位,下图是主程序运行的时序(单总线协议),代码源自esp32 采集dht11温湿度数据_esp32读取dht11-CSDN博客

仅在此基础上稍加修改注释。

  • 19
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值