« 2008年10月 | トップページ | 2008年12月 »

2008年11月の7件の記事

2008年11月28日 (金)

H8/3069FのMMCインタフェースがやっと動く

実にくだらないところが原因 (11/26/08)
 この夏からの懸案だった秋月のH8/3069LANボードのOS(MES)で、MMC(SDカード)インターフェースが動かない問題がやっとのことで解決した。OSのバージョンの問題もあったのかもしれないが、最終的な原因はここに書くのもためらわれる基本的でお粗末な原因だった。これを読んでも余り参考にならないと思うが、まあトラブルシューティングのケーススタディとしては少しは役に立つかもしれない。Pict0797

 ネット関係のマイコンでは、AVRのMega168で作ったプリンタ電源の遠隔制御が、あれから全くトラブルなく快調に稼動を続け子供たちから喜ばれている(階段の往復が一回で済む)。お父さんも鼻が高い。一方、このH8ボードは余り計画性なしに買ったマシンで、イーサネットインターフェースと2MBのRAMはついているが、Linuxを動かすには少し力不足で、イーサネットはそのうち雑誌の付録マイコン(インターフェース誌2008年7月号)にもついてきたので、H8の立場は微妙になっていた。

 H8の汎用ボードを作ったときも、SDカードスロットは作りこまず、ブレッドボード用のSDカード基板を流用して、基板にはそのソケットしかつけていない。結果としてはこれが良くなかったのだが、SDカードにこだわったのは、家庭内の小さなWebサーバーにするにしても、テキストだけでなくちょっと気の利いたテキスチャーを張った背景をつけたいとか、フラッシュメモリの書き込み制限が100回と少ないので、TFTPなどで起動のたびにプログラムを送らなくても良いように、独立の不揮発性の記憶装置が欲しかったからなどの理由である。

 しかし、こいつは最初どうしても動かず、クロックのクリスタルを20Mhzから25Mhzに換装するまで棚に放置されていた。クリスタルは表面実装でこの取り外しは、前の記事に詳しくあるように難儀を極めた。ちょうどフラックスが接着剤がわりになってクリスタルの背面シートが基板に固着しているうえ、ランドが大きく、サンハヤトの低温半田でも一部が溶け切れずランドをはがしている。ウェブで「H8」で検索すると、同じことをしてボードをおしゃかにした人の報告があったりして苦笑いである。

 そもそも換装したのは、MMCが安定稼動しているという古いカーネルを入れるためである。あれだけ苦労したのだから、意地でもMMCは動くようにしなければいけない。しかし古いカーネルに取り替えても、MMCは頑として動かない。ロジアナでシーケンスを追うと前と同じ、カードの初期化がすむのを延々と待っている。

 H8とMMCとのハード接続は、いくつかの回路例がウェブに載っているが余り大差はない。こちらのSDカード基板はchaN氏の記事そのままの回路に、3ステートバッファーの74VHC126を追加してレベルシフトしているが、ウェブではインバータや、NORの石を使って3.3Vと5Vのレベルシフトをやっている。デジタル的には全く変わりがない。しかもSDカードからはレスポンスが返っているので誤配線は考えられない。その証拠に、ブレッドボードに残したAVRのSDカードシステムでは問題なく稼動する。

 回路に問題がないとはいえ、ウェブとソフトが同じなので、ハードしか考えるところがない。プルアップ抵抗を、SDカードまわり(3.3V)からH8(5V)に移したり、AVRの回路図ではクロックがプルダウンされているのをプルアップにしてみたり、パスコンを大きくしてみたり、まあ、考えられる変更はすべてやったが、やっぱり動かない。

 途方に暮れて、こうなったら別のインタフェースをインバータで作ってみるかと、これまで色々いじったSDカード基板をすべて元に戻し、念のためAVRで動作確認してみたら、今まで動いていたSDカードアクセスが急に動かなくなった。半田付け?このあいだの半田ボール?いや、大丈夫。ロジアナを引っ張り出す。あれあれ、H8と同じように初期化でreadyが戻っていない。うーむ、これはH8のときと同じ現象だ。これは何かにおうぞ。

 おや、SDカードの電源をFETでコントロールするピンの配線がブレッドボードにない。いやこれは前からなかったような気がする。うーん、思い出せない。電源制御のFETのゲートは無接続で動くはずだ。念のため、ソースコードで確認する。うわあ、えらいことだ。電源ONはLowだ。H8のボードはここをどうしている。あーっ、何もしていない。これではSDカードの電源が入らない。しかし、入らないなら何故、レスポンスをかえすのだ。とにかくブレッドボードのジャンパーでピンをグランドに落としてAVRを動かす。問題なく元に戻った。これだ!

 電源が入っていないのに動く理由を調べているときではない。とるものもとりあえず半田ごてに電気をいれ、H8ボードのピンをグランドに落とし、SDカード基板を移す。あせる手で、コンソールに「mount  mmc1」とこれまで何百回も入れたコマンドを入力した。Ws000001

 アクセスランプが点き、エラーなしでプロンプトが返ってくる。やった。動いたようだぞ。「cd   /mmc1」を入れる。これもエラーがでない。どきどきしながら「dir」を入れると、やった、やった、差したSDカードのファイルリストが表示された。これ、これ、この夏から、夢にまで見た、H8でSDカードがつながった瞬間である。いやあ、長かった。苦労すればするほど喜びは大きいというが、電子工作での久しぶりの感激である。

 人間と言うのは因果なものである。楽しみだけでは人生は愉快に送れない。古いカーネルを入れてMMCが動かないときは、今やっていることだけでなくこれまでの人生すべてが無駄なことのようにみえて、自分の越し方行く末を暗い気分であれこれ考えていたのだが(いや、根が躁鬱なだけかも)、動いたとなると世界が一変して、まるで天下をとったような爽快な気分になる。アルコール中毒者が酒を飲むとそうなるらしいが、その意味ではこちらも少し中毒気味なのかもしれない。

大丈夫と思ったところが危ない(11/27/08)
 浮かれる気分はともかく、今後の課題として今度の騒ぎを整理してみた。まず原因は明らかで、SDカードの電源を制御するピンの勘違いで、グランド(電源OFF)、オープン又はHigh(電源ON)だとばかり思い込み、その配線をしなかったため、SDカードの電源が不安定になったことである(測ってみたら2V以上あった)。こんな基本的なミスが気がつかなかったのは、不安定ながらも、SDカードがコマンドにレスポンスを返したため、ここでのチェックを怠ってしまった。ブレッドボードでは恐らくグランドに落とすジャンパー線があったのだろう。それが、SDカード基板の接続替えのときか何かのときに偶然はずれ、AVRでも動かなくなった。

 しかし、H8でも、AVRでもこの状態(ゲートが浮いた状態)で、SDカードが初期化コマンドにレスポンスを返していることは、ロジアナで確認している。このレスポンスを見る限りでは、最新バージョンのMESのカーネルでも動いた可能性がある。 それはともかく、直接の原因はこの際、余り問題ではない。ここは本来、グランド(0)か、Vcc(1)でなければならず、無配線というハイインピーダンスの状況を追求してみても仕方がない。言えることは、これまでに何度も書いたようにデバッグの極意「デバッグは外へ、外へ」という教訓を忠実に守らなかったことである。Ws000000

 システムは膨大な要素で成り立っている。ひとつの要素が故障しているかどうかを確認するときは、普通、他の要素は正しく動いているという前提がなければ先に進めない。しかしトラブルは必ずしもその要素にあるとは限らない。プログラムのデバッグなど最たるものだ。問題だと思うルーチンのロジックをいくら念入りに調べてもだいたい解決しない。大抵は他のところに原因がある。

 これが、デバッグは外へ、外へと言う所以なのだが、今回はロジアナでカードのレスポンスを見たために、すっかりこの教訓を忘れてしまった。昔、ソフト開発の参考書を執筆したときに「絶対はありえない。変数より定数を疑え」などと偉そうなことを書いていたが、今回は正しく「SDカードは正常に動いている」という前提が間違っていた。お恥ずかしい。

 すべての前提を最初から疑い、ひとつひとつ複数の手段でその前提を確認して行ったらここまで解決が長引くことはなかったのではないかと思う。まあ、それにしても偶然ブレッドボードのジャンパー線がはずれたからAVRで動かなくなり解決の糸口が見つかった。もし、これがなかったらH8ボードは再びお蔵入りになっていたかもしれない。

 閑話休題。OSのMESのことである。小さなシステムの小さなOSだから多くは期待していなかったが、プログラムのロード以外にコマンドが何もないのに困った。欲しかったら自分で作れということなのだろうが、ネット関係はTFTPが動いたりそこそこ揃っているのに、ファイルの操作や、プロセスの管理はないに等しい(ファイルのdeleteがあるだけ)。一旦プロセスを動かすと、リセットしない限り止める事が出来ない(killがない)。

 それに開発元が、H8についてのサポートを打ち切ってしまい、このあいだソースの提供を電子メールでお願いしたけれど、今になっても全く音沙汰がない。一部のサイトには、デバイスドライバーの開発法が出ていたりして何とかコマンドの追加は出来るようだが、折角、MMCが動いたのに先行きが余り見通せなくなってきた。

 今、考えているH8での開発イメージは、シリアルコンソールをいちいち繋ぐのではなく、Telnetあたりからシステムを操作し、ウェブページの送り込みやHTTPサーバーの再起動、CGIによる別プロセスの操作などをやりたいのだが、相当量の作りこみが必要な感じである。それならもうちょっと汎用性の高い、TOPPERSプロジェクトのμITRONでも試してみようかと思う。

