CPU実験室

誰も見向きもしない古いCPUをいじって動かしてみようというプロジェクトです

周波数カウンタ

PIC16F886にまずは周波数カウンタの機能を実装します。主にポートON/OFF(Lチカ)の周期を見るくらいですから1MHzくらいまで測れれば十分です。

機能はプログラミングでどうにでもなるのですが内部ペリフェラルの相互接続は検討が必要です。今回ちょっとこれをあまり考えずハード設計してしまった感がいまさらながらしてきました。

 

最初に信号入力部とタイマ0の周辺です。通常動作時は赤ラインの経路でT0CKIピンに入ったパルスをTMR0でハード的にカウントします

f:id:O3I:20200712141312j:plain

デバッグ中は青ラインの経路に切り替え一時的に内部パルスを接続することでカウンタの動作が確認できます。もちろん同じ原振なので絶対精度はわかりませんけど。

 

次にタイムベースですがこれはタイマ2を使います。TMR2の値とPR2レジスタの値をコンペアすることでインターバルタイマとして動作させ割込みを発生させます

f:id:O3I:20200712141357j:plain

この分周比が重要で、様々な組み合わせが考えられますが外付けした水晶の原振Fosc=20MHzを勘案すると以下が最適と考えました

 プリスケーラ入力=Fosc/4=5MHz

 プリスケーラに1:4を選択・・・出力が5/4=1.25MHz

 コンパレータの比較値PR2に250を設定・・・出力が1250/250=5kHz

 ポストスケーラに1:5を選択・・・出力が5/5=1kHz

この1kHzでタイマ2割込みを発生させます

(※後から気づきましたがコンパレータの比較値はPR2+1で評価されるので、PR2の設定値は249でなければならない)

 

割込みハンドラはこういう感じ。

f:id:O3I:20200712141417j:plain

割込みごとにTMR0を読み取りすぐにTMR0をクリアします。これで割込み周期1ms(ゲートタイム)毎のカウント値でkHz単位の周波数を直読で測定できます。厳密にいえばコード自体の実行時間も考慮すべきでしょうが周期割込みなので誤差が蓄積しないのと有効桁数がたかだか4桁なので問題ありません。

 

・・と云ったそばから問題発生なのですがTMR0は8ビット長しかないので当然10進で有効桁数4桁どころか3桁も確保できません。桁上げを考えないと・・