« VXO再検討 | メイン | DSPラジオ(7MHz AM用) »

2016年7月 7日 (木)

周波数カウンターの製作

[自作 PIC TCXO AN592]

ATUやアンテナアナライザーを製作する中で、周波数カウンターも作ってきましたが、色々実験している内に、汎用の周波数カウンターを必要とする場面が結構発生します。 その為に、アンテナアナライザーの中に外部の信号の周波数をカウントする機能を用意したのですが、このカウンターの入力インピーダンスが50Ωの為、信号源を過負荷状態にしてしまい、場合によっては発振周波数が変わってしまうという不都合がありました。

そこで、入力インピーダンスが比較的高く、40Hzくらいから500MHzくらいまでを簡単に測れる周波数カウンターを新たに作る事にしました。

周波数カウンター回路図 Fcounter0.pdfをダウンロード

使うマイコンはジャンクBOXの中に余っているPIC24FV32KA302という16bitのマイコンです。単純なカウンターですので、8bitでも十分実用になる物をつくれますが、アンテナアナライザーの製作で、開発資産がいっぱいありますので、今回のカウンターは16bitで進行します。

目標の仕様は、40Hzくらいの低周波から500MHzまでのUHFまでをそこそこの精度でカウント出来、入力インピーダンスは10KΩ以上で感度も100mVくらいとしました。

ハード的には、プリスケーラ無しの場合、1Hz単位で10MHzまで、10Hz単位で50MHzくらいまで測れる回路と、1/64のプリスケーラーを付けて1MHz以上1GHzまで100Hz単位で測れる回路をスイッチで切り替えて実現させます。 それぞれの回路にデュアルゲートのMOS-FET BF1211によるLNA(ローノイズアンプ)を設けて所定の感度と周波数帯域を確保します。

Fcfront

Fcback

-

2個のBNC端子の内、左側がAF,HFを1Hz単位ではかれる入力端子、右側が一応1GHzまで100Hz単位で測れる入力端子です。どちらの端子が有効かは真ん中のスナップスイッチで切り替えます。 UHFで動作するプリスケーラーは低い周波数が苦手で、簡単に手に入るプリスケーラーは、2GHzまで測れても最低周波数は100MHzくらいというICが多いのですが、今回使った富士通のプリスケーラーMB501Lは、最高1GHzながら、最低1MHzという、ハムにとっては非常に利用しやすい帯域となっています。 ただし、すでに廃番品種ですので、入手はプレミアム価格を覚悟必要です。

カウンターのゲート時間の管理は、それぞれのカウンター動作モードごとに、独立したカウンター関数を用意し、個別にゲート時間を微調整する事にしています。 校正はFT991から10120.00KHzの信号を送信し、すべてのモードでこの表示になるようにソフトを調整してあります。

Fc40hz

Fc500mhz

左上は、自作の正弦波発振器で40Hzを出力したときのカウント値です。31Hzとカウントしています。 この原因を調べたところ、本来1秒のゲート時間が必要なのに、100msecのゲート時間でカウントした後、10回分の合計を表示した事により、本来のカウント値は小数点付でなければなりませんが、カウント値に小数点以下は含まれませんので、小数点以下を切り捨てて合計した為と判りました。 よって、1Hz単位表示の場合、1秒のゲート時間に変更しました。 この変更の結果、40Hzと表示するようになりました。

右上は手元のCAA-500を最高周波数にした時の表示です。CAA-500の表示との差は1KHz以下ですが、どちらが正しいか判りません。 しかし、私が使う範囲内ならこれくらいの精度で十分です。 また、使用しているプリスケーラーの仕様の関係から、VUHF端子に入力が無い場合、ランダムノイズを計数しますので、表示がでたらめになります。 

ソースコード F-counter.cをダウンロード

C言語で書かれた周波数カウンターは特定の周波数で誤差が出ます。特に、カウンターのbit数が不足する為、ソフトで作成されたカウンターを連結して、カウントと条件判定をCで記述した場合、このソースでもその処理に1.2usから2.4usくらいの時間がかかりますので、この間に、ゲート時間がきたりしたら、その分だけ誤差になります。 精度を上げたい時は、アセンブラで記述しますが、それでも誤差が半分か1/4くらいになるだけで、決定的な対策にはなりません。 誤差が許容できない時は、外部回路によるゲート制御しかないようです。 実験的に、タイマーのオーバーフローを割込みで処理してみましたが、かえって誤差が多くなりました。 また、温度補償を行っていない水晶発振回路の周波数はかなりいい加減です。

2018年10月

DDSによる信号発生器(SG)を作ったので、50MHzを発振させ、このカウンターで測定してみたところ、2.5KHzも多くカウントします。 この誤差をPPMで表示させると、50ppmとなります。 通常の水晶発振器の誤差はこのくらいはありますので、水晶発振子と外付けの負荷容量だけで作成した発振回路の誤差としては当たり前の誤差となります。 今、50MHzのAM送信機を自作中ですが、この周波数を測定して2.5KHzの誤差では、全く周波数カウンターの意味がありません。 そこで、もう少し精度を上げたカウンターに作り代える事にしました。

