arduino:delaymicroseconds()


8

delayMicroseconds()函数如何工作。据我了解,timer0的预分频器设置为64。对于16MHz时钟,每个计数为4.0uS。我对达到1uS的时间间隔感到困惑吗?


4
文档说:“此功能在3微秒及以上的范围内非常精确地工作。我们不能保证delayMicroseconds在较小的延迟时间内将精确执行。” 的文档micros()说:“在16 MHz Arduino板上(例如Duemilanove和Nano),此功能的分辨率为4微秒(即返回的值始终是4的倍数)。”
RedGrittyBrick

Answers:


9

该函数的源代码已被很好地记录,可以在Linux系统上的/usr/share/arduino/hardware/arduino/cores/arduino/wiring.c中找到。Windows系统将具有与connection.c文件类似的路径。尽力查找文件并浏览它。现在仅关注此单个功能,它不依赖于任何其他功能。

通过检查代码,您会发现它与计时器无关,而与指令周期有关。该代码在很大程度上依赖于编译器优化,对于您而言,该优化与对于库开发人员而言完全相同。那是作者的一个假设!Atmel AVR指令集文档中详细记录了每个指令“消耗”的CPU周期数。

首先,检查延迟值是否等于1,在这种情况下,只是从已经花费了微秒CPU时间的例程中返回。

然后,将延迟值乘以四(<<=2)。所述__asm__-loop编译成4个CPU周期循环。4个周期×4 = 16个周期。16MHz /(4×4)= 1MHz,需要1 us的循环时间,即我们追求的分辨率。

最后的-2微秒(在循环开始之前)再次纠正了编译器引入的开销。__asm__从C 调用-code需要一些额外的指令来保存CPU寄存器。

对于普通的Arduino @ 16MHz,仅会编译以下代码:

/* Delay for the given number of microseconds.  Assumes a 8 or 16 MHz clock. */
void delayMicroseconds(unsigned int us)
{
        // calling avrlib's delay_us() function with low values (e.g. 1 or
        // 2 microseconds) gives delays longer than desired.
        //delay_us(us);
        // for the 16 MHz clock on most Arduino boards

        // for a one-microsecond delay, simply return.  the overhead
        // of the function call yields a delay of approximately 1 1/8 us.
        if (--us == 0)
                return;

        // the following loop takes a quarter of a microsecond (4 cycles)
        // per iteration, so execute it four times for each microsecond of
        // delay requested.
        us <<= 2;

        // account for the time taken in the preceeding commands.
        us -= 2;

        // busy wait
        __asm__ __volatile__ (
                "1: sbiw %0,1" "\n\t" // 2 cycles
                "brne 1b" : "=w" (us) : "0" (us) // 2 cycles
        );
}

顺便说一句:编译后的代码非常准确,但是请注意以下几点:在Arduino上,配置了大多数人都不知道的定时中断。在执行期间收到中断时delayMicroseconds(),的时间delayMicroseconds()将是错误的。您当然可以在调用之前停止中断,然后delayMicroseconds()再启用它们,但这又会影响已启用/禁用的已编译代码的持续时间,从而影响定时精度。


或者,如果你没有安装Arduino的IDE,该文件可在github.com/arduino/Arduino/blob/master/hardware/arduino/cores/...
microtherion

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.