Arduino 按位运行灯,具有单一延迟

问题描述 投票:0回答:1

我的任务是在我的 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 iterations
  //running light only runs once so first led does not light after third led is lit
}

我错过了什么?

c arduino bit-manipulation
1个回答
0
投票

也许是这样:

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

这也避免了

^
不在您允许的符号列表中。

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

这也可能有效,稍微简单一点:

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

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

© www.soinside.com 2019 - 2024. All rights reserved.