本来は、ネットワークとサーバーをどう、何のために使うか具体的に決めてから始めて、次にシステムを考えるべきなのだが、機械の方が先行してしまうのは、これはお遊びだから許してもらおう。まあ、世の中のプロジェクトだって余り威張れたものではないが。

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

2008年11月24日 (月)

H8/3069Fの水晶発振子換装で大騒ぎ

表面実装のクリスタル交換でボードが.....(11/22/08)
 ケースに入れた秋月のファンクションジェネレーターが稼動して、すっかり気が抜けてしまった。測定器の自作はあくまでも手段であって目的ではない。元々は、アナログ機器の調整用に、あらゆる周波数の信号が気楽に出せるようにケースに入れて周波数が見えるようにした。そこまでは良かった。しかし、いよいよこれを使ってどんなアナログ機器を作るかという段になって、急にやる気が失せてしまったのである。具体的な目標が見当たらないのだ。困った。

 最初はオペアンプを使ったヘッドフォンアンプでも作ろうと考えていた。そのために、オーディオ用の低雑音オペアンプと1WのパワーアンプICまで買ってある。計画では、昔のPCからはずしたCD-ROMドライブで卓上のCDプレーヤーにしようとでも思っていたが、考えてみると殆どのCD-ROMドライブには既にアナログ出力が出ている。これにアンプをつけてみても今さら始まらない。音質が良くなるとは思うが、これは今までに書いたように「良い音の地獄」に入りそうで余りやりたくない。

 そもそものアナログ研究のきっかけは、前のプロジェクト、リズムキャプチャーのときの音響パルス入力である。あのとき考えていた次の目標は、ネットを使った音声付きの電光掲示板で、音声発生のため、SDカードなどに入れたWAVデータをDACでアナログにすることだったのだが、CD-ROMドライブ出力からでは、DACの練習にしかならず、どうも食指が動かない。そう、AVR研究所と名乗るからには、マイコンが動かないと面白くない。

 ということで、秋月のH8/3069LANボードを棚から持ち出した。このボードは、この夏、OS(MES)のMMCインタフェースを動かそうと散々いじりまわしたが動かず、一時断念して放置してあるボードである。こいつは8ビットながらDACも持っているし、OSでMMCが動かなければchaN氏のコードをアプリケーションで動かしても良い。次の目標にもなる。

 それにこのボードは、このあいだ例のサンハヤトの実装部品取り外しセットのテストで、表面実装の20Mhzの水晶発振子を25Mhzに取り替えたまま、まだ動作確認をしていない。このクリスタルはキットの袋の中に、おまけのつもりか入っていたもので、換装しようとして基板の元のクリスタルが、2本の半田ごてを使ってもどうしてもとれず、くやしい思いをして、今度の取り外しキットでやっと換装したものである。

 この換装は、実は大変だった。半田が溶けたのは良いが、半田面が石の裏まで広がっており、その一部が良く溶けておらず水晶発振子を表面からずらすとき、無理をしてランドを大分ちぎってしまった。何とか残ったランドに新しい25Mhzの石を載せ固定したがFGキットの制作の方が忙しくてそのままになっている。Pict0795_2

 久しぶりに電気を入れてみる。クロックを25Mhzにしたので最初のカーネルロードからやりなおしである。このボードのクロックを25Mhzにしたのは実は目的がある。このあいだMMCインタフェースを動かそうと散々実験し、結局、MESの最新バージョンにMMCの不具合があるという情報で断念した。ところが別のウェブサイトで旧バージョンのMESのカーネルが公開されていることを見つけ、ダウンロードしたのは良いが、これが25Mhz版だったのである。

 旧バージョンならMMCも動くかもしれない。淡い期待を抱いて換装したボードの電源を入れる。しかし、フラッシュライターは「そんなシリアルインタフェースはないよ」とプログラムロードを拒否してしまう。H8のファーム書き込みは沢山の方法があるので別の方法と思ったとき、ちょっと不安になった。そもそもH8が動いているか確認していない。クリスタルがちゃんと接続されているかどうか確認するほうが先だ。

 不安は的中した。換装したH8のクロックが動いていないことがオシロでわかった。やれやれ。半田付け不良か。テスターでピンとクリスタルの接続をチェックする。うわあ、片側がコンデンサーとはつながっているが、肝心のピンとはつながっていないことがわかる。ランドをはがしたとき、ピンとの配線パターンを切ってしまったのだ。

 幸いH8ボードは2層基板でとりあえずクロック周りの配線は全て見える。ルーペでピンからの配線を調べると確かにクリスタルのランドの前でパターンが切れている。しかしピンからの配線パターンには余裕があり、レジストをはがして、クリスタルのランドから、そこへ細い線を半田付けすれば接続できそうである。カッターとピンセットで少しづつ配線パターンの上のレジストをはがし銅面を出した。そこへ、電子工作を始めるとき最初に買ったが細すぎて使っていない0.17ミリのUEW線をつけ半田を流してみた。おお、つながったようだ。引っ張ってみるがとれない。結構強く半田付けされている。テスターで確認する。うむ、しっかり導通している。やった。

 これで発振回路は大丈夫だ。通電する。しかし、ピンにはクロックがあらわれない。うーむ、やっぱり駄目か。原因はこれだけではないのだ。それにしても、可哀そうなことをした。何もしなければ少なくともハードは何の問題もなく動いていたのに、下手にクリスタルを換装しただけでボード全体が使い物にならなくなってしまった。LANコントローラがちゃんと動いてLEDが点滅するのが哀れである。

ピンとピンの間の半田ボール(球)(11/24/08)
 H8/3069LANボードがただのゴミになってしまった。大した値段ではない(¥3400)が悔しい。
