//头文件:新建头文件以#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博客
仅在此基础上稍加修改注释。