STM8 DHT11温湿度传感器

  DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,信号传输距离可达20米以上。

型号温度范围温度精度湿度范围湿度精度
DHT110~50°C±2°C20~90%RH±5%RH

一.接口说明

在这里插入图片描述  建议连接线长度短于20米时用5K上拉电阻,大于20米时根据实际情况使用合适的上拉电阻,供电电压3~5.5V.

二.通信协议

单总线通信,数据获取间隔建议大于1s.

通信总过程

通信总过程如下图1:
图1 通信总过程

图1 通信总过程

  总线空闲状态为高电平,主机把总线拉低等待DHT11响应,主机把总线拉低必须大于18毫秒,保证DHT11能检测到起始信号。DHT11接收到主机的开始信号后,等待主机开始信号结束,然后发送80us低电平响应信号.主机发送开始信号结束后,延时等待20-40us后, 读取DHT11的响应信号,主机发送开始信号后,可以切换到输入模式,或者输出高电平均可, 总线由上拉电阻拉高。

起始信号

图2 起始信号

图2 起始信号

  总线为低电平,说明DHT11发送响应信号,DHT11发送响应信号后,再把总线拉高80us,准备发送数据,每一bit数据都以50us低电平时隙开始,高电平的长短定了数据位是0还是1.格式见下面图示.如果读取响应信号为高电平,则DHT11没有响应,请检查线路是否连接正常.当最后一bit数据传送完毕后,DHT11拉低总线50us,随后总线由上拉电阻拉高进入空闲状态。

数据信号

数字0信号表示方法如图3所示:
图3 信号0

图3 信号0

数字1信号表示方法.如图4所示:
图4 信号1
图4 信号1

数据解析

一次完整的数据传输为40bit,高位先出。
数据格式:
  8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据 +8bit校验和
  数据传送正确时校验和数据等于“8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据”所得结果的末8位。

三. 封装与引脚对应

图5 封装

图5 封装

引脚说明

Pin名称注释
1VDD供电3~5.5V
2DATA数据
3NC空脚
4GND

四. 代码

时钟初始化(重要):单总线有us级时序要求,延时与主频相关

/**
  * @brief  系统时钟初始化
  * @param  None
  * @retval None
  */
static void System_Timer_Init(void)
{
    CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);    /*时钟   初始化时钟为1分频 16M   2分频8M*/
}

DHT11数据读取程序:ms级延时来自于一个定时器,us级延时由逻辑分析仪测试加实验调整获得。

#include <stm8s.h>
#include <stdbool.h>
#include <string.h>
#include "bsp_task.h"
#include "hw_DHT11_driver.h"

#define DHT11_PORT  GPIOC
#define DHT11_PIN   GPIO_PIN_6

#define DHT11_OUT   GPIO_Init(DHT11_PORT, DHT11_PIN, GPIO_MODE_OUT_PP_HIGH_FAST)   //输出模式
#define DHT11_IN    GPIO_Init(DHT11_PORT, DHT11_PIN, GPIO_MODE_IN_PU_NO_IT)        //输入模式
#define DHT11_H     GPIO_WriteHigh(DHT11_PORT,DHT11_PIN)                           //输出高
#define DHT11_L     GPIO_WriteLow(DHT11_PORT,DHT11_PIN)                            //输出低
#define DHT11_READ  GPIO_ReadInputPin(DHT11_PORT,DHT11_PIN)                        //数据读出

static bool hw_dht11_data_get(uint8_t *data);
static uint8_t debug[5] = {0};

/**
  * @brief  us级延时--非精准
  * @param  us  延时计数  24==100us 12==52.5us
  * @retval None
  */
static void hw_dht11_delay_us(uint32_t us)
{
  while(us--);
}

/**
  * @brief  获得DHT11 1 bit数据
  * @param  None
  * @retval 数据
  */
static uint8_t hw_dht11_bit_get(void)
{
    uint8_t temp = 0;
    for(int j = 0; j < 8; j++)      //获取一个字节
    {
        while(DHT11_READ == RESET); //等待字节起始低电平结束
        hw_dht11_delay_us(8);      	//大于40us (要求大于30us,小于70us)
        temp <<= 1;
        if(DHT11_READ != RESET)
        {
            temp |= 0x01;
        }
        while(DHT11_READ != RESET); //等待高电平结束
    }
    return temp;
}


/**
  * @brief  获得DHT11温湿度数据
  * @param  data  数据接收缓存(5字节)
  * @retval true 获取成功   false 获取失败
  * @note   采样间隔必须大于1s,采样过程禁止打断
  */