「H8はもう古い、Linuxを動かすために新しいボードを買おう」と大分前に言っていたはずだが、やはり諦めきれない。心が残る。貧乏性というか、¥1の抵抗でも生きていれば、ニッパーで切り取らずに再利用しようと半田ごてで回収する性分である。ましてや、2MBのSRAMや、RTL8019のLANコントローラは無傷だ。H8そのものもHTTPのテストをしたくらいでまともに使っていない。

 いずれお家サーバー用に、SH3ボードか、ARM9 の玄箱くらい買うつもりはしているが、このH8ボード、まだ何かに使えるところはないだろうかと、動かないH8ボードを手にとって眺めているうち、ボードの両側に並んでいるコネクターピンのところに、半田屑が挟まっているのを見つけた。ちょっと大きめの半田が上から落ちたような形でピンとピンを完全にショートさせている。これはまずいよね、と取り除き、もしかしたらこんなことが原因で、まさかとは思いながら、まあ、ものは試しと電源を入れてみた。

 何と、これが原因かどうかわからないが、オシロで見るとH8のクロックピンにクロックが戻ったのである。周波数は25Mhzを指している。間違いない。あわててフラッシュライターをつなぐ。25Mhz用のMESのカーネルは順調に読み込まれた。PCのコンソールを立ち上げ、ボーレートを25Mhzのときの115200bpsにする。動いた! 

 MMCはどうだ。コマンドを入れようとして殆どのコマンドを忘れていることに気づく。とりあえずうろ覚えでMMCをマウントするが、やはりHardErrorでつながらない。しかし、前と違っていきなりではなく、暫く経ってからエラーになる。ハングアップもしない。少なくとも前よりは進んでいる。まあ良かった。これで解析が進められる。

 以前の資料を取り出し、手順を考えてから、暫く経ってコンソールにコマンドを入れた。おやまた動かない。MMCのところでハングアップしたか。電源を入れなおす。やっぱり動かない。調べてみるとクロックが出ていない。あれから何も触っていない。熱で水晶をドライブするコンデンサーの容量抜けを疑ったが、追加してみても同じ。テスターで導通を調べるが異常なし。何かさっき動いたのが幻であったかのような感じでまたH8は頑として動かなくなった。

 あーあ、やっぱりこわしてしまったか。それにしても何故動いたのか、突然、動き始めて、また突然動かなくなる。理由がわからないので、手の施しようがない。そもそもクロックが動かなければMCUはただの石である。コネクターピンにはMCUのI/Oポートしか出ていない。このあたりのショートでクロックが動かないということも本来有り得ないはずなのだが、調べるところがない。とうとう、これ以上の究明はあきらめることにした。

 次の日、机を片付けながらH8ボードの最後のお別れに、動かないことを確かめようと、電源を入れてみた。ありゃりゃあ、またクロックが出ている。一体これは何だ。PCコンソールと接続してみる。ちゃんとつながる。ネットワークを始動させるコマンドを入れる。大丈夫。HTTPサーバーのバイナリをTFTPで送ってみる。送れた。何だ全く問題ないじゃないか。794_2

 ところが、そうこうするうちにまた動かなくなった。うーむ、これはやっぱり換装した場所がくさい。発生熱かなにかで部品がやられたか、水晶か、コンデンサーか。それとも断線か。それなら動かすと変化がありそうだが、少々強く動かしても変化はない。テスターでクロックピンまわりをもういちどチェックする。大丈夫だ。断線はない。それとも、ショートか、いや5Vはしっかり出ている。もう一方は0Vだが、これで良いのか。そう言えば、今まで断線は疑ったが、ショートは余りチェックしていない。

 電源を切って導通を確かめる。何ということだ。クロックピンの片側がグランドとショートしているではないか。これはおかしい。やっぱり換装したクリスタルをはずしてもう一度ランドをチェックする必要がある。半田ごての電気を入れてもういちどはがす準備をする。

 「食事ですよ」との家族の声で作業を中断して、食事から戻って来て念のためテスターで問題のピンをチェックしたらグランドとショートしていない! えーっ、これはどういうことなんだ。熱だ。熱を持つところは今の回路ではCPUチップしかない。ルーペでボードをよくよく観察する。するとH8のクロックピンと次のピンの間に光るものを発見した。ピンセットでは届かず、まち針でつつくと動く。これだ!次のピンは、何だグランドではないか。小さく光るものは半田ボール(球)だ。間違いない。針でこれを取り出し、フラックスクリーナーで丁寧にふき取る。あやしい箇所がもうひとつあって、これも綺麗にする。

 いやいや貴重な経験をした。H8のピン間隔は0.5ミリ、配線パターンに半田付けしたときフラックスのために半田が飛んで、小さな小さな半田球がピンとピンの間に入り込み、熱でピン間隔がせばまりショートしたのだ。冷えれば接触がなくなり生き返る。796_2

 この球をとってH8ボードは全く問題なく何時間置いても動くようになった。いや嬉しい。死んだと思っていた行方不明の息子が帰ってきたようなものだ。もともとこのボードはMega168を立て続けに2つ壊したとき、衝動的に買ったもので、どちらかというと継子扱いされてきた。マザーボードは作ったが、使用目的が明確に決まっているわけではない。これから少し本気になって、こいつの行く末を考えてやろう。OS(MES)でMMCが動かないなら簡単に諦めずアプリケーションで作ってやることにしよう。

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

2008年11月17日 (月)

秋月キットを使ったLCD周波数表示付きFG完成

最後の最後でつまづく(11/15/08)Pict0788
 実装のため、ブレッドボードから部品を取り出そうとして、大事なテストをするのを忘れていたのに気づいた。10Mhz以上測るため、4分周した直接計時入力と、レシプロカル方式で測る入力を分離して測るテストである。

 これまでは、同じT1(PD5)ピンで動かしている。別のピンで受けても関係ないはずだが、念のためということもある。プリスケーラーとMCUのピンの間に100Ωの抵抗を入れて、パルスがなまり(オシロで確認)、悩まされていた測定値のふらつきが劇的に改善された例もある。ハードのテストは環境の自由なブレッドボードでしておくに限る。

 確認テストくらいのつもりで気楽に、ピンの設定をソフトで換え、ジャンパーコードを1本追加して動かしてみた。ややや、動かない。レシプロカル方式は計測を入力の立ち上がりパルスに同期させるため、ピンにパルスが来るまでいつまでもループして待つ方式である。オシロで入力波形をみてみる。ちゃんと波形が入っている。しかし、波形が小さい。そうか。2つの入力に同時に入れたために、出力が下がってパルスにならなくなってしまったのか。

 これは大問題である。MCUに入れる前に、増幅するか、デジタル化する必要が出てきた。思わぬところに落とし穴があった。しかし、これだけのためにインバーターICを使うのも芸がない。ましてや増幅するオペアンプは高周波用が必要だ。で、思いついたのが例のトランジスターによるスイッチングである。レシプロカル方式はそもそも500Khzまでしか測らない。

 早速、トランジスタを持ち出した。この前のアナログと違って飽和領域を使うデジタルなので簡単である。動かしてみた。オシロで出力波形を見る。ははは、アナログアンプになっている。抵抗を替え、めでたくパルス波形になった。レシプロカル方式の入力に入れる。うむ、やっと周波数カウンターが動き始めた。これで実装だと、念のため高い周波数に切り替えてみた。何と、今度は直接計測が動いていない。オシロを見るとパルスがでていない。

 やれやれ、トランジスタを飽和領域まで動かそうとすると電流が流れて、FGの出力が下がってしまい、バイナリカウンターそのものが動かなくなるのだ。試行錯誤しているうち、オシロの画面をみていて、ふっと気がついた。波形出力が下がっているのではないのだ。中位電圧が下がっているだけなのである。

 あわてて中位電圧を作っている分圧抵抗の抵抗値を確認する。ありゃりゃ100KΩだ。これはいくらなんでも高すぎる。マイクロアンペアのオーダーで中間が崩れるはずだ。これを5Kにする。おー、バイナリーカウンターが動き始めた。待てよ。もしかしたらトランジスタも必要ないかもしれない。785fctr

 そのとおりだった。トランジスタでパルス波形にしなくても、普通の正弦波で何事もなくレシプロカル計測は動き始めた。しかし、ノイズが多く、周波数表示にばらつきが多い。色々やっているうちに、このあいだ入れた100Ωの抵抗をとるとぱったりノイズがなくなることを発見した。抵抗を入れるとまたノイズ。雑音発生器になっている。結局、最終的に安定した回路は、トランジスタもなし、抵抗もなしの一番単純な回路であった。替えたところは分圧抵抗値だけ。いやあ、アナログは難しい。

