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

CAPT と OVF のタイミングの関係を推測するために行った実験のようすを説明したいと思います。
CAPT 割り込みの発生タイミングを、1 クロック単位で可変するために、同じタイマ 1 の PWM 出力である OC1B 端子とコンペアレジスタ OCR1B を使いました。
analogWrite() 関数でのポート設定を利用した場合に出力される概略のタイミングを下に示します。

カウンタ TCNT1 の値が「MAX 値」である 0xFFFF から、「MIN 値」である 0x0000 へ変化するタイミングで OC1B 出力は「1」になり、コンペア・レジスタ OCR1B との比較一致がとれた (次のクロックの) タイミングで OC1B 出力は「0」になります。 この OC1B 出力の立ち下りエッジをインプット・キャプチャのトリガ信号とします。
実験としては、カウンタ値の 0xFFFF, 0x0000 を含んで、前後の少なくとも数クロック分はタイミングを変化させたいのです。
しかし、OCR1B を 0xFFFF に設定すると、出力デューティーは 100 %、つまり、直流レベルの「1」となり、パルスは消失してしまいます。
実際には、キャプチャ信号とクロックとの同期を取るために、内部で数クロック分の遅延が加わるので、0xFFFF, 0x0000 あたりで CAPT を発生させるためには、OCR1B レジスタには 0xFFFF よりも小さい値を設定すれば良く、実験は可能です。
それでも、もうちょっと余裕を持たせるために、外部にシフトレジスタを設け、さらに遅延を加えることにしました。 結線図を下に示します。

手持ちの関係で、使ったのは、いまさらながらの感がある LSTTL の 74LS166 です。 TTL では、入力をオープンにした場合に「H」レベルを入力したものと (ほぼ) みなせるので、配線の手間は少しだけ減りました。
シフト・レジスタにはシステム・クロックを加える必要があるので、CLKOUT フューズ・ビットを設定して、CLKO 端子 (14 番ピン) から外部へクロックが出力されるようにしました。
14 番ピンはディジタル信号によるキャプチャ入力 ICP1 の端子でもあるので、遅延させた OC1B 信号を ICP1 へ戻すことはできなくなり、アナログ入力である ADC4 端子へ入力しています。
この接続では、アナログ・コンパレータ経由となるので、内部での遅延がさらに加わって、結局トータルでは 16 クロック分の遅延となりました。
したがって、0xFFFF が ICR1 にキャプチャされるようなタイミングで CAPT を発生させたい場合には、OCR1B に 0xFFEF を設定すれば良いことになります。
このような準備のもと、キャプチャされたカウント値を横軸、CAPT 割り込みサービス・ルーチン内で TOV1 フラグが立っているのを観測した頻度を縦軸にとってプロットしたグラフを下に示します。

このグラフの詳しい説明は次回行います。