我想了解更多有关Arduino Nano计时器的信息。
delay()
和delayMicroseconds()
如何实施......
答案 0 :(得分:18)
考虑Arduino Nano定时器的最佳方法是考虑底层芯片中的定时器:ATmega328。它有三个定时器:
所有这些定时器都可以产生两种中断:
不幸的是,没有Arduino函数可以将中断附加到计时器上。要使用定时器中断,您需要编写稍多的低级代码。基本上,您需要声明interrupt routine这样的内容:
ISR(TIMER1_OVF_vect) {
...
}
这将声明一个服务timer1溢出中断的函数。然后,您需要使用TIMSK1
寄存器启用定时器溢出中断。在上面的示例中,这可能如下所示:
TIMSK1 |= (1<<TOIE1);
或
TIMSK1 |= BV(TOIE1);
这将设置TIMSK1寄存器中的TOIE1
(生成timer1溢出中断)标志。假设您的中断已启用,则每次timer1溢出时都会调用ISR(TIMER1_OVF_vect)
。
Arduino delay()
函数在源代码(wiring.c
)中如下所示:
void delay(unsigned long ms)
{
uint16_t start = (uint16_t)micros();
while (ms > 0) {
if (((uint16_t)micros() - start) >= 1000) {
ms--;
start += 1000;
}
}
}
所以内部它使用micros()
函数,它确实依赖于timer0计数。 Arduino框架使用timer0来计算毫秒数,实际上,timer0 count是millis()
函数获取其值的地方。
delayMicroseconds()
函数使用某些适时的微处理器操作来创建延迟;使用哪个功能取决于处理器和时钟速度;最常见的是nop()
(无操作),它只需要一个时钟周期。 Arduino Nano使用16 MHz时钟,这就是源代码的样子:
// For a one-microsecond delay, simply return. The overhead
// of the function call yields a delay of approximately 1 1/8 µs.
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 proceeding commands.
us -= 2;
我们从中学到了什么: