CL2*_*L22 6 avr atmega timer arduino atmel
我想了解更多有关Arduino Nano计时器的信息.
delay()
和delayMicroseconds()
实施...
ang*_*rge 18
考虑Arduino Nano定时器的最佳方法是考虑底层芯片中的定时器:ATmega328.它有三个定时器:
所有这些定时器都可以产生两种中断:
不幸的是,没有Arduino函数可以将中断附加到计时器上.要使用定时器中断,您需要编写稍多的低级代码.基本上,您需要声明一个这样的中断例程:
ISR(TIMER1_OVF_vect) {
...
}
Run Code Online (Sandbox Code Playgroud)
这将声明一个服务timer1溢出中断的函数.然后,您需要使用寄存器启用定时器溢出中断TIMSK1
.在上面的示例中,这可能如下所示:
TIMSK1 |= (1<<TOIE1);
Run Code Online (Sandbox Code Playgroud)
要么
TIMSK1 |= BV(TOIE1);
Run Code Online (Sandbox Code Playgroud)
这将设置TOIE1
TIMSK1寄存器中的(生成timer1溢出中断)标志.假设您的中断已启用,ISR(TIMER1_OVF_vect)
则每次timer1溢出时都会调用您的中断.
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
所以内部它使用的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;
Run Code Online (Sandbox Code Playgroud)
我们从中学到了什么: