周波数カウンタ


【概要】

 8ピンのPICを使って、最高2.5MHzまで1Hz単位で、または最高20MHzまで8Hz単位で
計測できる周波数カウンタです。
できるだけ少ない部品でできるように工夫しました。


【構成と回路図】

 構成は至って簡単で、下図のような全体構成となっています。




まず、PIC12F683を使って、全体を構成しています。このPICのタイマ0、タイマ1
CCP1モジュールを使ってカウンタを構成しています。

入力信号はFETだけで構成されたアンプを通過してGP2(T0CKI)端子に接続され
タイマ0でカウントします。内部でタイマ1とCCP1を使って正確な1秒を生成しています。
この動作の考え方を図にすると下図のようになります。




周波数カウンタとして動作させるためには正確な1秒間だけ外部からのパルスを
カウントすれば良いわけなので、この正確な1秒のゲート時間の間だけT0CKIのパルスが
入力されるようにしてやります。

そこでまず、正確な1秒はタイマ1とCCP1モジュールで作成します。
タイマ1を内部クロックで1/8プリスケーラで動作させると、タイマ1のクロックは 
12.8MHz÷4÷8=400kHz となります。
従ってCCP1をコンペアモードで使い、一致する値を40000とすると10Hz周期で一致割り込みが
発生し、その都度タイマ1が0にクリアされます。
この周期はハードウェアだけで生成されますから、割り込み処理時間には関係なく常に一定
の周期になります。

従ってこの割り込みが10回入って来たとき1秒後ということになりますから、ここでタイマ1を
停止させれば1秒という時間が作れます。
この10回目の割り込みからタイマ1を停止させるまでの時間が遅れ誤差になりますが、
この遅れ時間は他の割り込みを使っていませんから常に一定の時間となります。
そこで、この時間分だけ、最初のタイマ0のカウント開始を遅らせることにします。

この正確な1秒間だけT0CKIの入力をゲートします。このゲートする方法は、
常時はGP2を出力モードにしてLowを出力します。これでT0CKIへの入力は強制的に0に
固定されますので、外部パルスは入力されずカウントはしません。
次に、上記1秒のゲート時間の間だけGP2を入力モードにします。これで外部パルスが
入力可能となりT0CKI入力としてタイマ0でカウントされます。

タイマ0は8ビットのカウンタですから当然1秒間の間にオーバーフローします。このオーバー
フローを常時監視して、オーバーフローが発生したら内部の変数を+1してオーバーフロー
フラグをクリアします。
最後にこの変数の値に256を乗じて、残りのタイマ0のカウント値を加算すれば全体の
カウント値、つまり周波数が求められることになります。

ここでタイマ0のカウント能力ですが、外部パルスを内部クロックに同期させるため、
クロック周波数でカウント上限値が制限されてしまいます。
データシートに依れば、
   最大カウント可能周期 = (Tcy+40)÷N (nsec)    Nはプリスケール値
となっていますので、12.8MHzのクロックの時には、Tcy=295nsecですから

   N=1のとき  最高335nsec → 約2.9MHz  (実用レベルは約2.5MHz)
   N=8のとき  最高42nsec → 約23MHz   (実用レベルは約20MHz)

これが最大カウント能力ということになります。


以上を元に作成した回路図は下図となります。入力アンプをFETだけにしましたので
実に簡単な構成になっています。




USARTを内蔵していないので、ソフトウェアでシリアル通信を行うことになりますが
CCS社のC言語を使えば自動的にこのソフトウェアを生成してくれますので
簡単に実現できます。 
RS232Cのコネクタは本来はDSUBコネクタにするべきですが、大型になるので
小型のコネクタにして外部で変換ケーブルを自作して使うことにしました。



【ハードウェア製作】

 製作には基板が必要ですが、プリント基板を作るほどでも無いので、EジスPenで
作成しました。簡単にお絵かきで作成できるのでこういうときには便利です。
 できあがった基板は写真のようになります。


中央金属ケースが高精度発振器です。
少し浮かせてケースが基板のランドとショート
しないようにする必要があります。
左側がRS232C用ICとコネクタ、中央がPICです。
中央下側に入力アンプ用のFETがあります。
右下側にチップ型の10μFのコンデンサがあります。


パターンは下図となっています。




これをアクリルケースに実装して完成です。



【プログラム製作】

 このプログラムはCCS社のC言語で作成しました。RS232Cが数行で記述できて
しまいますので、こういうときには非常に便利です。

まず宣言部とCCP1の割り込み処理部分は下記のようになります。
クロックの宣言とRS232Cを使う宣言をしています。
CCP1の割り込み処理では10回目を確認し、GP2をLowにしてゲートを閉めてから
タイマ1を停止し終了フラグをオンにしています。




メイン部は下記のようになっています。これで全部ですから簡単です。
まず最初に各モジュールの初期設定をしています。CCP1で40000をセットして
100msec周期を指定します。
メインループでは、まず最初にGP0のHigh、Lowに従ってプリスケーラを切替えて
います。その後カウンタ類を初期化してからタイマ1をスタートし、10回目の割り込み
処理でタイマ1が停止するまでの遅れを相殺するための遅れ時間分だけ待ってから
GP2を入力モードにしてタイマ0のカウントを開始します。
あとは終了を待ちながらタイマ0のオーバーフローをチェックして変数を+1して
いるだけです。
終了フラグがオンになったらカウント値を計算して周波数を求め、シリアル通信で
出力しています。
シリアル出力では別項で製作した液晶表示器ユニットも使えるように、全消去の
制御文字も出力しています。
液晶表示器の全消去のときは、動作に2msec程度を必要としますので、ここで
5msecの待ち時間を挿入しています。
2行目にGP0の状態に従ってレンジ切替の状態を表示しています。





★★ プログラムダウンロード




  目次ページに戻る