Arduino 周波数/周期カウンタ (8)

前回の最後の図、つまり、

  • OVF 割り込み要求の方が先に発生するが
  • 実行中の命令が 2 サイクル (以上) かかるので
  • 命令実行中に優先度の高い CAPT 割り込み要求に「追いつかれて」しまい、
  • 命令終了時に優先度の高い CAPT 割り込みの方が先にサービスされてしまう

場合のタイミング・チャートを再掲します。

この場合、OVF 割り込みが後回しになってしまうため、CAPT 割り込みサーピス・ルーチン内では、まだインクリメントされていないカウンタ上位桁を読み込むことになるので、ちょうど 0x10000 分の誤差が生じることになります。
この「エラー」が発生する状況かどうかは、ソフトウェア的に検出可能なので、後で補正することができます。
まず、AVR では、割り込み応答シーケンスに入ると割り込みが禁止され、ソフトウェアで明示的に割り込み可にして多重割り込み可能にしない限り、割り込みサービス・ルーチン終了まで、ずっと割り込み禁止の状態で動作します。
したがって、いったん割り込み応答シーケンスに入れば、その割り込みの処理の終了まで、他の要因による割り込みが先に処理されることはありません。
CAPT 割り込みルーチンでは、キャプチャされたカウンタの値である ICR1 レジスタを調べて、その値が 0x0000 以上で、その付近であるかどうかを調べます。
そのような場合、CAPT に先立って OVF が処理されていなければなりません。
AVR の割り込みでは、周辺モジュールの割り込み要求に対応した割り込みサービス・ルーチンのベクタがフェッチされた時点で、そのモジュール内に設置された割り込み要求フラグがクリアされます。
タイマ 1 の場合には、具体的には、タイマ/カウンタ 1 割り込み要求フラグレジスタ「TIFR1」の中にタイマ・オーバーフロー割り込みを示すフラグ「TOV1」と、インプット・キャプチャ・フラグ「ICF1」が集められています。
OVF 割り込みルーチンがサービス済みであれば、TOV1 フラグは立っておらず、まだサービスされていなければ TOV1 フラグが立っているので、CAPT 割り込みサービス・ルーチン内で TOV1 フラグを読めば、これで区別することができます。
次に、CAPT 割り込みルーチン内の TOV1 フラグのチェックで、未サービスの OVF が存在することが判明しますが、動作に影響ない場合の例を示します。

上の例では、キャプチャ結果が 0xFFFD になるようなタイミングで、CAPT 割り込みが OVF 割り込みに先行して発生しています。
この場合、キャプチャ・イベントが発生した時点でカウンタ値が 0xFFFD であったことを示しているので、その時点では OVF 割り込み要求は物理的に発生していなかったことが保証されます。
上の例では、CAPT 割り込みシーケンスが開始されたあとに、「後追い」で OVF 割り込み要求が発生し、 TOV1 フラグが立った状態が CAPT ルーチン内で観測されることになります。
キャプチャされた値が 0xFFFF 以下であれば、OVF 割り込み要求がまだ発生していなかったことは保証ずみですから、ソフトウェア拡張されたカウンタ上位桁の「icr1x」は常に正しく、TOV1 フラグの値を気にする必要はありません。
以下、次回に続きます。