汎用8桁周波数カウンタ

PICを2個使ってセグメント発光ダイオード表示の
8桁汎用周波数カウンタをつくって見ました。
いろいろな周波数表示用に応用が出来ます。





【概要】

  このPICで周波数カウンタを作ると最大20MHz程度までのカウンタの製作が
可能ですので使い道は結構多いと思います。
プリスケーラと呼ばれる高速のカウンタを追加してやれば、数GHzまでの
周波数カウンタとすることも可能です。
 今回、製作したカウンタの外観は写真のように基板のままです。これを何か
別のものに組み込んで周波数表示用に使うという前提で作ります。
 表示部分にはセグメント発光ダイオードを使いましたが、ここは好みで色や
大きさを選んで製作して下さい。


【全体の構成】

(2001/1/19)

 全体の構成は下図のように、大きく制御基板と表示基板の2つで構成し、
制御基板内は、入力アンプ、カウンタ部、表示制御部の3つの部分から構成します。
 制御基板内のカウンタ部は、PICに全部を任せてしまうことにし、入力アンプで
増幅され整形された信号をRA4端子から入力してプログラムで常時3バイトデータ
としてカウントアップします。
そして毎回カウント結果の3バイトデータを表示制御部にシリアル信号で送信します。
 表示制御部も別のPICで構成し、カウント部からの送信を常時監視し、受信した
3バイトのバイナリデータを8桁のBCDデータに変換してから、さらにそれをセグメント
データに変換して表示部に出力します。
 このデータ受信と並行してセグメント発光ダイオードのダイナミック点灯制御を実行
します。この時の表示桁数は設定スイッチによって4桁、6桁、8桁の3種類の指定が
出来るようにします。








【カウンタ部の構成】

カウンタ部の動作タイミングは下図のようにします。まずPICを周波数カウンタとして動作
させるためには、高精度のゲート信号を必要とします。この単位信号となるゲート信号を
1秒と0.1秒のパルスとし、このパルスそのものもPICのプログラムで生成してRA4に
出力します。RA4はワイアードANDが構成できるようになっていますので、RA4の信号が
Highの間だけRA4の内部回路を通してタイマー0への入力信号となり、RA4がLowの時は、
RA4の内部でタイマ0への入力は強制的に0レベルのままとなりますので、カウント入力
信号は入らないことになります。





 ここでゲート信号(RA4 Gate)は、図のようにゲート信号がHighの間に入力されたパルスだけを
カウントすることになりますから、正確な単位時間だけHighとすることが必要になります。
この単位時間には表示が周波数で直読できるようにするため、1秒と0.1秒の2種類を
用意することにします。そしてこの時間パルスをプログラムの命令実行を繰り返すことで
生成するため、命令実行時間を高精度とする必要があります。
 そこで、この命令実行時間のもとになっているPICのクロック信号として高精度のクリスタル
発振器である12.8MHzのTCXOを使います。
 この高精度のTCXOをPICのクロックにすれば、PICの命令実行時間の1サイクルは正確に
4/12.8MHz=312.5nsecとなりますので、命令の実行サイクル数を3,200,000サイクルと
すれば合計命令実行時間は正確に1秒となります。320,000サイクルで0.1秒です。
このパルス作成部分の命令群の最初と最後でRA4のHigh/Lowの制御をすれば高精度の
1秒、0.1秒のゲート時間とすることが出来ます。

 入力された信号の周波数をカウントするカウンタとしては、下図のようにPIC内部のタイマ0の
ハードウェアカウンタ1バイトとプログラム変数2バイトを連続した3バイトのカウンタとして
プログラムでカウントアップします。
このタイマ0を使うことで高速のカウントをすることが可能となります。しかしタイマ0のカウンタは
1バイト分しか無いので、プログラムで2バイト目、3バイト目のカウンタを動作させます。
従って、このカウントプログラムは常時動作させておく必要がありますから、ゲート時間作成の
命令群の中に含めなければならないことになります。そのためプログラムの流れがどのルートを
実行しても同じ実行時間になるようにカウントアッププログラムを作成する必要があります。







【データ転送】

 カウンタ部と表示制御部のPIC間のデータ転送方法を説明します。
カウンタ部でカウントした3バイトのデータを表示制御部に送るのですが、この転送のために
使うPICのピン数を少なくするためシリアル通信で送ることにします。
シリアル通信の方式は調歩同期式といわれる方式をモデルにすることとし、データフォーマット
を下図のようにします。
これでPIC間を互いに入出力ピンを1ピンづつだけで通信をすることが出来ます。



 送信側となるカウンタ部のPICは、まずスタートビットを送出後、上位バイトの上位ビットから
順に1ビットずつ出力し、最後にストップビットを送出して完了します。
1ビットの時間幅は、プログラムで作成しますので十分の時間幅を確保するため100μsecとし
全体が3msec程度で送れる様にします。
こうすると常時は常にHighの状態となっていて、送信が開始されると必ず最初はLowになります
から受信側はこのタイミングを検出するようにします。
 受信側となる表示制御部のPICでは、常時、ダイナミックスキャン表示制御をしながら、その間
でスタートビットの受信を監視し、もしスタートビットを検出したら一旦表示制御をお休みして
データ受信を実行し内部の表示データを更新します。 データ受信が完了したら3バイトの
バイナリデータを8桁のBCDデータに変換して格納しておきます。


【全体回路構成】

今回は表示の見やすさを考えて、表示素子としてセグメント発光ダイオードを使うこと
にしました。そこで表示にカソードコモンのセグメント発光ダイオードを使ったとすると、
PICからの制御信号は、セグメントドライブ用の7個と各桁ドライブ用の8個の制御信号が
必要となります。
 この必要なピン数からPIC16F873を使うことにしました。出力の仕方としては、まず
