« 2008年10月19日 - 2008年10月25日 | トップページ | 2008年11月2日 - 2008年11月8日 »

2008年10月26日 - 2008年11月1日の1件の記事

2008年11月 1日 (土)

秋月FG用の周波数カウンターをつくる

シュミットトリガーは必要なかった(10/24/08)
 これまでのプロジェクト(リズムキャプチャー)が終わって、次のテーマは、このあいだからバラックで使っていた秋月のファンクションジェネレーターキット(以下FG)に周波数カウンターを組み込んで少しまともな測定器にすることにした。そのためにケースも買ってある。表示用のLCDも揃えてある。ただし、この周波数カウンターは、もっぱらFGからの出力の表示だけに使い、他の用途は考えない。アナログも必要でないし、そんなに正確さが求められているわけでもない。

 今のところ音声周波数しか使っていないが、このキットは20Mhzまでの正弦、方形、三角波まで出る。どう考えても、このさき20Mhzの信号を使うことはまずないだろうが、ジェネレーターについている表示がそこまで出ないのはやっぱりおかしい。しかし、AVRマイコンの最大クロックは、20Mhzなので、マイコンだけでは測定不能である。 

 いつものようにWebに助けを求める。ある、ある。周波数カウンターは自作の恰好の課題と見えて、たくさんの人が自作している。今度は、この前のアナログのオーディオマニアではなくアマチュア無線のマニアのサイトに多い。

 いつもお世話になっているchaN氏のサイトにもユニバーサルカウンターという測定器の詳しい情報がある。これはCPLDとGhz帯まで動くプリスケーラーICを使ってあらゆる信号の周波数が測れる。うーむ、これはすごい、写真も付いている。きれいだ。余り綺麗なので、何か簡単に作れそうに見える。しかし、今度の周波数カウンターはとてもこんなレベルまで必要がない。だいたい測定対象はジェネレーターの出力だけである。なるべく簡便に作りたい。

 さらに調べる。なんだプリスケーラーってカウンターICのことなんだ。CPLDでなくても単に8 ビットのバイナリカウンターのICひとつで最大256分周できる。4Mクロックで2Mまで測れるとして128Mhzまで測れる(分解能は64hzになるけれど)。何もCPLD、ましてやFPGAを持ち出す必要はない。

 理屈がわかれば話は早い。昨日、家内の買物につきあったついでに、このあいだ行ったばかりの秋葉原に寄って、バイナリカウンターの74HC393とシュミットトリガーインバータの74HC14を買ってきた。そう言えば昔、Z80のワンボードコンピューターを自作しようとこのあたりを色々勉強した記憶がよみがえる。なつかしい。74hc393

 帰って早速、ブレッドボードに二つのICを差し、抵抗で中位電位をつくり、FGからのAC信号をコンデンサーで入れてオシロで波形を見る。うーむ、オシロのおかげで考えたことがすぐ実験できる。素晴らしい。

 シュミットトリガーは、Webのサイトの回路図に入っているのがあるし、アナログ入力をいきなりカウンターに入れるのに抵抗があったこと、それにアナログからデジタルへの変換は「整形にシュミットトリガー」、という教科書的知識で何の疑いもなく買ってきた。しかし、結論から言えば、全く必要がなかった、というより74HC14では遅くて使えないことがわかった。

 考えてみれば、殆どノイズのないFGの信号(2VP-P)入力なので整形の必要もないのだが、始めは、全くカウンターが動かず頭を抱えた。分圧抵抗を可変抵抗器に変えてやっと出力されるところを見つけた。要するに中間電位がとてもクリティカルで、20Mhzを超えるとどれだけ調整しても出力されない。

 思いあぐねて、次の日、思い切ってシュミットトリガーなしに、カウンターの入力に直接入れてみたら、何のことはない。全く問題なくカウンターが動いたのである。やれやれ、始めからこうしておけば良かった。

 しつこい性格なので、何故シュミットトリガーで動かなかったのか調べてみた。74HC14のデータシートをWebから落として調べる。ヒステリシス機能があるので普通のインバータより出力が遅れるのはわかるが、全体に遅れるだけで同期をとる必要がないのだから問題ないと思っていた。

 遅延時間がでている。Vccが4.5Vで、遅延時間9ns(typ)、最大で17ns。一見早そうだが、チャートを良く調べるとトリガーがかかってから出力が変わるまではこの1.5倍、15ns程度かかる。メーカーの最大保証値なら17ns×1.5で25.5nsとなる。20Mhzの半サイクルは25nsなので、中間点からはずれると出力が変わらないうちに次のトリガーがかかってしまうことになる。20Mhzを超えたところで調整不能になって当たり前なのだ。74VHC14ならこの3倍くらい早いので、必要ならこれを使えばよい。いや、データシートは穴のあくまでよく読めといわれているがそのとおりだった。調べておけば、昨夜の数時間は無駄にせずすんだというものである。

