PICマイコン(PIC12F675)の割り込みの考え方と注意事項

組み込みエンジニア

こんにちは、ENGかぴです。

マイコンのソフトを開発するとき割り込み処理をよく使います。割り込み処理について理解することはAD変換やPWM制御を行う上で重要です。割り込みは優先的に処理を実行できるため便利ですが使いすぎるとメイン関数に戻れなくなるなどの問題もあります。

PIC12F675を使って割り込みについて考え方と注意事項を説明していますが、マイコンを問わず共通の考え方です。

PIC12F675を使ってマイコンの動きを勉強するためにPIC12F675の機能でできることについてまとめています。

PICマイコン(PIC12F675)で実現できる機能と解説リンクまとめ

マイコンの割り込み

マイコンのソフトを開発していくと複雑なプログラムになっていき割り込みを多用するようになります。割り込みの考え方が理解できていないと思わぬ動作不良を起こしかねません。

割り込みとは他のプログラムが動作している途中でも割り込んで先に割り込み内部の処理をさせることを言います。

通常はメイン関数の無限ループを繰り返しながら処理を行っているのですが、割り込み発生の条件を満たしたときメイン関数からいったん抜けて対象の割り込みの処理を先に行います。

割り込みにはマイコンの機能が充実しているほど多くなりますが、代表的な割り込みについて例を挙げると以下のような処理があります。

  1. タイマー割り込み
  2. AD変換完了割り込み
  3. シリアルデータの送受信割り込み
  4. シリアルデータの異常割り込み
  5. NMI割り込み
  6. INT割り込み(入力端子端子で検出)

PICマイコン(PIC12F675)についてはこれらのうちタイマー割り込みAD変換完了割り込みINT割り込みをよく使います。RXマイコンについても通信データを送受信した時に割り込みを使用したり、アナログデータを取得して判断させる場合AD変換完了割り込みを使用しています。

割り込みを使用する意味

マイコンで正弦波(50Hz)で振幅が0~5Vのアナログデータを取り込むことを考えます。1周期分を16分割してサンプリングを行う場合、50Hzなので1周期の時間は20msになります。20msを16分割することになるので1.25msの間隔でサンプリングする必要があります。

マイコンのAD変換器を使用してデータを等間隔で格納することになりますが、割り込みがなかった場合メイン関数内でAD変換が完了したことを確認してデータを格納することになります。

仮にメイン関数の処理が重たくなった時にAD変換開始が遅れて1.30msになってしまったとなればその分ずれたデータが取得されることになるので精度が落ちてしまいます。

データのずれによる精度のずれの説明
データのずれによる精度のずれの説明

サンプリング時間が短いほど影響が大きくなってしまいます。インバータ制御などでは200us以下でAD変換を行いPWM制御することもあるのでAD変換データのずれは大きく制御に影響してしまいます。

データ取得のタイミングのずれを少なくするために割り込みを使ってデータを取得するなど優先させたい処理に対して割り込みを使用するのが一般的です。割り込み内の処理は可能な限り少なくしてメイン関数で処理させるようにすることも大切なことです。

正弦波を2.5Vを中心に入力しているのはマイコンの電源範囲が0~5Vだからです。そのため正弦波を入力する場合にゼロクロス点を中心に入力するためには2.5Vにする必要があります。直接印加すると-に振れたときに故障してしまう可能性がありますので注意が必要です。

割り込みの処理を可能な限り少なくする

割り込みの渋滞の例

割り込みは優先的にメイン関数から抜けて処理するため便利なことから多用してしまうことがあります。

しかし、割り込み内の処理が重たくなりすぎて次から次へと割り込み条件となった場合、割り込みが渋滞してしまいメイン関数に戻ってこれなくなってしまうことがあります。

メイン関数に戻ってこれないためWDTクリアができなくなるためWDT異常となリセットとなります。(マイコンによってWDT異常の場合の処理を決めることはできる)

