Arduinoで時間遅延割り込みを作成しようとしています。これは内部割り込みなので、interrupts()関数を使用したいと思います。
例:割り込みのタイミングのみでライトを点滅させたいとしましょう。
サンプルコードがありますが、外部割り込み(attachInterrupt())を使用しています。内部割り込みを使い続けたいのですが。
Arduinoで時間遅延割り込みを作成しようとしています。これは内部割り込みなので、interrupts()関数を使用したいと思います。
例:割り込みのタイミングのみでライトを点滅させたいとしましょう。
サンプルコードがありますが、外部割り込み(attachInterrupt())を使用しています。内部割り込みを使い続けたいのですが。
回答:
Noah Stahlのブログには、Timer2でLEDを点滅させる例があります。それとデータシートを使用して、使用したい割り込み(つまり、通常の機能を放棄する余裕がある、または変更したい割り込み)にそれを適合させることができるはずです。Timer2は通常、一部のPWM機能に使用されます。
彼の例はATmega2560を引用しています。ATmega328pでも動作することを確認できました。より有用なArduino割り込みの例については、彼のサイトを見てください。
編集:
これは、わずかに編集された(主にコメントの)バージョンのNoahのコードです。関連するデータ構造またはハードウェアを初期化した後、Arduinoのsetup()関数からTimer2init()を呼び出します。これを行うと、タイミングと割り込みが開始されるためです。
F / ex、3桁の7セグメントディスプレイを多重化するために使用したので、タイマーを初期化する前に、ディスプレイI / Oレジスタを初期化し、ISRが検索する場所のディスプレイデータをブランクにしました。
データシートのいくつかの有用なタイミングデータと、別のタイミングスキームを設定するための参照用の独自の計算のコメントに表があります。
ISR()マクロは、通常の関数の入り口と出口の代わりにISRの割り込み入り口コードと出口コードを作成し、それを適切な割り込みベクトルにリンクします。その関数の残りの部分は、1)各割り込みで実行されるコード、および2)次の割り込みのタイマーをリセットするコードコードです。
書かれているように、これは.pdeまたは.inoスケッチ(またはeclipse、f / exを使用する場合は.cppファイル)にドロップする必要があります。スケッチはLEDPINを#defineする必要があり、setup()はTimer2init()を呼び出す必要があります。ループ関数は空かそうでないかもしれません。ダウンロード時にLEDが点滅し始めます(まあ、文字通り、Timer2init()が呼び出された後)。
/*
* From sample interrupt code published by Noah Stahl on his blog, at:
* http://arduinomega.blogspot.com/p/arduino-code.html
*
*/
/*** FUNC
Name: Timer2init
Function: Init timer 2 to interrupt periodically. Call this from
the Arduino setup() function.
Description: The pre-scaler and the timer count divide the timer-counter
clock frequency to give a timer overflow interrupt rate:
Interrupt rate = 16MHz / (prescaler * (255 - TCNT2))
TCCR2B[b2:0] Prescaler Freq [KHz], Period [usec] after prescale
0x0 (TC stopped) 0 0
0x1 1 16000. 0.0625
0x2 8 2000. 0.500
0x3 32 500. 2.000
0x4 64 250. 4.000
0x5 128 125. 8.000
0x6 256 62.5 16.000
0x7 1024 15.625 64.000
Parameters: void
Returns: void
FUNC ***/
void Timer2init() {
// Setup Timer2 overflow to fire every 8ms (125Hz)
// period [sec] = (1 / f_clock [sec]) * prescale * (255-count)
// (1/16000000) * 1024 * (255-130) = .008 sec
TCCR2B = 0x00; // Disable Timer2 while we set it up
TCNT2 = 130; // Reset Timer Count (255-130) = execute ev 125-th T/C clock
TIFR2 = 0x00; // Timer2 INT Flag Reg: Clear Timer Overflow Flag
TIMSK2 = 0x01; // Timer2 INT Reg: Timer2 Overflow Interrupt Enable
TCCR2A = 0x00; // Timer2 Control Reg A: Wave Gen Mode normal
TCCR2B = 0x07; // Timer2 Control Reg B: Timer Prescaler set to 1024
}
/*** FUNC
Name: Timer2 ISR
Function: Handles the Timer2-overflow interrupt
Description: Maintains the 7-segment display
Parameters: void
Returns: void
FUNC ***/
ISR(TIMER2_OVF_vect) {
static unsigned int led_state = 0; // LED state
led_state = !led_state; // toggles the LED state
digitalWrite(TOGGLE_PIN, led_state);
TCNT2 = 130; // reset timer ct to 130 out of 255
TIFR2 = 0x00; // timer2 int flag reg: clear timer overflow flag
};
attachInterrupt()関数は、実際にピンの外部状態変化への割り込みを装着され、それは他のオプションを持っていません。
上の同じページモードオプションは、次のように記載されています:
モードは、割り込みをトリガーするタイミングを定義します。4つの定数が有効な値として事前定義されています。
- ピンがローのときはいつでも割り込みをトリガーするLOW、
- ピンが値を変更するたびに割り込みをトリガーするCHANGE
- RISINGは、ピンがローからハイになったときにトリガーします。
- ピンがハイからローになるときのフォールリング。
悪い知らせの持ち主になって申し訳ありません。それも私が最初に探したものの1つです。
PWMに関するこの記事では、Arduinoタイマーの使用に関する多くの疑問を解決します。Arduinoには2つの8ビットタイマーと1つの16ビットタイマーがあります。ISR関数をタイマーに直接フックする高レベルのAPIはありません。これは、Arduino SDKに同梱されて(つまり、標準ライブラリとして)提供されていますが、Special-Function-Registersおよびbit-arithmetic /を設定するやや低レベルのメソッドです。それらの操作。ただし、Timer oneというユーザー提供のライブラリがあります。
ArduinoはATMega328で3つのタイマーをすべて使用しています。Timer1
(16ビット)のような機能のために使用されるdelay()
とmillis()
ピン5と6他の二つのタイマーのPWM出力のために- Timer0
とTimer2
ピン3、9、10、11にPWM出力のために使用されます。
そのため、タイマー割り込みのためのArduino関数はありません。しかし、方法があります。このコードを使用して、タイマー割り込みを有効にすることができますTimer2
。
ISR(TIMER2_OVF_vect) {
// Interrupt routine.
}
void setup() {
// Enable Timer2 interrupt.
TIMSK2 = (0<<OCIE2A) | (1<<TOIE2);
}
void loop() {
// Your main loop.
}
このコードはテストせずに作成したので、間違えた可能性があります。その場合は、データシートp.156をご確認ください。
タイマ周波数(プリスケーラ)を変更したい場合は、レジスタを変更するだけTCCR2A
です。詳細については、データシートの153ページを参照してください。ただし、タイマーの周波数を変更すると、2つの出力ピンのPWM信号の周波数も変更されます。
Timer0
とTimer2
8ビットであり、唯一のTimer1
16ビットです。