static bool hw_dht11_data_get(uint8_t *data)
{
    DHT11_OUT;
    DHT11_H;                //准备--总线空闲
    Task_Delay_Ms_Time(2);  //延时2ms
    
    DHT11_L;                //总线拉低--主机开始信号
    Task_Delay_Ms_Time(25); //保持25ms --大于18ms
    DHT11_H;                //结束开始信号
    hw_dht11_delay_us(10);  //延时 20us~40us
    DHT11_IN;               //切换输入模式 准备读响应

    if(DHT11_READ != RESET)     //未检测到应答
    {
        return false;
    }
    while(DHT11_READ == RESET); //等待应答结束
    while(DHT11_READ != RESET); //等待DHT11发送起始高电平结束
    
    for(int i = 0; i < 5; i++)  //共5字节
    {
        data[i] = hw_dht11_bit_get();
    }
    
    DHT11_OUT;
    DHT11_H;                	//准备--总线空闲
    return true;
}


/**
  * @brief  获得DHT11温湿度数据
  * @param  temp 温度     hum 湿度
  * @retval false 数据错误  true 数据正常
  */
bool hw_dht11_th_count(uint16_t *temp,uint16_t *hum)
{
    uint8_t dht11_data[5] = {0};
    if(!hw_dht11_data_get(dht11_data))
      return false;
    memcpy(debug,dht11_data,5);
    if(dht11_data[0] + dht11_data[1] + dht11_data[2] + dht11_data[3] != dht11_data[4])
      return false;
      
    *hum = 0xf0 | dht11_data[0];
    *hum <<= 8;
    *hum |= dht11_data[1];
    
    *temp = 0xf0 | dht11_data[2];
    *temp <<= 8;
    *temp |= dht11_data[3];

    return true;
}





五.文章引用

https://blog.csdn.net/u013151320/article/details/50389624
https://wenku.baidu.com/view/29bc6e8fb4daa58da1114a3a.html
https://blog.csdn.net/qq_27508477/article/details/83661672

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要使用STM32与DHT11传感器进行温湿度采集,可以参考以下步骤: 1. 首先需要连接STM32和DHT11传感器,可以使用数字引脚或模拟引脚进行连接。 2. 在STM32上编写程序,通过GPIO口读取DHT11传感器的数据。具体可参考以下代码: ``` GPIO_InitTypeDef GPIO_InitStruct; TIM_TimeBaseInitTypeDef TIM_InitStruct; // 配置GPIO口 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStruct.GPIO_OType = GPIO_OType_OD; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA, &GPIO_InitStruct); // 发送启动信号 GPIO_ResetBits(GPIOA, GPIO_Pin_0); delay_ms(18); GPIO_SetBits(GPIOA, GPIO_Pin_0); delay_us(30); // 配置GPIO口为输入模式 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStruct); // 等待DHT11响应 while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == Bit_SET); while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == Bit_RESET); while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == Bit_SET); // 读取DHT11数据 for (i = 0; i < 40; i++) { while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == Bit_RESET); start_time = TIM_GetCounter(TIM2); while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == Bit_SET); end_time = TIM_GetCounter(TIM2); if (end_time - start_time > 40) { data[i] = 1; } else { data[i] = 0; } } ``` 3. 解析DHT11传感器的数据,获取到温度和湿度值。具体可参考以下代码: ``` uint8_t rh_byte1, rh_byte2, temp_byte1, temp_byte2, check_sum; uint16_t humidity, temperature; rh_byte1 = data[0]; rh_byte2 = data[1]; temp_byte1 = data[2]; temp_byte2 = data[3]; check_sum = data[4]; if (rh_byte1 + rh_byte2 + temp_byte1 + temp_byte2 == check_sum) { // 计算湿度和温度值 humidity = (rh_byte1 << 8) | rh_byte2; temperature = (temp_byte1 << 8) | temp_byte2; temperature = temperature & 0x7FFF; // 清除最高位的符号位 if (temp_byte1 & 0x80) { temperature = -temperature; } } else { // 数据校验错误 } ``` 4. 将温度和湿度值存储到变量中,或者发送到其他设备进行处理。 需要注意的是,DHT11传感器的数据读取需要严格按照其协议进行,否则会出现数据错误或读取失败的情况。在实际开发中,可以使用定时器进行精确的时间控制,避免因为硬件延时等原因导致读取错误。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值