今までは、最低でも50MHzまでは外部プリスケーラーなしでカウントする為、非同期カウントが可能なTimer1で周波数カウントをしていますが、このカウンターは16bitです。 最大999MHzまで100Hz単位で表示するには最低24bitのカウンターが必要であり、16bitのTimer1がオーバーフローする度に、ソフト的に作成した16bitのカウンターをインクリメントしていました。 このソフトでインクリメントする最中にゲートOFFの時間になると、即カウント誤差が生じ、これが50ppmくらいの誤差となっていました。

一方、この16bit PICの中には、ハード的に連結出来る32bitのカウンターが2系統ありますが、いずれも同期カウンターの為、その最大カウント周波数が10数MHzという条件があり、とても50MHzはカバーしません。 しかし、カウンター入力部に接続されたプリスケーラーの分周比を大きくすると、例え同期式カウンターであっても、カウント可能な周波数は50MHz以上にする事ができます。

An592

そこで、マイクロチップがかなり以前に公開したAN592という技術資料で紹介されたプリスケーラー内のデータを読み出す技法を使う事にしました。 左の回路図がAN592によるプリスケーラー残数を読み出す為のハード接続図です。

AN592の解説はWEB上に沢山ありますので、それを参照して下さい。 この技法は、まだPICの規模が小さく、8bitのカウンターしかなかったころ、内部にある8bitのプリスケーラーを使い、トータル16bitのカウンターにした後、カウント終了後にプリスケーラーの入力にパルスを加え、プリスケーラーがオーバーフローし、タイマーが1カウントアップするまでのパルスの数を数える事により、プリスケーラーのカウント値を知る事ができ、このプリスケーラーの値とカウンターの値を連結した16bitのカウンターから、単位ゲート時間内にカウントした周波数を知る事が出来るものでした。 

左上の回路図はカウントしたい信号を470Ωのシリーズ抵抗経由で、カウンター入力に加え、かつこの入力をRA2という端子を出力にして、外部からの信号をブロックした後、RA2にパルスを出力してプリスケーラーをインクリメントするものですが、470Ωの抵抗が災いして、最高カウント周波数は20MHz位にしかなりません。 

An592gate1

そこで、左に示す様に、AN592が解説する技法を外付けのNANDゲート回路で実現し、この最高周波数が低下するのを防ぎます。 この方法も先人がすでにWEB上で紹介しています。

IC7Aの入力Aにカウントしたい信号を加え、入力Bでこの信号をゲートコントロールします。 カウントソースは入力BがHの時だけ通過しますので、入力Bをカウンター用のタイムゲートで制御してやればOKです。 一方IC7Bは、IC7AがOFFの時、入力BをH→L→Hとすることで、カウンター入力にワンパルスを転送できますので、このパルスでプリスケーラーをインクリメントさせます。 このようにゲート回路を組み、プリスケーラーの分周比を1/64にすると、470Ωの抵抗の場合、22MHzくらいまでしかカウントしなかったのが、110MHzくらいまでカウントするようになりました。

次にタイムゲートを作成する為に、ディスクリートの水晶発振回路をTCXOに変更します。 TCXOは秋月で2個、350円で売られていた、26MHzのセイコーエプソン製ですが、そのまま使うには多少難点があります。 まず、SMT用の極小品ですから、ハンダ付け作業はかなり気を使います。 うっかりすると、端子と金属カバー間をショートさせてしまいますので、かなり先細のコテが必要です。 また、出力が0.8Vpp以上となっていますが、実測で0.9Vppくらいしかなく、そのままでは、PICへ入力できません。 従い、TCXOの出力を1石アンプで増幅する必要があります。 もちろん、このTCXOの電源の為に3.3VのLDOも必要となります。

回路図 Fcounter2.pdfをダウンロード

Txco_pwbこれらのハード変更を行ったのが、左の基板です。

追加したTCXOもNANDゲートもLDOも米粒より小さいサイズなので、良く見えません。 NANDゲートは5pinパッケージに2入力NANDゲートが1個だけ入った物を2個使っています。 LDOは不動在庫していたトレックス製の4pinパッケージ品をつかいましたが、これもTCXOの1/4くらいのサイズです。 これらを、拡大鏡を使いながら、基板にマウントして、テスターで導通確認を行い、動作確認するまで足かけ2日かかりました。

そして、10MHzの標準電波BPMでゼロビートを取ったDDSの信号をこのカウンターに入力し、指示が10,000,000Hzに最も近くなるようにゲート時間を調整した結果が下の写真です。

10mhzcnt

ゲートタイムのカウントはタイマー4,5による32bitカウンターで行いますが、C言語で作成されたプログラムの実行時間はかなり長く、これらの実行時間を含めて、1秒とか0.1秒の時間を作る必要があります。 従い、ゲートタイムカウントモードに入ったら、全ての割込みを禁止した上で、タイマー4,5によるカウント時間は、計算で得られる時間より短めに設定し、細かい時間調整はNOP命令の数で行います。 このようにしても1Hzの差は解消できませんでしたが、それでも0.1ppmの誤差まで詰める事ができました。 50MHzの場合5Hzの誤差ですから、問題なく使う事ができます。

