PIC16シリーズのマイコンを使用していると、複数の割り込み要因がほぼ同時に発生した場合の動作が気になることがあります。特にGPIO割り込みやタイマー割り込みを併用する場合、「割り込み処理中に別の割り込みが発生したらどうなるのか」「後から来た割り込みは失われるのか」といった疑問を持つ方は少なくありません。この記事ではPIC16シリーズの割り込み処理の仕組みをわかりやすく解説します。
PIC16シリーズの基本的な割り込みの仕組み
PIC16シリーズの多くのデバイスでは、割り込みベクタは基本的に1か所しかありません。そのため、複数の割り込み要因が存在していても、CPUは共通の割り込みサービスルーチン(ISR)へジャンプします。
ISR内では各種割り込みフラグを確認し、どのイベントが発生したかをソフトウェアで判定します。
例えばGPIO割り込みとTimer0割り込みが有効になっている場合でも、CPUはまずISRへ移動し、その後でINTCONレジスタやPIRレジスタなどのフラグを確認します。
割り込み処理中に別の割り込みが発生した場合
PIC16シリーズでは通常、割り込み受付後にグローバル割り込み許可ビット(GIE)が自動的にクリアされます。
そのためISR実行中は新たな割り込みでISRが再度呼ばれることはありません。これを非ネスト型割り込みと呼びます。
しかし、割り込み要因そのものは消えているわけではありません。ISR実行中に別の割り込みイベントが発生すると、その対応する割り込みフラグがセットされます。
ISR終了時にRETFIE命令が実行されるとGIEが再び有効になり、未処理のフラグが残っていれば直後に再度ISRへ入ります。
後から発生した割り込みは無視されるのか
結論から言うと、多くの場合は無視されません。
例えばAピンの割り込み処理中にBピンの割り込みが発生した場合、B側の割り込みフラグが保持されるため、Aの処理完了後にBの割り込みとして認識されます。
ただし注意点もあります。同じフラグが立った状態でさらに同じイベントが複数回発生しても、フラグは1ビットしかないため回数までは記録できません。
| 状況 | 結果 |
|---|---|
| A割り込み中にB割り込み発生 | Bのフラグが立ち後で処理される |
| 同じ割り込みが短時間に複数回発生 | 発生回数は保持されない場合がある |
| フラグ未クリアで再発生 | 追加発生を検出できない場合がある |
タイマー割り込みでも同じ考え方なのか
タイマー割り込みでも基本的な考え方は同じです。
ISR実行中にタイマーオーバーフローが発生すると対応するフラグがセットされます。
ただしタイマー周期が短く、ISR処理時間が長い場合には問題が発生します。例えばタイマーフラグが既に立っている状態でさらにオーバーフローしても、追加回数までは記録されません。
その結果、本来発生したタイマーイベント数とソフトウェアが認識した回数に差が生じることがあります。
実務でよく行われる対策
PICプログラミングではISRをできるだけ短く保つことが重要です。
一般的にはISR内ではフラグ変数をセットするだけにして、重い処理はメインループ側で実行します。
例えば次のような設計がよく使われます。
- ISRではイベント発生フラグのみセット
- メインループで実際の処理を実行
- タイマー周期より十分短いISRを維持
- 必要に応じてイベントキューを利用
このような構成にすることで割り込みの取りこぼしを減らし、システム全体の応答性も向上します。
まとめ
PIC16シリーズでは通常、割り込み処理中に新しい割り込みが発生しても即座には実行されません。しかし対応する割り込みフラグは保持されるため、ISR終了後に処理されるのが一般的です。
一方で同じ割り込み要因が短時間に何度も発生した場合、フラグが1ビットしかないため回数情報が失われる可能性があります。そのためISRは短く保ち、フラグ管理を適切に行うことが安定したPICプログラム設計の基本となります。


コメント