セグメントの表示ドライブですが、これは20mA程度の電流のドライブですので、PICの
入出力ピンで25mAまでは直接制御が可能な範囲ですから、ポートBから電流制限抵抗を
経由して直接セグメントドライブを行うこととします。
 これに対し各桁のコモンのドライブは、電流が各セグメントの和が流れますので、
最大160mAにもなってしまいますから、トランジスタによるドライブの強化が必要となります。
 このようなドライブ用トランジスタをいくつかまとめたICが出ていますのでこれを利用して
実装を簡単化します。今回利用したICはMOS FETモジュールで数Aまで制御可能なもの
ですが、こんなに大きな負荷では無いですが手持ちの関係で使いました。
結局表示制御の部分は、これらを組み合わせると、下図のように接続すれば、最大8桁の
セグメント発光ダイオードをプログラムでダイナミックドライブして数値を表示できることになります

これらと入力アンプ部、電源部を加えて全体の回路は下図のようになりました。下図は拡大
表示が出来ます。






WinDraft、WinBoard用の回路図とパターン図は下記からダウンロードできます。

  ★ 汎用8桁周波数カウンタ回路図
  ★ 汎用8桁周波数カウンタパターン図



【カウンタ部のプログラム】

 カウンタ部にはPIC16F84Aを使い、プログラムの全体の流れは下図のフローチャートのよう
にします。
 まず全体の流れは0.1秒か1秒で周波数カウントをし、その結果を表示制御部にシリアル転送
してまた元に戻るという大きな流れになります。
 この周波数カウントする直前で、ポートAの設定スイッチの内容を入力して、ゲートが0.1秒か
1秒かの判定と、タイマのプリスケーラを使う、使わないの判定もします。そしてその結果で
分岐します。
 おのおののカウントルーチンの中では、タイマ0のオーバーフローを常時監視し、オーバー
フローしたらBYTE1、BYTE2をカウントアップすることをゲート時間の間だけ繰り返します。
 ゲート時間が終了したら、カウント結果をゲート時間、プリスケーラの有無によって補正して
から、シリアル転送で出力します。



 ★ カウンタ部のプログラムソースファイル


【表示部のプログラム】

 表示制御部はPIC16F873という少し大きめのPICを使っています。このPICは単に
入出力ピンが多いだけでなく、A/D変換モジュールやパルス幅変調モジュールなど
数多くの機能が内蔵されています。
 しかし、今回は、これらは使わず、単にディジタル入出力だけを使っています。
 まずしなければならないことは、最大8桁のセグメント発光ダイオードのダイナミック
点灯制御ですから、1桁当り約2msecでの表示制御を止めることなく繰り返す必要が
あります。従って他の処理はすべてこの表示制御の繰り返しループの中で処理する
必要があります。
 この繰り返しループでは、表示のために、まず指定された桁数の上位桁から順に
BCDデータをセグメントデータに変換してポートBに出力し、該当する桁の1ビットを
ポートCに出力して約2msecの間だけ点灯させます。そして一旦ポートCをクリアして
全桁OFFにしたら、次の桁の制御に移ります。これを全桁繰り返しまが、スイッチの
指定によって、桁数を4桁表示、6桁表示、8桁表示と設定できるようにしましたので、
途中でスイッチの状態を確認して不要な桁の制御をスキップします。
 表示を約2msecの間点灯させるためにタイマで待ちますが、この間に常時カウンタ部
からのデータ送信をチェックします。つまりスタートビットが来たかどうかをポートRB0を
入力して確認し、もしスタートビットの受信が確認できたら、つまりLowとなっていたら、
続くデータ3バイトを各ビット100μsec毎に入力して受信する処理を実行します。
この間約3msec程度表示時間が延長されてしまいますが、実際の表示上は、ほんの
瞬間ちらつくだけですから問題は無いでしょう。
 受信が完了したら、そこで直ぐバイナリからBCD8桁への変換を実行して表示データを
更新してしまいます。従って次の桁表示から新しいデータで表示することになります。
 この通常の表示制御以外に、全桁が正常に表示できるかどうかを確認するための
テストモードを用意しました。DIPスイッチの4をONにすればテストモードということにして、
これでテスト表示を開始します。テスト内容は単純に0から9までの全桁同じ数字の表示を
約1秒間繰り返すということを実行します。テストの間はカウンタ部からのデータ受信も
実行しないようにします。



  ★ 表示部のソースプログラム




【表示基板】

 セグメント発光ダイオードを使った表示基板を組み立てます。
今回使用するセグメント発光ダイオードはカソードコモンタイプです。
表示部分の回路図は下図のようになります。簡単な回路ですので問題は無いでしょう。
小数点も表示できるようにジャンパで接続できるようにコネクタに端子を出しておきます。
下図は拡大できます。





【製作】

組み立てには専用のプリント基板製作から始めます。パターン図は下記ですので
ダウンロードしてWinBoardでお使い下さい。
 組み立てには、ICはすべてICソケットを使います。これらの部品を実装する前に、
ジャンパ線を抵抗などのリード線の切りくずを使って実装します。
あとは、特別に実装が難しい部品はありませんので、組み立ては簡単に出来ると
思います。下記写真が基板の組み立て完了後の状態です。







電源のレギュレータには放熱器をつけました。

接続ケーブルは基板に直接はんだ付けしました。
小数点は適当な桁にジャンパ線で配線します。






  目次ページに戻る