割り込みが渋滞しないように、極力割り込み内の処理からスムーズに抜けられるように割り込み関数内では最低限必要なの処理のみにすることが必要です。

割り込みをイメージをフローで考える

割り込みのフロー図
割り込みのフロー図

割り込みについてメイン関数との関係について説明します。割り込みを使用しない場合のメイン関数の処理は処理A→処理B→処理Cを繰り返すものとします。割り込みを使用を使用する設定を行うと、割り込み発生の条件を満たすとメイン関数の途中の処理をいったん抜けて割り込み処理を行います。

例では処理Aと処理Bの途中で割り込み処理に遷移していますが、割り込みは条件を満たすと発生するのでメイン関数の処理の場所を問わず発生します。割り込みの頻度を増やしすぎるとメイン関数から抜けることが多くなりメイン関数を1周する時間に遅延が発生します。

割り込み関数の処理が重たくなりすぎるとメインに戻る前に次の割り込みが発生してしまうことが連続してしまい割り込みの渋滞によりメイン関数が処理できなくなってしまいますので注意が必要です。

割り込み処理の注意事項

割り込みについて割り込み渋滞の問題について説明してきましたが、変数の取り扱いについても注意する必要があります。メイン関数と割り込み関数で同じ変数を使用する場合について注意が必要です。2つの例を見てみます。

割り込み関数内でのみ変数をセットする場合

割り込み内で変数を変更する場合
割り込み内で変数を変更する場合

前提条件として変数flagは1と0の2値でフラグとして使用するものとします。変数としてflagを定義して割り込みの処理内でflagに1をセットします。メイン関数はflagがセットされているかを確認してセットされていれば処理Aを行うことになります。

処理Aはflagがセットされているときだけ処理したい内容とするとflag = 0としてクリアすることで次のメイン関数での処理時には処理Aを無効にすることができます。

割り込みの処理で値を更新しメイン関数内では参照するのみの使い方であれば問題になることはありません。

割り込み関数とメイン関数内で同じ変数を使用する場合

前提条件として変数adbufはアナログデータを格納するものとします。

同一の変数をメインと割り込みで使用している例
同一の変数をメインと割り込みで使用している例

変数adbufを割り込み関数とメイン関数内で使用しています。処理Aはadbufを使用して値を計算していますが、条件を見るとadbufが100より大きい時としています。

注意が必要な例はadbufが110だったときにif文の条件としてadbuf > 100を満たすことから処理Aを実行しようとすることです。

処理Aを実施している途中若しくは前に割り込みの条件を満たして割り込み関数内でadbufの値が更新され100以下になる場合など、条件を満たした後に割り込みによって値が更新されることが問題です。

処理Aは100より大きい時に計算するものなのに割り込みによってadbufの値が90(dataが90)なったとすると処理Aは100以下の値で計算してしまうことになります。また、100より大きいとしても条件後に値が変わることは計算結果が変化してしまうため望ましくありません。

例)処理Aの2つの式の間で割り込みが来た場合(adbufは110とする)
vaule = 10 + 110 = 120 (この処理の後割り込みで90になったとする)
value2 = 10 *  90 = 900(本来であれば10*100 = 1100)

このように値が変化してしまい計算結果が期待していたものと異なってしまいます。

上の例より値が変化すると不良動作の原因となってしまいます。これを防ぐためには※1で一旦割り込みを禁止にして処理Aが完了した後の※2で割り込みを許可する必要があります。

関連リンク

PICマイコンを使ってマイコンのレジスタの設定やMPLAB X IDEのプラグインであるMCCを使用して動作確認したことについてまとめています。

PICマイコン(PIC12F675)で実現できる機能と解説リンクまとめ

PICマイコン(PIC16F1827)で実現できる機能と解説リンクまとめ

TECH::CAMPプログラミング教養【無料体験会】

最後まで、読んでいただきありがとうございました。

タイトルとURLをコピーしました