あとは順調。遂にケースに入れた実装版が動く(11/16/09)
 周波数カウンターを作り始めてちょうど3週間、秋月のFGキットを使ったLCD表示付きのファンクションジェネレーターの実装版がやっと完成した。いやいや今回も楽しませてもらった。沢山の勉強をして、また経験値が上がったと思う。写真をとり、散らかった机の上を片付ける。プロジェクトの完了したときの気分はいつも同じだ。心は充実感で一杯なのだけど、ちょっと片隅に、何となくさびしい気分がよぎるのは私だけだろうか。

 ケースのレイアウトは、保守性を高めるため、構造に工夫がしてある。すべてのパーツをケースの下半分に固定し、しかも容易に分解できるよう、コネクターを4つも使って、LCD、VR、電源スイッチ、ロータリースイッチの間をつないでいる。上蓋は穴が開いているだけ(まだ開けていないが)で、部品は全くつけない。このあたりが、アマチュアと言えども、ちょっとこだわっているところである。

 実装版の配線は、久しぶりの完全試合で電源を入れるとすぐ動いた。FGからの出力をプリスケーラに接続する最後の半田付けを忘れていたから、完全試合でなくノーヒットノーランくらいかもしれないが、このところ凡ミスが続いていたので、最初電源を入れてLCDが表示されたときは、正直、本当にほっとした。MCUはちゃんと動いている。786fctr

 しかし、FGの方は動いていない。いじったところは、秋月FGの外部抵抗の設定ピンだけである。説明書を読み返し正しい設定にしたら元通り動き始め、ちゃんと周波数が表示された。万歳。これまでドライバーでちまちま変えていた周波数がつまみひとつで自由に変えられる。素晴らしい。

 波形選択はどうだ。おや、方形波が出ないぞ。これはソフトの疑いが強い。LEDが点くようにしただけで、正確な仕様を確認していない。説明書を読み返す。やっぱりそうだった。正論理と負論理を間違えている。始めつけないつもりであとで念のためにつけたISPピンが早速役に立つ。コンパイルし直したファームをISPを通して流し込む。これは便利だ。今度のレイアウトではLCDがMCUチップの上に乗っているので、もしこれをいちいちチップを外してライターなどに書き込む石だったら、とんでもない手間がかかっているところだ。

 ファームをとりかえて無事、方形波も出るようになった。LCDのコントラストが少し強すぎ見づらいが、これで周波数表示付き秋月FGキットの完成である。MCUのTiny2313のフラッシュサイズはプッシュスイッチで波形を選択できるロジックを入れて、ぎりぎりの2016バイト。分解能は、400khz以上が10hzである。それ以下はレシプロカル方式で測るため1hz以下(1khz以下は小数点2位まで)、レシプロカルは500khzまで動くがたまに不正確になることがあるため、安全のため400khzを境界にした。外部抵抗にしたためか最高周波数は24Mhzまで下がったが特に問題ない。そこそこのスペックに納まったと自己満足する。

 次の日、最後の工作、上蓋の穴明けに着手する。一番の難物は、LCDのスクリーンの窓明けである。このあいだのプラスチック工作ではマイクだけでなく、スクリーンも少し大きく開けすぎている。今度は慎重にノギスで何度も測って位置決めし、例のピラニア糸鋸で開ける。プラスチックほど楽ではないが、この糸鋸はアルミの1ミリの板でも快調に切れる。ハンドニプラーを買おうかと思ったが、これで今のところ十分なようだ。思ったより簡単に切り取ることができた。あとはやすりで整形する。

 これが済むとあとは、リーマでBNC出力と、DCアダプターの丸穴を広げるだけである。位置決めを丁寧にやったおかげで、誤差が少なく穴あけが楽だ。いやいや会心の出来だ。工作技術も大分腕が上がってきた。勢いに乗って、LCDのコントラストが強すぎる修正までやってしまう。始め半固定抵抗でコントラストの最適位置を測って、1Kと10Kの固定抵抗で分圧する。このあいだのLCDは電池で電圧が4.5Vだったので必要なかったが、5Vだと0.5Vくらいかけてやるとちょうど良いコントラストとなった。
Akifg_ctr_3
 秋月のFGキットを買ってきてから2ヶ月、カウンターの開発を始めてから3週間、遂に、ケースに入った周波数表示付のファンクションジェネレーターの完成である。ソースコードと回路図を公開することにする。ただ、ソースコードはともかく回路図は余り自信がない。少なくとも、こちらでは無事に動いているが何か基本的な誤りがあるかもしれない。自己責任でお使いください。

ソースコードはこちらから。前に公開したソースとファイル名が同じなので注意してください。回路図のハードで動く実装版です
注記:2011/4/29 eNastyさんの指摘でソースコードを直してあります。PD4とPD5が逆さまに
なっていました。回路図はこのとおりで間違っていません(PD4は外部クロックT0で固定)

「AKI_FCTR2313.lzh」をダウンロード

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

2008年11月16日 (日)

周波数表示付きの秋月FGキット制作も大詰め

ロータリースイッチでも26Mhzが楽々(11/10/08)
 秋月FGキットのケースのレイアウトで一番気を遣ったのが、周波数帯を決めるコンデンサーとロータリースイッチの位置だった。ウェブには、この秋月FGキットの沢山の制作例が紹介されており、凝った例では、リレーを並べて切り替えているものもある。秋月のキットにしては珍しくページの多い説明書には、「コンデンサーは半田付けしろ。スイッチで切り替えるな」とある。インダクタンスと浮遊容量で正しく動かなくなるそうだ。

 しかし、いくら何でも半田付けはないだろう。現に、ソケットにしてコンデンサーを差し込み、全く問題なく動作している。リレーにするのも工作心(ごころ)を刺激するが、それほど大げさにするのも何か抵抗がある。で、出来る限り配線に近づけたロータリースイッチでコンデンサーを切り替えようと考えた。

 基板の固定用の穴を開ける前に、ロータリースイッチに7ヶのコンデンサーを付け、仮配線をして、どれだけ動くかテストすることにした。グランド側が空中配線になってしまうが、うまくコンデンサーがロータリースイッチに固定された。これまでのコンデンサーのソケットがそのまま役に立ち、本体とはピンプラグで接続する。このコードの長さもあとで効いてくるはずだ。なるべく短くする。784

 スイッチを所定の開けた穴に固定し、FG基板をケースに入れて接続する。基板の位置決めも兼ねている。電源を入れる。おおー、これは楽だ。今まで、バラのコンデンサーをひとつひとつ入れ替えていた周波数切り替えが一瞬にしてできる(当たり前だ)。出力も安定している。

 高い周波数帯にロータリーをまわしていく。順調にオシロの波形が細かくなっていく。最高の周波数帯である22pFのところも問題ない。いよいよ最高周波数の挑戦だ。バラックでは、26Mhzが安定して出ていた(仕様上は20Mhzが上限)。微調整可変抵抗器のネジをドライバーで回し(これが結構面倒なのだ)、周波数を上げる。20Mhz、問題ない。何だ、バラックと同じ26Mhzまで軽く出るではないか。暫く様子を見るが、何の問題もない。方形波もオーバーシュートだらけだけどちゃんと出る。

 やれやれ、スイッチを使うなというのは、線を引き回すなということだったのか。心配のしすぎだった。ちなみにロータリーを未接続のところへ回すと(12接点もあるロータリーしかなかったので)、周波数は、29Mhzを示した。ロータリースイッチの浮遊容量分というところだろう。