ISPは配線を間違えても動く(10/25/08)
 周波数カウンターのハードの目処が立ったので、本格的な設計開発に入る前に、この前のプロジェクトで気になっているUARTの不調を直しておこうと調べ始めた。リズムキャプチャーのWebに上げたソースコードは、これを全く使っていないので問題はないのだが、このまま放っておくのは、何となく気持ちが落ち着かない。

 症状は、AVRspで全く問題なく、プログラムが正常に書き込めるのに、デバッグ用に愛用しているISPを通したUARTだけが動かないのである。このコードは初期に割込み付きのUARTとしてWebにも公開して以来、がた老AVR研の殆どのプログラムに入っている。PCを通じてマイコンの動きが逐一把握できるので、デバッグが早い。昔の大型機のプログラマーをしていたときから、私はデバッガーやシミュレーターというのを殆ど使ったことがない。大体、デバッガーもソフトなので系に不確定要素をさらに加えることになるし、そもそも自分の開発したソフトをデバッガーがないと解析できないというのは、コーディング以前の構造的な設計に問題があるからだと思っている。

 余談はさておき、リズムキャプチャーのUARTである。ソフトは試作版と全く変えていないので、問題はソフトではなくハードであることは間違いない。電源は電池になっているが5Vと4.5Vでは全く関係ないだろう。だいいち低電圧版のAVRは3V以下でも動くのだ。

 とすると、実装基板の配線ということになるが、ファームの書き込みは正常だし、AVRspのコマンドレスポンスも正常だ。配線間違いならそもそもこれが動かないはすだ。

 それでUARTだけが動かない。そんな馬鹿なと、基板の配線を眺めながら独り言を言っていたとき、ふとISPピンの最後のピンに目が止まった。縦一列のISPの最後がリセットピンにつながっている。アートワークもそうなっている。このへんは何十回と配線していて間違えるはずがないと豪語していたところだ。

 あれ、待てよ。ISPピンの最後はGNDじゃなかったっけ。GNDの印を白のサインペンでよくピンヘッダーに印をつけていた。ひゃあ、そうだ。急いで資料を確かめる。そのとおり最終ピンがグランドだ。リセットとグランドを間違えて配線している。大失敗である。正しく配線しなおす。UARTは何事もなく正常に戻った。

 ISPのリセットとグランドは逆にしてもファームウエアの書き込みが出来ることを始めて知った。ISPはリセットをグランドにして動くので書き込みは問題なく動くが、終わったあとにおかしくなるものと思われる。いやいや「ISPはOK 従って 配線もOK」という思い込みが招いたお粗末だった。何事にも絶対は有り得ないということである。

カウンターのロジックはこれはこれで難しい(10/26/08)
 Webに沢山あるからと、たかを括っていたがまともに調べ始めると、周波数カウンターのロジックはたくさんあるが、簡単なロジックで正確に測るのは結構難しいことがわかった。

 特に、今度は信号発生器用の表示なので、測定器のように、正確な1秒の間、パルスをカウントして、1サイクルまで測るという直接的な方法は余り実用的ではない(一番正確だが)。周波数を変えていったときの表示が1秒毎というのは、いくらなんでも遅すぎる。微調整に時間がかかってしまう。

 使う側からみれば、測定間隔は短ければ短いほど良い。周波数を変化させて表示がそれに自然に対応すると言えば、最低でも1秒2回、出来れば3~4回は欲しい。しかし、1秒より測定ゲート(カウントを数える区間)を短くすると分解能は単純に下がっていき、数をカウントするだけでは、低い周波数では、荒すぎて話にならない。最低でも3桁の有効数字がでないとカウンターとは呼べないだろう。100Hz以下で例えば、1秒間に3回の計測では、3Hz刻みになってしまい、いくら自分しか使わないにしても気分が良くない。

 面倒だがレシプロカル方式のように、パルスの間隔時間を測るようにしないと低い周波数では使い物にならないことがわかる。しかし今度のプロジェクトに想定しているTiny2313はフラッシュが2Kしかなく、測定を2本立てにするとコードサイズが厳しい。なるべくひとつのロジックで低周波も高周波も測りたい。結構、難しいものである。Webの情報を参考に、あれこれ頭を捻った結果、とりあえず出来たのは次の仕様であった。

  • 2 バイト程度のカウンターと、タイマー値の変数を用意する。
  • 16ビットタイマーを300ms程度でオーバーフローするようタイマーのプリスケール値を決める。
  • 測定開始の最初のパルスと同時に16ビットタイマーをスタートさせ時間を測りながら
    パルスをカウントしていく(直接計数方式とレシプロカル方式を併用)。 
  • パルスカウントが最大になるか、タイマーのオーバーフローで測定を打ち切り、そのときのカウントと経過時間で周波数を求める。これにより低周波から、高周波まで同じロジックで周波数を出す。
  • マイコンの測定限界を超える周波数は、プリスケーラーからの分周パルスを入力パルスとし、所定の倍率をかけて表示する。
  • 入力が測定限界を超えた周波数かどうかは、予備的に短くプリスケール値をカウントし、どちらの入力を選ぶか判定する。

 この仕様だと、1Mhzあたりでは、タイマーの最小きざみが周波数パルスに近くなるので精度が高くならないが、周波数が低くなれば、小数点以下の周波数も 求めることが出来る。いずれにしても、マイコンが測れる最大周波数を実験で調べてからでないと、このあたりの緒元は決められない。ブレッドボードで組 んでいくことにする。

 ターゲットチップのTiny2313は、8bitタイマーひとつと16bitタイマーひとつを持っているのでカウンターのリソースに不足ない。ロジックに凝らなければLCDの表示まで2Kのフラッシュで出来る(だろう)。クロックを20Mhzとすると、一命令は、0.05μs。カウンターのクリアや、オーバーフローのインクリメントなどを含めて測定ループは10~15ステップに納まるだろう。とすると1ループ0.5~0.75μs。1Mhzあたりの周波数が上限か。WINAVR(GCC)のコンパイラーはオプションを最小(Os)にすると結構効率的なコードを作ってくれるので始めはこれで書いて、駄目ならアセンブラーにしよう。

