这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » Arduino中使用延时函数出现异常

共1条 1/1 1 跳转至

Arduino中使用延时函数出现异常

专家
2025-12-01 16:50:08     打赏

我在测试TB6600步进电机控制器时,使用了ESP8266。在Arduino上编程,测试发出脉冲信号时,程序代码如下:

// 旋转指定步数
void rotateSteps(int steps) {
  for(int i = 0; i < steps; i++) {
    digitalWrite(PUL_PIN, HIGH);
    delayMicroseconds(stepDelay);
    digitalWrite(PUL_PIN, LOW);
    delayMicroseconds(stepDelay);
  }
}

其中stepDelay设置为1000,实际上delayMicroseconds(stepDelay);也就是延时1mS。然后实际运行中出现了异常,

图片1.png

那延时处理换成delay函数,

// 旋转指定步数
void rotateSteps(int steps) {
  for(int i = 0; i < steps; i++) {
    digitalWrite(PUL_PIN, HIGH);
    //delayMicroseconds(stepDelay);
    delay(1);
    digitalWrite(PUL_PIN, LOW);
    //delayMicroseconds(stepDelay);
    delay(1);
  }
}

运转就正常,

图片2.png

根据经验看,感觉在使用delayMicroseconds函数时,可能导致了中断嵌套、堆栈溢出,发生了异常。

于是重新温习这两个延时函数的知识。

delaydelayMicroseconds属于是阻塞式延时处理,前者是毫秒级别,后者是微秒级别。

调用delayMicroseconds(us)时,Arduino将参数值加载到定时器寄存器中,并禁用全局中断。长时间使用delayMicroseconds可能导致程序运行效率降低,建议结合millis()函数实现非阻塞延时。

millismicros函数是非阻塞式处理函数,前者是毫秒级被,后者是微妙级别。因此如果想要维持微秒级的延迟,可以考虑下面的处理方式:


  unsigned long previousMicros = 0;
  const long interval = 1000000; // 1秒
  
  unsigned long currentMicros = micros(); // 获取当前时间
  if (currentMicros - previousMicros >= interval) {
    previousMicros = currentMicros; // 更新上次时间
    ......
  }

按照这个思路,改造了程序:

// 旋转指定步数
void rotateSteps(int steps) {
  for(int i = 0; i < steps; i++) {
    digitalWrite(PUL_PIN, HIGH);
    //delayMicroseconds(stepDelay);
    //delay(1);
    delayMicro(stepDelay);
    digitalWrite(PUL_PIN, LOW);
    //delayMicroseconds(stepDelay);
    //delay(1);
    delayMicro(stepDelay);
  }
}
void delayMicro(uint32_t us) {
  unsigned long previousMicros = micros();
  while (true) {
    if (micros() - previousMicros >= us) {
      break;
    }
  }
}


结果,仍然是出现了异常。

图片3.png


这下,真就理解不了了。

如果开发板的工作主频更高,代码执行周期更短,这样的异常还会产生吗?




关键词: 菜鸟学单片机     Arduino     延时    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]