意外にもろい3端子レギュレーター(11/12/08)
 久しぶりの事故である。それもお恥ずかしいことに、半田ごての熱で7805をおしゃかにしてしまった。これまで半田付けの熱でICを壊したことは一度もない。昔のトランジスタは熱に弱く、ピンセットでリード線を押さえて熱を逃がしたり、相当気を遣っていたが、最近は強くなったというし、半田ごてのパワーも小さいので殆ど気にしていなかった。まあ単価の高いCPUチップやICはソケットにして熱が直接かからないようにしてはいるが、3端子レギュレーターあたりは電源用で熱に強そうだしあまり気にとめていなかった。

 ちょうどグランド線が混んできて、非力な基板配線用の半田ごてではうまく半田が流れないので、30Wの電気配線用の半田ごてを持ち出したのが良くなかった。こいつは強力だが、こて先が太い。うっかりしてレギュレータの隣の端子と半田ブリッジをしてしまった。このブリッジを吸い取り線でとる作業が思いのほか時間がかかったのが致命傷になったのだろう。組み立てて通電したが7805なのに4Vしか出てこない。

 ちょっとショックだった。どうも3端子レギュレーターとは相性が悪い。前は逆接続して淡い煙とともに昇天させたし、こんどは初心者のやる半田ごてのあてすぎの破壊だ。原因は、はっきりしている。「レギュレーターを軽く見ている」からである。自戒。自戒。

 気を取り直して、部品箱をかきまわして予備の7805を探す、これがない!このあいだまでゴロゴロしていたのにどうして?あった。いやこれは負電源用の7905だ。そうか沢山あったと思ったのはこの7905だったのだ。これは困った。7805ひとつのために秋葉原に行くわけにはいかない。このまま作業を中断するのも気分が悪い。と思い出したのが、このまえに雑誌付録基板の時に買った電圧が可変できるレギュレーターLM317(秋月で4ヶ¥100)である。3個も残っている。このレギュレーターは、電圧が任意に変えられるのは便利だが、がた老AVR研究所は今のところ、5Vと3.3Vしか使用しておらず、抵抗器2つとはいえ、部品が余計に必要なので使っていなかった。

 これこれ、早速データシートをとりだし必要な抵抗値を計算する。3倍比の抵抗の組み合わせで5Vがでるようだ。こういうデータシートで困るのが絶対値が書いていないことだ。3倍の組み合わせは無数にある。雑誌の記事を参考に、手持ちの330Ωと1kΩにする。秋月で100個入り¥100という袋で買ってきてある定数のところである。ちょうど良い機会なので前からやりたかった、5%抵抗のバラつき調査をやることにする。仕事なら「この忙しいときに」と叱られるが、これがアマチュアの特権である。

 330Ωをやってみた。ロットで袋に入れていくのだろう。ばらつきは±5%に均等に散らばってはいない。つまり330Ωを中心に正規分布していない。私の買った袋は、320Ωあたりに平均値があり、分布は5%より狭い。結果として5%の中に納まっている。しかし、平均値が下に行っているので、欲しい333Ωは見つからない。331Ωで我慢する。

 電源部が少し広がってしまったが、LM317は何事もなく納まった。電気を入れてみる。ややや、0Vだ。何い、さっき出ていた負電源も0Vだぞ。顔が青ざめる。ショートさせたか。色々な部品を触って発熱を確かめる。問題ない。そのときテスターに手が触れて、一瞬、電圧が出た! いやいや悪いことは重なるものである。テスターのリード線が断線してついたり消えたりする。

 そういえば、このあいだからどうもテスターの調子が悪く、電池を取り替えたが、そのあとも導通テストが時々動かないときがあった。テスター棒の付け根で断線をしているようだ。まあ¥2000少々のテスター(これも秋月製)で耐久性を求めるのも酷な話だ。テスター棒は一体成型でコードだけの取替えは出来ない。今度の秋葉原に行ったときに棒ごと買ってこよう。

 テスターの導通を確かめて、もういちど通電。出た。4.997V。1KΩのところは990Ωを選んだお陰で、0.1%以内の精度の5Vである。いや思い通りに出ると嬉しい。いやなことを忘れさせてくれる。

ロジックは間違っていなかった(11/13/08)
 電源部の実装が終わったので、次はカウンター部の実装である。アマチュアの電子工作は、目的と手段がはっきりしないことで、これを仕事にしている人から見れば、「何という無益なことを」と呆れられることばかりだろうが、これが楽しいのだから仕方がない。

 3端子レギュレーターの分圧抵抗の選択など最たるものだ。 真夜中、袋から100個の抵抗を机にぶちまけて、ひとつひとつ抵抗を測っていく自分が我ながらおかしかった。そう、これまでのシステム開発の仕事は、目的に向かって少しでも前進できる、合理的、かつ効果的な、あらゆる方法を46時中考え続け、それを実行することが使命だったから、その反動ということなのだろう。

 翌日、断線したテスターの接続コードを見ていて、また脱線してしまった。プローブとコードは一体化されているので分解するわけには行かないが、断線した場所の見当はついている。プローブの付け根付近である。このテスターはコードを本体の横に収納できるようになっているので、収納するときここに無理がかかりやすい。

 はじめは、予想が正しいか確かめるだけのつもりで、ニッパーで線を切った。ピンセットで銅線を引っ張ったら、見事に予想通りの長さの断線のかたわれが出てきた。こうなるともう止まらない。プローブ棒がやわらかいプラスチックなので、ナイフで半分に少しづつ裂いて中身がどうなっているか調べ始めた。どうせ新しいのを買えばゴミになる運命である。

 少々裂いても全く変わらず、このプローブ棒は先端のピンをコードにつけたあと、プラスチックを圧着して作っているようだと独り言を言った途端、ひらめいたものがある。そうだここに切ったコードを半田付けしてあとはビニールテープかなにかで巻けば、少し短くなるがまだ使えるのではないか。笑ってください。写真が修復後のプローブである。ビニルテープを巻くまでもない。裂いた部分は、細い銅線で縛ってあるだけである。これで当面しのげる。783

 それはともかく、カウンター部の実装である。ブレッドボードで最後の調整を行った。クロック用のクリスタルの換装である。 この前、較正に使った20Mhzの発振器をMCUクロックにし、より正確にする。まあ、無線をやるわけでもないのでここまで必要ないと思うが、周波数カウンターと言うからには、少し贅沢をして恰好をつけてみた(といっても¥150だが)。

 絶対値の最終的な較正は、先日、秋月で買って来たプロ機並みの精度があるといわれる12.8Mhzの京セラの発振器でやる。周波数精度が1ppm、温度補償があって温度特性も数ppmというから、時計に使えば、月差数秒という高精度なもので、これで値段がたったの¥200。いやいや秋月電子さんには、テスターから何からお世話になりっぱなしである。値段が良心的なのが嬉しい。我々アマチュアの強い味方である。

 ブレッドボードに差し込む。Tiny2313のヒューズビットを切り替え(CKSEL1~3 を000)、まず、MCUを20Mhzの水晶発振器の外部クロックで動かす。 動いた。今度は、京セラの発振器にVccを入れ発振させる。オシロで波形を確認する。波形はあまりきれいではないが、ちゃんと12.8Mhzと表示された。784_2

 カウンターの電源を入れる。LCDに周波数が表示された。おや、6.4Mhzで数百ヘルツ多いぞ。何だ何だ。このまえ補正した分だけ多いじゃないか。ブログの記事にはそれらしく書いたが、実は書いてから、どうも腑に落ちないところがあって自分では納得していなかった。割込みルーチンでタイマーの処理をしている間にも、タイマーそのものは動いているから、最後の端数の調整は、本当なら計算で求めた値から少なめにしないと、その分余計に時間をとってゲート期間が増え、実際より高い周波数が出るはずである。

 ところが、最初の結果は、実際より低い周波数だった。最初の端数値は理論上の数で、遅れを考慮していない。本来なら、ゲートが長くなるので周波数は高くならないとおかしいのに、逆に端数を増やして(実際にはスタートを遅らせる)、ゲートを広げ、周波数を増やしてピッタリにあわせた。従って最初の狂いは、どうも当初の¥50のクロックの発振子の誤差のようである。

 端数を最初の理論値にもどして動かしてみる。ピッタリ6.4Mhzで20 hz以内に納まった。うむ、俺の計算が正しいことが証明された。微調整で1回だけひとつ端数を変えてみたが、50hz近く変動し、これ以上の調整はあきらめる。計算上は3.2μsの違いは0.4秒ゲートを開けているので6.4Mhzで5hz位のはずなのだが、割込みルーチンのロジックが増え、さっきの端数値に効いてくるからだろう。

 これで、カウンター部の構成が確定した。今度はLCDを乗せるため大きめの基板にしたのでスペースに余裕がある。部品も少ないし実装は楽だ。周波数表示付きの秋月FGキット制作もそろそろ大詰めを迎えた。

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

2008年11月 9日 (日)

周波数カウンターと秋月FGキットの合体