ソースファイル F-counter2.cをダウンロード

カウンターのゲートタイムはプリスケーラーなしのとき1秒と0.1秒のみです。 1秒の場合、1Hz単位、0.1秒の場合、10Hz単位で測定できます。 100Hz単位ならゲートタイムを10m秒に、1KHz単位なら1m秒に設定し、データの更新を早くできますが、100Hz単位、1KHz単位いずれの場合でもゲートタイムは100m秒とし、計測データの未表示部分を切り捨てています。 1/64プリスケーラー付の場合、640m秒のゲートタイムのみで、100Hz単位、1KHz単位いずれも同じゲートタイムです。 このようにすることで、不要な表示チラツキを抑制できます。 また、1秒ゲート以外は全て5回分の計測値の平均を表示させています。

このカウンターは1GHzまで測定できますが、信号源がないので、実際の誤差は判りませんでした。 手元のCAA500mk2を接続すると505MHzくらいまでは測れます。プラスマイナス1KHzくらいは一致していますが、このカウンターが正しいのかCAA500mk2が正しいのかは???です。 逆に言えば、CAA500mk2のカウンターは以外と正確であると言えます。

2019年1月

ゲート時間を一定にしておき、表示桁のみ切り捨てる方式の場合、例えば、99.9の小数点以下を切り捨てると99になりますが、これを1/4分周器を通した後、測定すると24.9から9を切り捨てる事になり結果は24となってしまいます。 ここは25と表示して欲しいので、切り捨てではなく四捨五入する事にしました。 この例では99.9は100と表示され、1/4分周後の表示は25となります。 

修正したソースファイル F-counter3.cをダウンロード

2019年5月

表示に使っている99円のLCDの最上位桁の文字が欠けて数字にならなくなりました。 そこで、このLCDを16文字2行のLCDへ交換する事にしました。 LCDのサイズが大きくなったので、ケースは100円ショップで入手したアクリルケースで作り直しです。

32bitカウンター+6bitプリスケーラーにより、周波数カウント用のカウンターは38bitとなりましたので、カウントそのものは1GHzでも1Hz単位で行えますが、PICの上限周波数が110MHzですので、1Hz単位で表示出来るのは110MHzまでです。

LCDがi2cインターフェースに変わりましたので、PICのi/oの変更も必要となり、ソフトもLCDドライブを全面的に変更する事になってしまいました。 このカウンターを使う時、いつもDC12Vの電源を用意する必要がありましたが、今回、ケース変更に伴い、電池を内蔵させ、どこでも使えるように改良しました。消費電流は50mAくらいですので、追加した電源スイッチにより、1年以上は電池交換なしでつかえそうです。

Fcounter3

LCDに追加した機能は、選択されたBNC端子がA かBかを表示する事。 それに電池の電圧を小数点を省いて表示させます。 左の写真は、50MHzのDDS(すでに26MHzのTCXOに変更し、10MHzでゼロビートを取った改良品)の信号を測定した時の表示ですが、6Hzの誤差で表示しています。 TCXOの温度ドリフトはゼロではありませんが、当初より大きくドリフトはしていないようです。

右端に086と表示しているのは電池の電圧で8.6Vである事を示しています。この電池はすでに3年以上経過した低周波発振器用に使っていたのですが、使用頻度が少なかった為、まだ9Vちかくあります。 カウンター回路は6Vの電圧まで動作しますので、さらに1年くらいは使えそうです。

変更した配線図 Fcounter4.pdfをダウンロード

変更したソフト F-counter_i2c-LCD.cをダウンロード

 

  

2019年10月

しばらく使っていましたら、「Hz」の文字付近の下に、白い雲が現れるようになってきました。 LCDのガラス面に歪が発生しているようです。 コントラストも薄くなってきたようですので、再度このLCDを交換する事にしました。

Ng_lcd

New_lcd

今までのLCDはI2Cインターフェースでしたが、手持ちのLCDは4bitパラレルのインターフェースしか有りませんので、過去のLCDのソフトが使えるように、またPICのi/oを変更し、かつ、パネル化粧も、新しいLCDに合わせて作り直しました。

左が、その完成品のパネルとなります。

LCDは秋月から購入したものでしたが、コントラストがかなり改善されました。

電池を実装したまま、外部DC電源のプラグをDCジャックに挿入すると、電池は回路から切り離されるのですが、同じDC電源で動作している発振回路の周波数を測る為に、プローブをつなぐと、このプローブのGNDラインが電源スイッチをショートする事になります。プローブをつないだまま、外部電源からのDCプラグを抜くと、電池から電流が供給されっぱなしになり、1日以上放置すると、電池が液漏れしてしまいました。  対策は、電源スィッチを2回路にし、OFF時は、DCジャックのGNDラインも切断する事にしました。

最新の配線図 Fcounter6.pdfをダウンロード

最新のソースプログラム F-counter_ACM1602K-LCD.cをダウンロード

簡易型の7MHzのAM送信機専用の周波数カウンターも作成しました。 配線図とソースコードは

VXO再検討 を参照下さい。

INDEXに戻る