Arduino Nano タイマーについて考える最良の方法は、基礎となるチップであるATmega328のタイマーについて考えることです。3 つのタイマーがあります。
- タイマー 0: 8 ビット、PWM on chip ピン 11 および 12
- タイマー 1: 16 ビット、PWM on chip ピン 15 および 16
- タイマー 2: 8 ビット、PWM on chip ピン 17 および 5
これらのタイマーはすべて、次の 2 種類の割り込みを生成できます。
- 「値一致」割り込みは、タイマーのすべてのティックに追加されるタイマー値がタイマー レジスタの比較値に達すると発生します。
- タイマー値が最大値に達すると、タイマー オーバーフロー割り込みが発生します。
残念ながら、タイマーに割り込みをアタッチする Arduino 関数はありません。タイマー割り込みを使用するには、もう少し低レベルのコードを書く必要があります。基本的に、次のような割り込みルーチンを宣言する必要があります。
ISR(TIMER1_OVF_vect) {
...
}
これにより、timer1 オーバーフロー割り込みを処理する関数が宣言されます。次に、レジスタを使用してタイマー オーバーフロー割り込みを有効にする必要があります。TIMSK1
上記の例の場合、これは次のようになります。
TIMSK1 |= (1<<TOIE1);
また
TIMSK1 |= BV(TOIE1);
これによりTOIE1
、TIMSK1 レジスタに (timer1 オーバーフロー割り込みを生成してください) フラグがセットされます。割り込みが有効になっていると仮定すると、ISR(TIMER1_OVF_vect)
timer1 がオーバーフローするたびに呼び出されます。
Arduinodelay()
関数は、ソース コードでは次のようになります ( 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カウントはmillis()
関数がその値を取得する場所です。
一方delayMicroseconds()
、関数は、特定の適切なタイミングのマイクロプロセッサ操作を使用して遅延を作成します。どの関数が使用されるかは、プロセッサとクロック速度によって異なります。最も一般的なものnop()
(操作なし) は、正確に 1 クロック サイクルかかります。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;
これから学ぶこと:
- 1 µs の遅延は何もしません (関数呼び出しが遅延です)
- より長い遅延では、左シフト操作を使用して遅延の時間を計ります。