最後のひとふんばり(11/04/08)
 ソフトの開発は実装に向けて一段落したけれど、実はまだ心残りなことがある。秋月のファンクションジェネレーター(FG)は、ファンクションという通り、一応、正弦波だけでなく、方形波と三角波をジャンパーピンを切り替えて出すことが出来る。始めはTiny2313でソフト的に切り替え、LCDにその状態が表示されるとスマートだなと思っていたが、メモリはもう2Kぎりぎりまで使ってしまい、とてもその余裕はない。ディップスイッチにして外からいじれるようにしようか。いや正弦波だけであとは変えなくても構わないか。でも折角ある機能だし何とかできないかと色々考えていた。

 現在のバイト数は、1926バイト。残り100バイト少々では外部スイッチの実装はとても無理だと考えていたとき、ふと気がついた。周波数を測っているとき、スイッチの割り込みなど入ったら計測は少なくともレシプロカルでは目茶目茶になってしまう。むしろ、このプログラムでは外部割込みは使ってはいけないのだ。あ、そうか。割り込みなんて使う必要はない。レシプロカル方式のように、単純に、ピンの入力を監視しているだけでスイッチの替わりになるではないか。スイッチの反応は遅くなるが(周波数計測の合間だけ反応)、チャタリングを気にする必要もない。

 思いついたら、すぐ体が動くタイプである。2日間の研修講師の仕事がいよいよ明日にせまっているのも何のその、ひとつのピンを見ながら2つあるジャンパーピンの設定を順次に実現していくコードを書き始めた。プッシュスイッチを押すたびに、2本の出力ピンの状態がサイクリックに変わっていく。始めは状態遷移図などと大層に考えていたが、書いてみたら、if  elseを3個並べるだけでコードは完成した。

 コードサイズはぎりぎりの2040バイト。うーむ、LCDに表示するためにはこれではもう無理だな。まあ、とりあえず動くだけ動かしてみよう。考えたロジックが正しいか確認するのは動かすのが一番だ。

 と、やっぱりこれが動かない。スイッチを押してテスト用のLEDがつくところまでは良いのだが、想定どおりの動きをしない。LEDはこのあいだ面白半分に買ってみた2色出るLEDだ。千石電商の2Fで¥40で売っていた。2本アノードピンが出ていて赤と緑が点灯できる。あれこれいじる。状況は変わらない。同時につけばオレンジになるはずだが、オレンジどころが赤しかつかない。

 もしやと思って、このLEDを単独で点灯させてみる。ひゃー、こいつは一旦赤がつくと、緑をONにしても緑はつかないのだ。緑がついているとき赤をONすると緑が消えて赤になってしまう。オレンジが出るわけがない(このあと共通のカソードに制限抵抗を入れて点けようとしていたことに気づいた。アノード側に抵抗をいれてオレンジが出るのを確認した。LEDさんごめんなさい)。Pict0788

 あわてて、緑用の別のLEDをブレッドボードに追加して実験再開。しかし、緑はついたがやっぱり想定どおりではない。サイクリックにLEDが点灯しない。こんな簡単なロジックでどうして動かないんだろう。何度もコードをチェックする。間違いはない。10ステップかそこらのコードで振り回されている自分に段々腹が立ってくる。そろそろ焼きがまわったか。

 ロジアナまで持ち出す。外見は変化がないが、実は瞬間的な動きをしているのかもしれない。しかし、何も問題ない。見えている状況と変わりはない。調べることがなくなって、気分を鎮めるため少し休む。デバッグで頭に血が昇ったらおしまいである。気持ちを落ち着かせて考えてみると、AVRを始めた頃、ピンとポートの違いがわからず大騒ぎしたことを思い出した。今度は大丈夫か。基本に立ち返ってもう一度このあたりから点検することにする。

 LED(将来はジャンパーピン)をドライブするピンはDDRで出力方向に指定し、その状態はPINに入力をかけて値を得ている。正しく値を得ているようだ。おや、ピンへの出力をピンに対して行っているぞ(PIN = 1<<PD2)。ふむ、ちょっとおかしいけれどLEDはこれでちゃんと点いている。では、PIN = 0<<PD2はどうだ。ややや、これは0にならない。これはどういうことだ。

 要するに、PINに1を書き込むとそのピンは1になるが、0を書き込んでも0にはならない。そもそもPINに出力することに意味がない。PORTに対して書き込まないと状態は変わらない。最初のLED点灯がたまたまPINへの出力で動いたために基本的な間違いに気がつくのが遅れたのだ。

骨身を削ってコードを押し込む
(11/06/08)
 間違えて設定していたPINをPORTに換えて、めでたくスイッチは想定どおりサイクリックにLEDをドライブするようになった。計測の合間でしかスイッチのPINの状態を見られないので、スイッチを少し長く押しておく必要があるが、まあ、しょっちゅう動かすスイッチではないので問題ないだろう。

 問題なのは、LEDでなく最終目的のLCDへの表示である。LCD関数の呼び出しだけで数十バイト、最低3ヶ所必要なので、60バイト以上のメモリのスリム化が必要である。既に削れるところは削ってしまった。もう削るところはない。ダイエットした人間にさらに痩せろと言っているようなものである。

 しかし、この作業はなつかしい。昔は、メモリが小さかったので散々この作業をやった記憶がよみがえる。昔を思い出しながらソースコードを調べなおす。調べれば出てくるものである。保守性を上げるため、一旦ワークエリアにデータを揃えてから次のステップに移るところや、LCDの表示の順番、データ初期化の場所を換えてステートメントを減らせるところ、わかりやすく65535を掛け算しているところを16ビットシフトに変えるなど、2バイト、4 バイトと、それこそ爪に火をともすような節約作業を続ける。

 カウンターの初期化などは下手に省略すると暴走したりするのでいちいちコンパイルしなおして確認しながらの作業である。4バイトコードの処理はうまくやると大幅なメモリの節約が出来るので苦労の甲斐がある。SRAMを節約できるフラッシュから直接データを取り出す関数は、必ずしもメモリを普通のSRAMにおく関数よりフラッシュを喰うとは限らない。かえって減ったりする。まさしく試行錯誤である。まあ、これはこれなりに面白い。ただしコードは読みにくくなって保守性は間違いなく悪くなるが、これは仕方がない。

 数時間の努力の結果、サイズはそれでも100バイト近く縮めることが出来た。やれば出来るものである。これでLCDにも出せそうだ。LCD出力を組み込んでコンパイルしてみた。やったやった。2Kバイトを割る1988バイトだ。動かしてみる。おお、2行目にSIN(正弦)、SQR(方形)、TRI(三角)の波形表示がサイクリックに出た。小数点表示も出せたし、これでソフトの実装は満足できる状況になった。残るはハード工作である。

 昨日、研修が早めに終わったので秋葉に寄り、秋月で低電圧版でない20Mhz動作保証の標準電圧版のTiny2313を念のため買い(¥100)、千石でハード実装に欲しかったLCD固定用の長めのスペーサー(25ミリ)を手に入れた。くやしいことに千石で、このあいだ買ったサンハヤトの実装部品取り外しセットが買った値段より¥300 も安く売られているのを見つける(¥4200)。ここはミニルータを郊外のDIY店より安く売っていたりして油断がならない。

 帰宅して、ケースの位置あわせをする。このあいだ作った両電源の位置は全く合わず、ちょっとがっかり。もういちど作り直す必要がでてきた。しかし、買ってきたスペーサーはぴったり製図どおり高さが合い、心配した強度も十分だ。これでハード実装の不安材料はなくなった。順調に作業は進んでいる。

ケースの工作と微調整(11/8/08)Pict0783
 この前買ったタカチのケース(YM150)の工作を始めている。これまでのケースはすべてプラスチックで気楽に穴を開けられたが、今度はアルミとは言え、金属製のケースである。ただ、厚さは1ミリなので、今のミニルータで何とかなるだろうと考えている。しかし、これもやってみなければわからない。工作が楽になるように、慎重に手順とレイアウトを考える。

最も厄介なLCDは、基板の上に長めのスペーサーを立て、追加する汎用基板の上で、片側を固定し、残りの側は、スペーサーをLCD側のみ固定して基板の上に置くことにする。片側は秋月のFGキットの基板の上なので下手に穴を開けることが出来ないからである。

 このあたりは現物合わせで工作していくしかない。確定しているところから線引きを始める。まず、周波数を切り替えるロータリースイッチとFGキットのコンデンサーピンを可能な限り近づける配置を選ぶ。これで側面パネルとFG基板の位置が決まる。周波数変更用のVR2つと、波形選択のプッシュスイッチをレイアウトし、電源スイッチは側面のパネルにスペースが出来たので当初予定の後面から前に持ってくることにする。

 ここらあたりが決まると、あとは現物合わせで工作ができそうである。今日の土曜は雨でテニスが流れたので、お昼すぎから、いよいよアルミ板の工作にとりかかった。ケースは側面にのりしろがついているので、簡単に万力や工作台で固定できない。冶具と呼ぶには大げさすぎるが、かまぼこ板2枚をケースの奥行き分だけの長さに切って、ケースに入れて補強し、ドリルスタンドに立てて固定し、スイッチの穴あけを開始した。

 ミニルータでも意外に簡単に穴が開いた。ほっとする。調子に乗って、電源スイッチ用の方形の穴を、ミニルーターのカッターで切ってみた。おお、これは楽だ。最初はドリルの穴を連続してあけてニッパーか何かで切り取る予定だったが、これなら板が歪む心配もなくあけられる。

 しかし、このスイッチの穴は折角綺麗に開いたのに、やすりがけのときに誤った方向に削りすぎてしまい(ストッパーの付いているほうを削りすぎ)、しっかり固定できない穴になってしまった。やれやれ、調子に乗るといけない。この前のマイク穴といい、イーサネットマイコンのときの放熱孔といい、調子よくいった後がいつも失敗する。まあ、あとでボンドで固定してしまえば良いのだが。Pict0782x

 何とか側面パネルの穴あけが終わったので、仮組み立てをしてみる。いやいや久しぶりのアルミ板工作にしてはうまくいった。残る大物の穴あけ工作は、上蓋のLCDの表示パネルの窓と、BNC出力の穴、DCアダプターの入り口の3つである。こういうのに比べれば、基板の固定穴を開けることや、配線は楽なものである。

 ソフトのほうは、1/4のプリスケーラーを常時動かすために、直接計測のインターバルタイマーの修正をする。直接計測が16ビットのカウンター(タイマー1)を使っているので、8ビットタイマーで切りの良い時間を作る必要がある。これまで0.1秒を100回ばかりのオーバーフローで作っていたが、1/4分周で同じ分解能をだすためには0.4秒にしなければならない。フラッシュがもうないので、16ビットの変数は使いたくない。8ビットの変数で、今までのルーチンをさらに4回くりかえすロジックを加える。ついでにもう少し精度を上げることにする。

 というのは、Tiny2313のクロック用にこのあいだ秋月で少しまともな20Mhzの水晶発振器(発信子でなくVccで出力される部品)を買ってきて調べてみたら、どうも1Mhzで数百サイクル近く低いことを発見した。誤差にすると数百ppm。オシロの周波数表示は4桁までで、そこまでは合っているが、桁上がりの様子をみていると、この水晶とオシロの方が正しいようだ。