参考:以下の横河電機の測定器入門講座のカウンターの記事は入門とは思えない詳細な解説で大変ためになる。
      http://www.yokogawa.co.jp/tm/TI/keimame/torjikan/index.htm

この方法では525Khzが限界(10/29/08)
 やっとのことで、安定して周波数が測定できるようになった。始め、頻々とMCUそのものがリセットし、最初は割込みなどを疑ったが、原因はヒューズビットの設定ミスというお粗末な原因だった。

 今度のマシンは周波数カウンターなのでクロックを20MHzという最高速で動かしている。今まで、Tiny2313をこんな高速で動かしたことがない。ヒューズビットの設定が8Mhz以下と以上で違うことに気づかず、あれこれ悩んでしまった。何となく動くと言うのも原因解明には障害になる。

 何しろ、UARTから結果が出ては来るのだけど、動きが不安定なのである。UARTがハングアップしたり、MCUにリセットがかかる。それに100Khzくらいで測れなくなる。タイマーの割込みをやめて、全部ループで組んでも同じ。そこで、計測ルーチンそのものをコメントアウトしてみたらそれでも起きる。ありゃりゃ、これは別の問題だ。残るはUARTだが、これまでと全く同じコードでこれが原因とは考えられない。

 試しに、シグナルジェネレーターからの信号を止めてみたら、トラブルが止まった。えー、ピン入力だけでおかしくなる?入力に使っているPD2ピンは、2313では多目的ピンで設定がおかしいのかとデータシートを確かめる。問題ない。パラパラとデータシートを見ていて、気がついたのがヒューズビットであった。思わぬところに原因があるものだ。何となく動いていたので今まで気がつかなかった。この前のリセットピンの配線違いと同じことである。やはり基本からの積み上げが大切であるということを痛感した。ヒューズビットを8MHz以上に設定して(CLSEL3~1を111)、2313は全く問題なく周波数を表示するようになった。Fctr

 さて、測れた最高周波数である。サイトのみなさんの周波数カウンターを見ていると、カウンターやCPLDなどでハードを追加されているのが多く、MCUチップだけで作られているのが意外に少ない。今作っているロジックは至極簡単で、ピンに入ってくるパルスを読み、立ち上がりパルスを律義に数えているだけである。測定ループでのステップが10から20 程度だと20Mhzのクロックで1Mhzまで測れるはずだが、結果は、残念ながら500Khz程度に留まった。

 理由ははっきりしている。Tiny2313は8bitマシンなので、カウンターのような大きい数字は、1バイトづつの命令で2回かけて処理しなければならない。WINAVR(GCC)で書いたコードを、.lssリスト(アセンブラになった命令が見える)で見てみると、立ち上がりパルスのときにタイマ時間と回数を記録するループは一周34ステップもあった。 20Mhzのクロックでは一命令の時間は0.05μsで、一回1.7μs。理論上でも最大周波数は、588Khz。計測できた最大周波数は525Khzだったので、ほぼ想定どおりである。

| | コメント (1) | トラックバック (0)

« 2008年10月19日 - 2008年10月25日 | トップページ | 2008年11月2日 - 2008年11月8日 »