在一整秒内每 X 毫秒在一个值之间循环的条件

Condition for cycling between a value each X milliseconds within a full second

我正在使用一个微控制器,它有一个自启动后每 1 毫秒计数一次的中断。

我有一个介于 0 和 999 之间的变量,如果经过的时间小于 x 毫秒(在以下示例中为 500 毫秒),我想切换另一个值。所以在时间 0 到 500 之间我希望 shouldActivate 为真,在 500 到 1000 之间它应该为假,然后在 1000 到 1500 之间它应该为真等等。

int activeTime = 500; // 500ms active
int shouldActivate = 0;
int elapsed = 0; //how many ticks we had so far
// This function gets automatically called every 1ms
void tick() {
  if(elapsed < activeTime) {
     elapsed++;
     shouldActivate = 1;
  } else {
     shouldActivate = 0;
     elapsed--;
  }
}

上面的代码在我刚开始的时候工作,当 elapsed 超过 500 时,我遇到了问题,因为它只做了一次递减操作。

我应该在函数中加入什么条件才能达到预期的结果?

你有两个解决方案,创建新变量"direction"(用于指定你是递减还是递增)但我认为更好的是:

void tick() {
  elapsed++;
  if(elapsed < activeTime) {
     shouldActivate = 1;
  } else {
     shouldActivate = 0;
  }
  if(elapsed>999)
    elapsed = 0;
}

您的代码不工作的原因是:如果 elapsed == activeTimeelse 分支触发,您的 elapsed-- 运行,之后 elapsed < activeTime 再次是正确的,因此它在分支之间不断来回移动。

在我看来,最简单的解决方案就是将经过的时间重置为 0,并在 elapsed 的值达到 activeTime 后反转 shouldActivate

void tick() {
  if(elapsed < activeTime) {
     elapsed++;
  } else {
     elapsed = 0;
     shouldActivate = !shouldActivate;
  }
}

根据我的理解,您的应用程序应处于活动状态 500 毫秒,休眠或不活动状态 500 毫秒。您可以像下面这样实现:-

int activeTime = 500; // 500ms active
int shouldActivate = 0;
int elapsed = 0; //how many ticks we had so far
// This function gets automatically called every 1ms
void tick() {
   if(elapsed < activeTime) {
   elapsed++;
   shouldActivate = 1;
  } else {
     shouldActivate = 0;
     elapsed++;//keep increasing elapsed for another 500ms
  }
    // after sleeping for 500ms assign elapsed to zero so that it should active again
    if(elapsed >= (activeTime + 500))       
      elapsed = 0
    //with the above condition you can switch off and on every after 500ms 
}

怎么样:

const int activeTime = 500; // 500ms active
int shouldActivate = 0;
int elapsed = 0; //how many ticks we had so far

// This function gets automatically called every 1ms
void tick() {
    elapsed = (elapsed + 1) % 1000;
    shouldActivate = (elapsed < activeTime);

    // And possibly:
    // if (elapsed == activeTime) { /* State change to Inactivate */}
    // if (elapsed == 0) { /* State change to activate */}
}

因此您的代码仅递减 elapsed 一次,然后下一次 elapsed < active,因此它再次递增。

到目前为止,大多数答案会在达到 500 或 1,000 时重置 elapsed。但是,如果它被称为 elapsed 我认为它应该包含自开始以来经过的时间。这是一个允许 elapsed 永远增加的解决方案,或者对于 32 位 int 至少超过 20 亿毫秒。

void tick()
{
     shouldActivate = elapsed % (2 * activeTime) < activeTime;
     elapsed++;
}

你基本上描述的是一个循环,其中经过的范围从 0 到 2*activeTime-1,下一个毫秒它又回到 0。所以为了检查你在范围的哪一部分每时每刻,你都可以简单地做

elapsed = (elapsed+1) % (2*activeTime);

这将使最终代码如下所示:

int activeTime = ...;
int shouldActivate = 0;
int elapsed = 0; //how many ticks we had so far
// This function gets automatically called every 1ms
void tick() {
  elapsed = (elapsed+1) % (2*activeTime);
  if(elapsed < activeTime) {
     shouldActivate = 1;
  } else {
     shouldActivate = 0;
  }
}