今回は、8bit AVRマイコンの割り込みについて説明したいと思います。
割り込みとは?
AVRマイコンは、同時に一つの処理しか実行できません。このため、ハードウェアからのトリガーを元に優先すべきサブルーチンを実行する「割り込み」と呼ばれる仕組みが備わっています。良く利用される割り込みの例としては、タイマーやUARTの送受信、コンパレータの判定が変化した時などが挙げられます。
具体的には、次の様なプロセスで割り込みは処理されます。
(1)割り込み要求IRQ(Interrupt Request)が周辺回路から発行される。
(2)次に実行予定であったアドレスをスタックに格納する。
(3)現在実行中の命令を完了させる。
(4)割り込み処理ルーチンISR(Interrupt Service Routine) に制御を移す。
(5)割り込み処理終了後、本来実行予定であった(2)のプロセスに戻る。
以上が割り込み処理の簡単なイメージですが、実際はステータス・レジスタや汎用レジスタも保存や復帰も伴い複雑なものとなります。ですがプログラムを記述する上では、次項の例の様に、そこまで意識する必要はありません。
割り込み処理のサンプル・コード
割り込み処理の例としては、次の様なコードが挙げられます。
//Example: Interrupt
//Target Device: ATmega328
//Author: easy labo
//Created: 2014.11.02
#include
volatile unsigned char timerCountMax = 10;
volatile unsigned char timerCountUp = 0;
ISR(TIMER1_COMPA_vect){
if(timerCountUp >= timerMax){
timerCountUp = 0;
}else{
timerCountUp++;
}
}
通常、割り込み処理内容の記述には、マクロISRを使用します。ISRの引数に、_vectで割り込みベクタを指定します。この指定を選択する事で、様々な種類の割り込み制御を行う事ができます。ISRの中に記述してある内容が実際に割り込みが発生した際に行う処理となります。この例では、カウントアップ・タイマを構成しています。
割り込みベクタの種類と優先度
割り込みベクタの種類を次表に、まとめておきます。
Vector No. | Symbol | Interrupt Definition |
---|---|---|
1 | - | Reset Pin, Power-on Reset, etc. |
2 | INT0_vect | External Interrupt Request 0 |
3 | INT1_vect | External Interrupt Request 1 |
4 | PCINT0_vect | Pin Change Interrupt Request 0 |
5 | PCINT1_vect | Pin Change Interrupt Request 1 |
6 | PCINT2_vect | Pin Change Interrupt Request 2 |
7 | WDT_vect | Watchdog Time-out Interrupt |
8 | TIMER2_COMPA_vect | Timer/Counter2 Compare Match A |
9 | TIMER2_COMPB_vect | Timer/Counter2 Compare Match B |
10 | TIMER2_OVF_vect | Timer/Counter2 Overflow |
11 | TIMER1_CAPT_vect | Timer/Counter1 Capture Event |
12 | TIMER1_COMPA_vect | Timer/Counter1 Compare Match A |
13 | TIMER1_COMPB_vect | Timer/Coutner1 Compare Match B |
14 | TIMER1_OVF_vect | Timer/Counter1 Overflow |
15 | TIMER0_COMPA_vect | Timer/Counter0 Compare Match A |
16 | TIMER0_COMPB_vect | Timer/Counter0 Compare Match B |
17 | TIMER0_OVF_vect | Timer/Counter0 Overflow |
18 | SPI_STC_vect | SPI Serial Transfer Complete |
19 | USART_RX_vect | USART Rx Complete |
20 | USART_UDRE_vect | USART, Data Register Empty |
21 | USART_TX_vect | USART, Tx Complete |
22 | ADC_vect | ADC Conversion Complete |
23 | EE_READY_vect | EEPROM Ready |
24 | ANALOG_COMP_vect | Analog Comparator |
25 | TWI_vect | 2-wire Serial Interface |
26 | SPM_READY_vect | Store Program Memory Ready |
AVRマイコンが同時に一つの処理しか実行できないのは、割り込み処理においても同様です。その為、競合した場合は通常、ベクタ番号(Vector No.)の小さいものが優先して処理されます。すなわち割り込み頻度を均等化する様な基本機能は備わっていない事になります。
割り込みの許可と禁止
ISRで割り込み処理を記述しただけでは、割り込み処理は行われません。
//Example: Set or Clear Interrupts
//Target Device: ATmega328
//Author: easy labo
//Created: 2014.11.15
#include
sei(); //Set Interrupts
cli(); //Clear Interrupts
割り込み許可sei()と、割り込み禁止でcli()で、割り込みの許可と禁止を行います。またUART(USART)やタイマなどの設定レジスタに割り込みを有効化する
ビットがあるので、データシートで確認して設定しておく必要があります。
割り込みとメイン処理間のデータ受渡し
割り込み処理とメイン処理間でデータを受渡しした場合は、volatileを付けた変数を宣言して、それを介してデータの受け渡しをします。サンプルコードでも利用しています。ちなみに、volatileをつけた変数については、コンパイラは最適化を行いません。
Sponsored Link