【问题标题】:Trying to understanding a for loop that iterates through 40 bits试图理解迭代 40 位的 for 循环
【发布时间】:2019-08-29 01:18:57
【问题描述】:

我最近订购了一个 DHT22 温度和湿度传感器,以及一些我仍在等待的 arduino nanos,我正在阅读一些教程以及当我得到它们时我将要做的事情他们正在阅读如何使用非常简单的 DHT22,并且在阅读了数据表之后,他们对它们如何迭代 40 位数据很感兴趣,因为我之前从未在代码中使用过字节,所以查找了库它在这里https://github.com/markruys/arduino-DHT

DHT22 的数据表在这里https://cdn-shop.adafruit.com/datasheets/Digital+humidity+and+temperature+sensor+AM2302.pdf

这是循环位的主要代码块。

这就是我认为正在发生的事情;你有一个从 -3 开始的 8 位整数 i,因为它使用 3 位开始与传感器通信。 i

接下来是我不太了解的部分,while 循环,如果 pin 为高电平 - 1 并且 == (i(i being 0) & 1) 那么 while 循环将为 LOW,或者如果 i 为 1,则循环将很高。然后哪个流入 if 语句 if ( i >= 0 && (i & 1)), 但 i 最终不会总是 1 吗?如果不是什么在修改我?从我所看到的情况来看,您不想在信号为 LOW 时移动这些位?

我可以看到代码的其余部分在做什么我只是不理解它,第一个 if 语句在每个循环中移动 i 数据留下的位,如果信号为高电平 > 30 微秒,那么该位是1 和 1 被添加到数据中。

// We're going to read 83 edges:
// - First a FALLING, RISING, and FALLING edge for the start bit
// - Then 40 bits: RISING and then a FALLING edge per bit
// To keep our code simple, we accept any HIGH or LOW reading if it's max 85 usecs long

uint16_t rawHumidity = 0;  
uint16_t rawTemperature = 0;  
uint16_t data = 0;

for ( int8_t i = -3 ; i < 2 * 40; i++ ) {
  byte age;
  startTime = micros();
  do {
    age = (unsigned long)(micros() - startTime);
    if ( age > 90 ) {
      error = ERROR_TIMEOUT;
      return;
    }
  } while ( digitalRead(pin) == (i & 1) ? HIGH : LOW );

  if ( i >= 0 && (i & 1) ) {
    // Now we are being fed our 40 bits
    data <<= 1;

    // A zero max 30 usecs, a one at least 68 usecs.
    if ( age > 30 ) {
      data |= 1; // we got a one
    }
  }

  switch ( i ) {
    case 31:
      rawHumidity = data;
      break;
    case 63:
      rawTemperature = data;
      data = 0;
      break;
  }
}

// Verify checksum

if ( (byte)(((byte)rawHumidity) + (rawHumidity >> 8) + ((byte)rawTemperature) + (rawTemperature >> 8)) != data ) {
  error = ERROR_CHECKSUM;
  return;
}

【问题讨论】:

    标签: c++ arduino bit


    【解决方案1】:
    // We're going to read 83 edges:
    // - First a FALLING, RISING, and FALLING edge for the start bit
    // - Then 40 bits: RISING and then a FALLING edge per bit
    

    当“while”循环中断时,数据位左移:当 条件的三元运算符结果 (HIGH 或 LOW) 评估为 false。由于我们缺乏 HIGH 和 LOW 的定义,因此具体何时应该发生这种情况有点不清楚。

    但是,因为:

    • 全大写标识符一般表示该标识符代表一个宏,
    • 具有严格恒定真值的 HIGH 和 LOW 会使其中的三元表达式完全没有意义(如果为真,则为真,否则为假??)
    • 一些东西在这一切据说可以区分上升沿值和下降沿,
    • 几乎没有其他合理的地方可以发生这种情况(除非 pin 读取功能在内部完成,并且 cmets 讨论只是水冷的东西)

    ...我们可能应该假设它们每个都扩展为某种表达式,而 THAT 的结果决定了循环是否应该停止。

    因此,data &lt;&lt;= 1; 最有可能出现在以下情况:

    • digitalRead(pin) 高,*~something~*
    • digitalRead(pin) 低,*~something else~*

    据我所知,如果 ~something~~something else~ 取决于age 的值,这将是最有意义的。

    【讨论】:

      【解决方案2】:

      这就是我认为正在发生的事情;你有一个从 -3 开始的 8 位整数,因为 它使用 3 位开始与传感器通信。 i

      https://en.cppreference.com/w/cpp/language/operator_precedence

      *(作为乘法运算符)比&lt;(作为小于)具有更高的优先级,因此这些术语被分组以便首先解析*

      所以 (i

      接下来是我不太了解的部分,while 循环,如果 pin is high - 1 and is == (i(i being 0) & 1) 那么while循环将为LOW,或者如果i是 1 则循环为高电平。

      do { 
      ...
      }
      while ( digitalRead(pin) == (i & 1) ? HIGH : LOW );
      

      这里,== 具有更高的优先级,因此首先解析 (digitalRead(pin) == (i &amp; 1)。即,当digitalRead(pin) 为0 且i 为偶数时为真,digitalRead(pin) 为1 且i 为奇数。 [因为 (i & 1) 有效地测试了最低位] 然后解析三元子表达式,如果为真则返回 HIGH,如果为假则返回 LOW。

      必须奔跑,希望能帮助你。

      【讨论】:

      • 非常感谢。我想我现在明白了。无论出于何种原因,我认为您只能使用 & 1 或 0。仅在while循环为HIGH时确认数据位左移?
      • 显然我对内联回复来说太罗嗦了:查看其他答案
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-21
      • 2012-06-27
      • 1970-01-01
      • 2023-03-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多