« 2025年5月 | トップページ

2025年9月

2025年9月18日 (木)

割り込みの話

割り込みの話とは

行列に割り込む、あの割り込みではありません。

マイコンの機能で、外部信号や、タイマーなどによって通常のプログラム制御の流れから飛び出して(割り込む)処理を行うことです。
大昔のプログラムでは、CPUの機能で割り込み種類によってプログラムのテーブルにある順番で処理ルーチンのアドレスに飛んだり、飛んで実行する時にそれまでのCPUのレジスタを自動的にスタックといって、RAMエリアの高位アドレスにある部分に退避したり、戻る時に自動的に元のレジスタに戻す機能がありました。しかしながら、変数として RAMを使いたい場合は自分でスタック上にRAMを確保したり、この部分はマシン語(いわゆるアッセンブラー言語などで)書かなければならなかったり面倒でした。

ところが最近のPICのようなCPUの開発環境では、ライブラリーに従って記述するだけで、C言語で書けちゃうので、今回の割り込み機能は

1) ポート2箇所(PortA2,A3)の立ち上がりエッジで割り込み
2) タイマー0でオーバーフロー割り込み
3)タイマー2の比較機能でカウント一致割り込み

という贅沢な割り込み機能で動作しているのですが、どうも1)の割り込みが交互にくるはずが、時々変なタイミングでかかってしまうのです。
ポートのエッジ検出なのでノイズか、誤動作かとオシロで見ても波形には出ていないので、ここ1ヶ月ばかりハード的なフィルタやレベルの調整を行っていましたが、まだ時々出てしまうのでした。

動作の仕組みとしては 2)のオーバーフロー割り込みの後に 1) の割り込みが交互に来るはずなので、
  2)のタイマースタート時に1)の割り込みOFFにして
  2)のオーバーフロー割り込み後に 1)の割り込みを許可して
  1)の割り込みを待つ
という仕様なのですが、ノイズ対策したのちはほぼ満足した動きになるのですが、ほんの時々 2)の直後すぐ1)が来てしまうのです。他のタイミングでは数mS後なのに、この時は50uS程度で 来るので生成波形がぶれてしまうのでした。

色々ノイズ対策をし尽して、ソフトでどうにかならないかとライブラリのデフォルトの割り込みルーチンを眺めていると、その最終行にヒントがありました。

割り込み発生フラグ = 0 ;  // 実際はフラグレジスタ名のビット

なのでした。

2)のオーバーフロー割り込み中の最後に、 1) の割り込みを許可しているのですが、ノイズなどで発生した信号で、割り込みが許可されていない時に起こったイベントがすでに割り込みフラグを立てていた場合、許可した直後に 1) の割り込みが発生してしまうのです。

 本来、ノイズなどを避けるために割り込み禁止していたのに、ノイズによる誤動作割り込みフラグをクリアしないで、割り込み許可したので、結局ノイズで割り込み起こしていたというわけです。

 

| | コメント (0)

« 2025年5月 | トップページ