Pict0787
 数百ppmの誤差は、クロックに使っている発振子の誤差なのか、ソフトのバグなのか微妙なところだ。ただ、オーバーフロー割込みが0.4秒だと500回近く起きるので、ここでの遅れはばかにならない。タイマーは割込みが起きた後も動いているので、端数を設定するときは、ここでの遅れを勘定に入れておかないと全体が短くなってしまう。とりあえず、この水晶発信器の周波数に合わせることにする。試行錯誤の結果、端数を1つ増やしてループさせ、最後に1tick(3.2μs)加えると、5Mhzでピッタリ10hz内外におさまった。いやあ気分が良い。6桁まで0が並ぶ表示を見て一人ご機嫌になる。

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

2008年11月 3日 (月)

2方式の周波数カウンターを2313で動かす

基本的な誤り(10/29/08)
 どうもおかしい。クロック20Mhzのマイコンの周波数計測が最大1Mhz以下というのはどうみてもおかしい。Webでもういちど調べてみた。こんなにみんな苦労していない。CPUクロックの半分の周波数は測れると書いてある。どうしてだろう。あああ、なんだ、わかった。カウントを数える直接計測はもっと簡単な方法があるのだ。タイマー/カウンターの機能に、外部クロックによるカウンターの駆動というのがあるではないか(だからカウンターなのだ)。今まで何と言う無駄なことをやっていたのだ

 やれやれ、おかしいと思った。これを使えば、少なくともクロックの半分くらいまでは測れるはずだ。プログラムを大幅に変更することにする。ただし、カウントするだけなので、計測時間が0.1秒なら分解能は10hzになるし、低周波では最低でも1秒は測らないと使い物にならない。これまでのレシプロカル方式で、時間を内部クロックで測りなおすという2本立ての測定ルーチンが必要になる。メモリが足りるかどうか。

 メモリのことはあとで考えるとして、カウンター入力によるプログラムをコーディングする。こちらのロジックは滅法簡単で、一定時間のゲートを開けてカウントするだけである。あっけなく出来た。動かしてみる。おお、10Mhzまでなら楽々測定できる。10Mhzがほぼ測定限界で、11Mhzではかえって周波数が落ちる。ハングはしない。

 計算を楽にするため切りの良い時間を作るのに良いタイマーの設定が見つかった。CPUクロック20Mhzで、8bitタイマーのプリスケールを64にしてTickを3.2μsにすると、122回(256×122×3.2=99.9424ms)まわした端数が18(0.0032×18=0.0576ms)できっちり、0.100秒になる。クロックが正確ならどこまでも0.1秒である。

 オシロとの周波数の誤差は全くなかった。温度特性はわからないが使っているクリスタルは一ヶ¥50 の普及品なのに立派なものである。少なくともオシロの表示する数字とは完全に一致している。1桁ほどこちらのほうが細かい。満足満足である。ただ前にも書いたように、あくまでも周波数測定ではなく、シグナルジェネレーターの周波数表示用のために作っている。なるべく早いタイミングで計測をしたい。とすると分解能を上げるためには、前に作ったレシプロカル方式のロジックを併用する必要がある。どのあたりでこの直接計測に切り替えるか、レシプロカル方式の測定期間をどの程度にするか、調べなければならないことが沢山でてきた。

 まず、レシプロカル方式は、どれだけ細かい時間まで計測できるかが、有効桁数を上げる決め手になるので、CPUのタイマーをプリスケールなしの最高速で動かすことにする。しかし有効桁数を上げるため大きな数字を取り扱おうとすると、計測時の変数は簡単に2バイトの上限(65535)を超えてしまう。4バイトデータのやりとりは2バイトのときよりはるかにステップを喰うので使うわけにはいかない。おのずと測定期間や最大測定カウント数が決まってきた。

 プログラムロジックは最初のプログラムとほぼ同じで、パラメーターを変えるだけだったので、プログラムはすぐ動き始めた。フラッシュサイズは2方式の測定、UARTを入れても1800 バイトどまりでLCDに切り替えても何とか入りそうである。

 UARTに直接計測で出した周波数と、新しいレシプロカル方式で出した周波数を並べて表示し、テストに入った。測定範囲が5Hz(レシプロカル方式の測定期間による下限)から、500Khz(I/Oポート入力を繰り返すループロジックの上限)ととんでもなく広いので、チェックしていくのに時間がかかる。

 最初にでてきたデータは、あっているところが少しある程度で、どこも全部違っていた。直接計測の方は、10Hzの分解能ながら見事に10Mから低周波まで、オシロが出す周波数と一致している。これはすごい。それに対して、レシプロカルは不安定極まりない。同じ周波数でも測るたびに違うし、第一合っていない。まあ、これからが勝負だ。少しづつバグをつぶしていこう。

 まず、すぐ分かったのは、タイマーオーバーフローのキャリーフラグ上げと測定時とのタイミングの違いによるミスである。何しろタイマーをCPUのクロックと同じ最速(0.05μs)で動かしている。測ったときとタイムアウトしたときのキャリーを一致させるため、やりたくなかったが、ループの中に時間記録と同時にキャリーも保存するステップを加える。

 次に頭を悩ませたのが、周波数帯の一部で、突然、測定周波数が不正確になる現象である。これは、UARTに途中経過の変数を逐一表示させ、数字をチェックして、4バイトのデータの桁あふれを見つけた。4バイトは10進数で9桁あるのだが、計算の段階の、ある変数の範囲で10桁になることが分かった。

 マイクロセカンドの世界なので通常の数が6桁、除算は乗算より桁を取らないとはいえ、うまく分割して計算しないと、32ビット(4バイト)でも難しい。周波数を出すのに一回の計算ではできないので、始め3回分けて計算していたのを工夫して2回に減らしていたがその配分がまずかった。WINAVRで64ビット変数が使えることを発見し、喜び勇んで入れてみたら、フラッシュサイズがいきなり5Kを超えて唖然とする。そう世の中は甘くない。775

