旅人与风858 2023-04-22 21:40 采纳率: 42.9%
浏览 252
已结题

stm32 如何才能使dht11精确到小数点后两位

dht11如何才能精确到小数点后两位啊,还有这里为什么写的是<<8啊

img

img

  • 写回答

2条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-04-24 00:29
    关注
    不知道你这个问题是否已经解决, 如果还没有解决的话:
    • 给你找了一篇非常好的博客,你可以看看是否有帮助,链接:STM32利用滴答定时器实现高精度延时(在DHT11温湿度传感器中的应用)
    • 除此之外, 这篇博客: stm32实现DHT11读取温湿度中的 数据传输的数据 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

      一次完整的数据传输为40bits,也就是32位机的5个字节(byte),假如数据为buf[0]~buf[4],每个buf为一个unsigned char,或者其他8位的数据类型,buf[0]就是湿度的整数数据,buf[1]就是其湿度的小数部分,然后buf[2]就是温度的整数部分,buf[3]就是其温度的小数部分,buf[4]是校验和,也就是前面4个buf加起来的和。如果前面四个加起来等于校验和,说明数据传输成功,否则说明数据传输有问题。
      在这里插入图片描述

    • 以下回答来自chatgpt:

      解决方案: 在stm32中实现对dht11读取温湿度值的精确控制,需要对DHT11输出的波形进行解码,从而获取到温湿度数据。在解码波形的过程中,需要计算出低电平持续时间和高电平持续时间,用于将波形转换为二进制数。根据DHT11手册,温湿度数据分为整数和小数两部分,因此需要分别计算出整数和小数部分,再将它们组合成一个完整的数值。

      以下是代码示例:

      // 解码DHT11输出的波形,获取温湿度数据
      // 参数:data 保存温湿度数据的数组,长度为5
      // 返回值:成功返回0,失败返回负数
      int decode_dht11(uint8_t* data)
      {
          // 发送开始信号
          // 设置引脚为输出模式,并输出低电平
          GPIO_InitTypeDef GPIO_InitStruct;
          GPIO_InitStruct.Pin = GPIO_PIN_0;  // 选择引脚
          GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;  // 输出模式
          GPIO_InitStruct.Pull = GPIO_PULLUP;  // 上拉
          GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;  // 低速
          HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);  // 输出低电平
          HAL_Delay(20);  // 低电平持续时间至少18ms
          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);  // 输出高电平
          HAL_Delay(40);  // 高电平持续时间20-40us
      
          // 切换引脚为输入模式,接收DHT11响应信号
          GPIO_InitStruct.Mode = GPIO_MODE_INPUT;  // 输入模式
          HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
          uint32_t t = 0;
          while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_SET) {
              HAL_Delay(1);
              ++t;
              if (t > 80) {
                  return -1;  // 响应信号持续时间大于80us,通信失败
              }
          }
          t = 0;
          while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET) {
              HAL_Delay(1);
              ++t;
              if (t > 80) {
                  return -2;  // 响应信号持续时间大于80us,通信失败
              }
          }
          t = 0;
          while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_SET) {
              HAL_Delay(1);
              ++t;
              if (t > 80) {
                  return -3;  // 响应信号持续时间大于80us,通信失败
              }
          }
      
          // 解码温湿度数据
          uint8_t buffer[5];
          for (int j = 0; j < 5; ++j) {
              uint8_t d = 0;
              for (int i = 7; i >= 0; --i) {
                  // 测量低电平持续时间
                  t = 0;
                  while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET) {
                      HAL_Delay(1);
                      ++t;
                      if (t > 100) {
                          return -4;
                      }
                  }
      
                  HAL_Delay(40);
      
                  // 判断是否有高电平产生
                  if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_SET) {
                      d |= 1 << i;
                      // 测量高电平持续时间
                      t = 0;
                      while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_SET) {
                          HAL_Delay(1);
                          ++t;
                          if (t > 100) {
                              return -5;
                          }
                      }
                  }
              }
              buffer[j] = d;
          }
      
          // 数据校验
          uint8_t sum = buffer[0] + buffer[1] + buffer[2] + buffer[3];
          if (sum != buffer[4]) {
              return -6;  // 校验和错误
          }
      
          // 计算温度和湿度值
          int temp_int = (int)buffer[2];
          int temp_dec = (int)buffer[3];
          int humidity_int = (int)buffer[0];
          int humidity_dec = (int)buffer[1];
          data[0] = (uint8_t)(humidity_int * 10 + humidity_dec);
          data[1] = 0;
          data[2] = (uint8_t)(temp_int * 10 + temp_dec);
          data[3] = 0;
          data[4] = sum;
          return 0;
      }
      

      关于参考资料中的 <<8 操作,它是将一个8位的数左移8位,相当于将该数乘以256。在温湿度数据传输过程中,第1个字节表示湿度的整数部分,第2个字节表示湿度的小数部分,而温度的整数部分和小数部分分别在第3个和第4个字节中。为了将整数部分和小数部分组合成一个带小数的数值,需要将小数部分左移8位,相当于将它乘以256,再与整数部分相加。因此,代码中需要进行左移位运算,将小数部分左移8位,再与整数部分相加得到完整的温湿度数值。


    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 5月4日
  • 已采纳回答 4月26日
  • 创建了问题 4月22日

悬赏问题

  • ¥15 idea 编辑语言的选择
  • ¥15 Windows下部署Asmjit
  • ¥15 请问双层规划模型的上下层目标函数不一致,是如何保证迭代收敛性的
  • ¥15 微信小程序 前端页面内容搜索
  • ¥15 cpu是如何判断当前指令已经执行完毕,然后去执行下条指令的
  • ¥15 安装visual studio2022时visualstudiosetup启动不了,闪退。问题代号0x0和0x1389
  • ¥30 java spring boot2.5.3版本websocket连不上
  • ¥15 angular js调外部链接查看pdf
  • ¥15 openFOAM DPMFoam
  • ¥15 将查询到的值,赋值到table指定行中