首先,DHT11 在哪运行,不重要,重要的是,它与主机的通信,也就是与单片机STM32(GD32)
或者STM8 ,或者51也行
看懂通信逻辑原理图,然后,,模拟时序,对,就是读写数据,,
在单片机通常使用 延迟io 口时间,来达到此效果。为此,我不做过多解释,看代码,
代码参考正点原子DHT11,如有侵权,联系我删除!!
/*
DHT11 temperature sensor driver
*/
#ifndef DHT11_H_
#define DHT11_H_
#include <stdio.h>
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "driver/gpio.h"
#define DHT_OK 0
#define DHT_CHECKSUM_ERROR -1
#define DHT_TIMEOUT_ERROR -2
// == function prototypes =======================================
#define DHT11_PIN (12) //可通过宏定义,修改引脚
#define DHT11_CLR gpio_set_level(DHT11_PIN, 0)
#define DHT11_SET gpio_set_level(DHT11_PIN, 1)
#define DHT11_IN gpio_set_direction(DHT11_PIN, GPIO_MODE_INPUT)
#define DHT11_OUT gpio_set_direction(DHT11_PIN, GPIO_MODE_OUTPUT)
void DelayUs(uint32_t nCount);
uint8_t DHT11_ReadTemHum(uint8_t *temp,uint8_t *humi);
void DHT11_task(void);
#endif
下面是源码 .c 的实现
#include "DHT11.h"
static const char *TAG = "DHT11";
void DelayUs(uint32_t nCount){
esp_rom_delay_us(nCount);
}
static void DHT11_IO_IN(void)
{
esp_rom_gpio_pad_select_gpio(DHT11_PIN);
DHT11_IN;
}
static void OutputHigh(void){
DHT11_OUT;
DHT11_SET;
}
static void OutputLow(void){
DHT11_OUT;
DHT11_CLR;
}
static uint8_t getData(void){
return gpio_get_level(DHT11_PIN);
}
static void DHT11_Rst(void){
OutputLow();
DelayUs(19*1000);//拉低19ms(最多30,最少18ms)
OutputHigh();
DelayUs(30);//拉高30us(20-40us)
}
static uint8_t DHT11_Check(void){
uint8_t retry = 0;
DHT11_IO_IN();
while(getData() && retry < 100){
retry++;
DelayUs(1);
}
if(retry>=100)return 1;
else retry= 0;
while(!getData() && retry < 100){
retry++;
DelayUs(1);
}
if(retry>=100)return 1;
return 0;
}
static uint8_t DHT11_Read_Bit(void)
{
uint8_t retry=0;
while(getData()&&retry<100)//等待变为低电平
{
retry++;
DelayUs(1);
}
retry=0;
while(!getData()&&retry<100)//等待变高电平
{
retry++;
DelayUs(1);
}
DelayUs(40);//等待40us
if(getData())return 1;
else return 0;
}
static uint8_t DHT11_Read_Byte(void)
{
uint8_t i,dat;
dat=0;
for (i=0;i<8;i++)
{
dat <<=1;
dat|= DHT11_Read_Bit();
}
return dat;
}
uint8_t DHT11_ReadTemHum(uint8_t *temp,uint8_t *humi)
{
uint8_t buf[5];
uint8_t i;
DHT11_Rst();//发握手
if(DHT11_Check()==0)//检查是否存在
{
//ESP_LOGI(TAG,"ESP32H2 DHT11 exist!\r\n");
for(i=0;i<5;i++)//读取40位数据
{
buf[i]=DHT11_Read_Byte();
}
//ESP_LOGI(TAG,"ESP32H2 buf1(%d) buf2(%d) buf3(%d) buf4(%d),buf5(%d)!\r\n",buf[0],buf[1],buf[2],buf[3],buf[4]);
if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
{
*humi=buf[0];
*temp=buf[2];
}
}else return 1;
return 0;
}
void DHT11_task(void){
ESP_LOGI(TAG,"ESP32H2 DHT11 Start:%s,%s!\r\n",__DATE__,__TIME__);
}
注意,设备上电后1s 后,再读取数据。
本文介绍了如何在STM32单片机如GD32或STM8上使用DHT11温度湿度传感器,重点讲解了与主机通信的逻辑,包括模拟时序和延迟IO操作。提供了一个C语言实现的DHT11驱动代码示例,强调设备上电后1秒再读取数据的重要性。
339

被折叠的 条评论
为什么被折叠?



