【问题标题】:Arduino bitwise runninglight with a single delay具有单次延迟的 Arduino 按位运行灯
【发布时间】:2021-02-12 14:17:39
【问题描述】:

我的任务是在我的 Arduino 上创建一个运行灯,具有以下要求/约束​​

要求

  • 使用 3 个 LED 实现所谓的“运行灯”。
  • 每个 LED 的开启时间相同,均为 0.5 秒。
  • 最后一个 Led 点亮后,第一个 Led 再次启动。

约束

  • LED 连接到 Arduino 的引脚 8,9 和 10。 (别忘了电阻)
  • 运行的led必须在Arduino的循环中实现
  • setup() 函数可以包含任何 Arduino 函数/宏。
  • 循环中只允许使用 Arduino 函数 delay()。
  • 循环中不使用任何其他 Arduino 函数/宏等。
  • 在 loop() 函数中不使用 for/while
  • 不使用您自己定义的函数
  • 您的循环函数必须包含不超过 10 个语句。
  • 所以在循环中你只能使用 o 延迟功能 o 你的变量 o 以下字符/数字:* ( ) & ~ | ; = ! + - 0 1 2 3 4 5 6 7 8 9

我试过下面的代码

    #include <Arduino.h>
    
    //mask for setting correct bits in register to setup leds to 1
    #define DDBMASK 0x07
    
    //masks for setting correct bits in register for led control to 1
    #define LEDMASK 0x01
    
    byte *ddBPtr;   //point to ddB register (data direction)
    byte *portBPtr; //point to portB resiger (data register)
    
    void setup() {
      //setup data direction register to set pins to output
      ddBPtr = (byte *) 0x24;
      *ddBPtr |= DDBMASK; // 0b0000 0111
    
      //assign pointer to right register
      portBPtr = (byte *) 0x25;
    }
    
    void loop() {
      //use data register (portB) for controlling leds
      *portBPtr ^= LEDMASK;
      delay(500);
      *portBPtr ^= LEDMASK;
    
      *portBPtr ^= LEDMASK << 1;
      delay(500);
      *portBPtr ^= LEDMASK << 1;
    
      *portBPtr ^= LEDMASK << 2;
      delay(500);
      *portBPtr ^= LEDMASK << 2;
}

显然,只有一个延迟函数并遵循要求和约束,这是可能的。我已经坚持了好几个小时,无法弄清楚。

我尝试了以下方法,但也无法正常工作,因为我无法将计数器重置为零

void loop() {
  //use data register (portB) for controlling leds
  *portBPtr ^= (LEDMASK << ledCount);
  delay(500);
  *portBPtr ^= (LEDMASK << ledCount);
  ledCount++;
  //cant figure out a way to reset ledCount back to 0 after 3 itterations
  //running light only runs once so first led does not light after third led is lit
}

我错过了什么?

【问题讨论】:

  • 一个理智的解决方案看起来像for(int i=0; i&lt;3; i++) { PORTB = 1u &lt;&lt; (i + offset); delay(500); }。随意将高尔夫“编码”成适合您的人工要求的东西。

标签: c arduino bit-manipulation


【解决方案1】:

也许是这样的:

*portBPtr |= (1 << ledCount);
delay(500);
*portBPtr &= ~(1 << ledCount);
ledCount = (9 >> (ledCount << 1)) & 3;

这也避免了不在您的允许符号列表中的^

ledCount = (9 &gt;&gt; (ledCount &lt;&lt; 1)) &amp; 3 行就像一个查找表,每个条目占用两位。它将0映射到1、1映射到2、2映射到0。这段代码的正常写法是ledCount = (1 + ledCount) % 3;

这也可能有效,但更简单一些:

delay(500);
*portBPtr = (1 << ledCount);
ledCount = (9 >> (ledCount << 1)) & 3;

使用赋值而不是 |或 & 或 ^,所有其他位将为零,可能会导致非电流 LED 关闭。

【讨论】:

  • 抱歉回复晚了!您展示的解决方案对我来说很有意义。这是我的第一个任务,我很难掌握这些限制,感谢您对代码的清晰解释。感谢保罗的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多