ロジアナさまさま(11/01/08)
 細かいバグを追いこんで、段々レシプロカル方式も精度が上がってきた。しかし、キャリーの食い違いによる誤った周波数表示は稀にだが起きるし、周波数が低くなると全く不正確になる。どうも一回分パルスをミスしているようである。2回に分けた計算法も自信がない。Webに助けを求めるが、出てくる記事は、大掛かりな多倍長演算の手法ばかりで、こうしたちょっとした多数桁の計算のヒントになるようなものはない。

 特に低周波が不正確なのは痛い。直接計測では1秒測らないと最小桁が出ないので、このあたりはレシプロカルに頼るしかないのだが、これが安定しない。こんな低い周波数のところで、1周期見逃すはずがないのだが、結果は見逃した形になっている。キャリーの食い違いは、どうしても起きることがあるので、とうとう計測ループの中に割込み禁止命令を挿入して対処した。これで最大測定周波数は500Khz以下に下がってしまったが背に腹はかえられない。

 低周波の方は万策がつきた。とうとうロジックアナライザーの登板をあおいだ。ソースの上では数命令先だが、もしかしたら意外な時間をとっているのかもしれない。割り込みがかかって別のところにいくのかもしれない。実際に確かめてみようと言うのである。要所、要所に、ピンをドライブするsbi(PORT,PIN)などの命令を挿入し、そのピンにロジアナのプローブを接続して動かしてみた。

 机上には、オシロ、シグナルジェネレーター、ブレッドボード、アッテネータ、ロジアナなど所狭しと機材が並ぶ。いくつか挿入ポイントを変えてテストするうち驚くべき事実が明らかになった。

 測定期間にはいったあと、最初のパルスを確かに一回見逃しているタイミングチャートがでてきたのである。ほんとだ、タイムアウトのときに何かおかしくなると予想していたが、最初でまるまる1パルスをとっていない。一体これは何だ。何故最初の立ち上がりだけ見逃す? うわあー、わかった。立ち上がりパルスかどうか決めるスイッチ(前の状態を保存)を測定の前でクリアしていない。プログラムが動く最初は初期化しているが、このルーチンは無限ループの中にあるので、その都度、クリアしておかないといけない。

 わかってしまえば、馬鹿みたいな原因である。前回の測定終了後のスイッチの状態で、たまたま正しくなったり間違ったりする。不安定な状態に見えるが原因は単純なミスである。今回は、タイマーのお守りに注意が集中し、割込み要求のマスクや、レジスタ設定と初期化などには熱心にチェックしていたが、ここまでのチェックを怠っていた。Photo

 それにしても、ロジックアナライザーが大活躍である。その威力をあらためて実感する。そうか内部でわからないときはこうしたプローブ点を作ればいいのだ。ひとつ勉強した。嬉しくて、電源を切るときロジックアナライザーに深々と頭を下げてお礼をした。

 これで、周波数カウンターの開発は峠を越した。必要部品も確定したので、安心してケースの工作にも入れる。25Mhzまでの計測は最初、リレーかなにかで10Mhz以上を4分周に切り替えて測ろうと思ったが、少し大げさすぎるので、直接計測式はすべて4分周で400khz以上を測り、それ以下はレシプロカル方式で測定しなおすことにする。直接計測は測定期間をこれまでの4倍(400ms)にすれば、当初の10hzの分解能は確保できるはずだ。

なんとかTiny2313に納まった(11/03/08)
 ロジアナのおかげでトラブルも収束し、直接計測式も、レシプロカル式もほぼ正確に周波数が出るようになった。次は、テスト用のUARTから、実装用のLCD表示に切り替える作業が待っている。しかし、フラッシュサイズはもう2Kバイト近くで余裕がない。祈るような気持ちで、UARTのライブラリをはずし、LCDを組み込む。

 コンパイルしてみる。やっぱり2Kバイトを超えてしまっていた。8桁の周波数を表示するためchaNさんのxatoiのライブラリを利用させてもらっている。書式付の出力関数(xprintf)は特に便利で楽なのだが、コードを喰うのが難点で、xprintfのステートメントひとつで100バイト近く増えるときがある。

 テスト用にいくつか書いていた出力関数をひとつに減らし、ライブラリにある使っていない関数をコメントアウトしたりして、何とか2K(2048バイト)以内におさめた。動かしてみる。と、また、全くLCDが反応しない。やれやれ、今度のLCDライブラリはピンの配置を自由に選べる最新版で問題ないはずだがと、ソースを見る。あーっ、単純にループする待ち時間が調整されていない。今度のプログラムは最速の20Mhzである。LCDはビジーフラグが動く前の段階の初期化に、一定の待ち時間を作らないとうまく動かない。そうか、これもコンパイラーオプションのF_CPUなどを使って自動的に変わるようにしないといけないな、と、このころは余裕を持ってデバッグしていた。

 しかし、その後もLCDは頑として動こうとしない。ビジーフラグを見るルーチンもはずしてみたが駄目、ウェイトの時間を増やしても駄目、コマンドenableの間隔を変えても駄目。配線の導通チェックも異常なし。UARTで状況を見たくても、もうメモリがない。だんだん顔が青ざめてくる。調べるところがなくなって、またロジアナに助けを求めることにした。

 そのときふと、データシートの表紙が目に留まった。Tiny2313には2つ種類があって、10Mhzまで動く低電圧版のTiny2313Vと、Vなしの20MhzまでのTiny2313がある。あーっ、私が秋月から¥100で買ってきた2313は低電圧版の2313Vだ。しかし、今までの何の問題もなく動いていた。UARTのときはピンが少ないので20Mhzでも動いたが、LCDのような多ピン駆動のときはロードがかかって駄目になるのだろうか。あわててオシロでクロックを確認する。少し電圧が低いけれど、クロックは20Mhzで動き、波形の乱れもない。

 ロジアナで見てみよう。動いていなければ買いなおしだ。確か、普通版の2313も秋月では¥100の値段に変りはなかった。どきどきしながらロジアナをつなぐ。これが、何と、ちゃんとというか、所定の初期化のコマンドシーケンスを送っている。しかし、初期化した後、全く反応がない。へえ、低電圧版でも20Mhzで動くんだと妙なところで感心するが、先が止まっていることに変りはない。

 これはもうLCDが原因ではない。何か別の原因でプログラムがスタックしている。試しにメインループに入る前にLCDにテストメッセージを出してみる。LCDが動いた!やっぱり、他の原因だ。どこを直した? UARTの部分をとりはずしただけである。それ以外に不要と思われるステートメントはフラッシュ節約のために色々変えた。そういえば初期化の割込み禁止のステートメントもはずした。ついでに解除(sei())のステートメントも。

 ええー、割り込みは禁止にしない限り、解除を入れる必要はないよね、と思いながらも半信半疑で元に戻して動かしてみる。驚くべきことに、これで動いたのである。タイマーの割込みが入らないのでスタックしていたのである。割込みを使うときにはsei()が必ず必要とは全く考えもしなかった。やっぱりバグは外に潜んでいたのだ。今日の朝からのトラブルがこれで解決した。Pict0778

 やっとのことでLCDに周波数が表示された。表示用だから更新間隔は短いほうが良いと最初考えていたが、余り早いと、下2桁くらいが見えなくなり、こういう表示は0.5秒くらいが一番見やすいことがLCD表示をさせてみて始めてわかった。

 しかし、フラッシュサイズはほぼ満杯の状態でこのままでは何も出来ない。メモリリダクションの作業に入る。まず、8桁の数字の一行表示だけに機能の豊富なxatoiライブラリを使うのは勿体無い。自前のルーチンを作る。これで200 バイト近くを減らした。次はLCDライブラリである。ピン配置が自由だけれどサイズは少し大きくなっている。これを今までのライブラリに切り替える。こちらは150バイト近くのメモリ節減になった。

 この余ったメモリを、やりたかった低周波数での小数点以下の表示に150バイトほど費やして、結局フラッシュサイズは、1926バイトに納まった。Tiny2313で、5hzから10Mhzまでの周波数カウンターのソフトの完成である。何とか、2313の2Kバイトのフラッシュに押し込むことができた。Pict0780

 直接計測からレシプロカルの切り替えは500Khzで自動に行い、11Mhzあたりまでこれだけで測れる。20MhzまではカウンターICで4分周して使う予定でこれは実装のときに細かいことを決めるつもりだ。分解能はレシプロカルはタイマーTickが0.05μsで、0.2秒ほど測っているので、上限の500khzあたりでも1hz近辺(理論上)。直接計測も0.2秒の測定ゲートで分解能は5hzとなっている。4分周するときは、測定ゲートを倍くらいにして分解能を10hz以下にしたいと思っている。

ここにTiny2313の周波数カウンターのソースコードをAVRstudioのプロジェクトファイルの形で置いておきます。ピンアサインはソースのコメントをご覧下さい。PD5がカウンター入力であることが変わっているだけで、それ以外は変わったところはありません。回路図は全体が完成してから公開する予定です。なお、入っているLCDライブラリのLCD.cとLCD.hは、名前は同じですが、最新のものとは中身が変わっています。ご注意ください。

「FCTR2313.lzh」をダウンロード

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

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月 | トップページ | 2008年12月 »