ATmega328の割り込みの使用方法
ナビゲーションに移動
検索に移動
概要
ATmega328の割り込みの使用方法を記載する。
割り込みには、シリアル割り込みやピン入力が変化した時の割り込み等がある。
ここでは、タイマ割り込みについて記載する。
割り込みの種類
ATmega328の割り込みの種類には、以下のようなものがある。
ATmega328の割り込みの種類 | ||
---|---|---|
シンボル | 名前 | 説明 |
INT0_vect | 外部割り込みピン INT0 | 外部ピンの変化で割り込み |
INT1_vect | 外部割り込みピン INT1 | 外部ピンの変化で割り込み |
PCINT0_vect | 外部割り込みピン INT0 | ピンの論理変化割り込みのみサポート PCINT0〜23まである |
TIMER0_COMPA_vect | タイマ0 コンペアマッチA |
タイマ0でコンペアマッチAのとき割り込み |
TIMER0_COMPB_vect | タイマ0 コンペアマッチB |
タイマ0でコンペアマッチBのとき割り込み |
TIMER0_OVF_vect | タイマ0 オーバーフロー |
タイマ0でカウンタ最大値を超えたとき割り込み |
TIMER1_COMPA_vect | タイマ1 コンペアマッチA |
タイマ1でコンペアマッチAのとき割り込み |
TIMER1_COMPB_vect | タイマ1 コンペアマッチB |
タイマ1でコンペアマッチBのとき割り込み |
TIMER1_CAPT_vect | タイマ1 捕獲イベント |
タイマ1でICR1に達したときに割り込み |
TIMER1_OVF_vect | タイマ1 オーバーフロー |
タイマ1でカウンタ最大値を超えたとき割り込み |
TIMER2_COMPA_vect | タイマ2 コンペアマッチA |
タイマ2でコンペアマッチAのとき割り込み |
TIMER2_COMPB_vect | タイマ2 コンペアマッチB |
タイマ2でコンペアマッチBのとき割り込み |
TIMER2_OVF_vect | タイマ2 オーバーフロー |
タイマ2でカウンタ最大値を超えたとき割り込み |
SPI_STC_vect | SPIシリアル転送完了 | SPIシリアル転送完了のとき割り込み |
USART_RX_vect | USART受信完了 | USART(シリアル通信)受信完了のとき割り込み |
USART_UDRE_vect | USART送信可能 | USART(シリアル通信)送信可能のとき割り込み |
USART_TX_vect | USART送信完了 | USART(シリアル通信)送信完了のとき割り込み |
割り込みのタイミングは、ピン入力の変化やタイマで指定した時間の経過、シリアル通信イベント等がある。
(上表に記載のない割り込みもある)
使用したい割り込みのシンボルは、ISR()関数の引数に指定して使用する。
割り込み処理の基本
割り込みを許可する命令は、sei命令である。
割り込み関数(ISR)からmain関数へ戻る命令は、ret命令である。
main関数から、割り込み関数(ISR)に処理が移る時、一旦、割り込みが禁止される。
割り込み処理が終わると、割り込みをまた許可しないといけないため、ret命令とsei命令を組み合わせた、reti命令がある。
reti命令で割り込み処理が終わる。
また、割り込みを禁止にするには、cil命令を使用する。
以下に割り込み処理のサンプルコードを記述する。
#include <avr/io.h>
#include <avr/interrupt.h> // 割り込み処理
// ISR関数とmain関数で使用する変数(コンパイラはこの変数を最適化しない)
volatile unsigned char count;
// 割り込み関数
ISR(TIMER0_OVF_vect) // タイマ0でオーバーフローが起きた時
{
count++;
}
int main()
{
// 割り込み処理を行うためレジスタの設定を行う
//cil(); // 割り込み禁止
sei(); //割り込み許可
while(1)
{
// メイン処理
}
return 0;
}
タイマ割り込みの使用方法
タイマの割り込みを使用するためのレジスタ設定およびプログラムを記述する。
タイマに関しての記事は、ATmega328でのタイマとPWMの使用方法を参照すること。
タイマ0の割り込み
タイマ0割り込みレジスタ TIMSK0 | ||||||||
---|---|---|---|---|---|---|---|---|
ビット | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
レジスタ名 | - | - | - | - | - | OCIE0B | OCIE0A | TOIE0 |
- OCIE0B : タイマ0のコンペアマッチBの割り込み(比較一致Bの割り込み)
- OCIE0A : タイマ0のコンペアマッチAの割り込み(比較一致Aの割り込み)
- TOIE0 : タイマ0のオーバーフロー割り込み
以下に、タイマ0でコンペアマッチAで割り込み処理を行うサンプルコードを記述する。
#include <avr/io.h>
#include <avr/interrupt.h> // 割り込み処理を行うため
ISR(TIMER0_COMPA_vect) // タイマ0 コンペアマッチAの割り込み関数
{
// ..略
}
int main()
{
// タイマ0 制御レジスタA
TCCR0A = 0b10000010; // 10 : コンペアマッチAでLOW、10 : CTCモード
// タイマ0 制御レジスタB
TCCR0B = 0b00000001; // 分周なし
// タイマ0 割り込み設定
TIMSK0 = 0b00000010; // コンペアマッチAの割り込みを設定
// コンペアマッチするタイミング
OCR0A = 32499; // 32.5[ms]でコンペアマッチ@1[MHz]
// ポートの設定
// ..略
sei(); // 割り込み許可
while(1)
{
// メイン処理
}
return 0;
}
タイマ1の割り込み
タイマ1割り込みレジスタ TIMSK1 | ||||||||
---|---|---|---|---|---|---|---|---|
ビット | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
レジスタ名 | - | - | ICIE1 | - | - | OCIE1B | OCIE1A | TOIE1 |
- ICIE1 : タイマ1の捕獲割り込み(タイマ(カウンタ)の値がICR1に達した時の割り込み)
- OCIE1B : タイマ1のコンペアマッチBの割り込み(比較一致Bの割り込み)
- OCIE1A : タイマ1のコンペアマッチAの割り込み(比較一致Aの割り込み)
- TOIE1 : タイマ1のオーバーフロー割り込み
以下に、タイマ1で捕獲割り込みをするサンプルコードを記述する。
#include <avr/io.h>
#include <avr/interrupt.h> // 割り込み処理を行うため
// タイマ1での捕獲割り込み関数(ICR1に達すると割り込み)
ISR(TIMER1_CAPT_vect)
{
// 処理
}
int main()
{
// タイマ1 制御レジスタA
TCCR1A = 0b00000010; // 高速PWMモード(TOP値 : ICR1)
// タイマ0 制御レジスタB
TCCR1B = 0b00011001; // 高速PWMモードで分周なし
// タイマ0 割り込み設定
TIMSK1 = 0b00100000; // 捕獲割り込みを設定
// 割り込み発生する時間の設定
ICR1 = 64999; // 65.0[ms]@1[MHz]
// ポートの設定
// 略
sei(); // 割り込み許可
while(1)
{
// メイン処理
}
return 0; //プログラム終了
}
タイマ2の割り込み
タイマ2割り込みレジスタ TIMSK2 | ||||||||
---|---|---|---|---|---|---|---|---|
ビット | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
レジスタ名 | - | - | - | - | - | OCIE2B | OCIE2A | TOIE2 |
- OCIE2B : タイマ2のコンペアマッチBの割り込み(比較一致Bの割り込み)
- OCIE2A : タイマ2のコンペアマッチAの割り込み(比較一致Aの割り込み)
- TOIE2 : タイマ2のオーバーフロー割り込み
タイマ2は、タイマ0と同じ使い方なのでサンプルコードは省略する。