エントリー

カテゴリー「make:」の検索結果は以下のとおりです。

Si5351Aを応用する その1 スクロールクロック編

  • 2016/03/17 09:43
  • カテゴリー:make:

 さて,作ったからには,使わないといけないというのが私の工作のポリシーでして,Si5351にATtiny13Aで散々検討したわけですから,なにか面白そうな応用を考えてみましょう。

 まずは,バカバカしい応用例として,あの「スクロールクロックの源発振」への応用を試して見ましょう。

 我らが秋月電子に古くからある時計キットの1つに,スクロールクロックという物があります。シャープ製の10x10ドットマトリクスLEDが特価で入ってきた時に,ほぼ同時に発売されたキットだったと記憶していますが,我々はそんな古いキット(しかもPICですよ)が未だに売られているという現実を、ベストセラーと解釈するか,あるいは不人気と理解すべきか,大いに悩むところです。

 不人気の可能性に言及したには訳があって,このキット,確かに面白いのですが,作った瞬間からとにかくがっかりなキットなのです。

 まず,精度が全然出ません。トリマコンデンサでクロックを微調整出来ますし,機能の1つとして進みと遅れを0.08秒/日単位で調整することも出来るのですが,まあとにかく全然追い込めません。結果を見るのに24時間かかると言うも途方に暮れますし,そうこうしているうちにクロックそのものがずれたりしてしまうので,もう暗闇を手探りで歩くようなものです。

 根気よく頑張って,結局調整範囲を超えてしまうことがわかると,もう一気にやる気がなくなります。こういうキットこそ,無調整でばちっと精度が出るように作らないといけないと思い知りました。

 その上,10x10ドットという中途半端なドット数による文字の読みにくさ,10ドットしかないところでスクロールされても一度の表示される情報が少なすぎて,なんだかよく分からない表示になる,LEDチップが小さく,しかも隣と間隔が開いているので少し離れてみないと読めない,でも離れてしまうと小さくて読めないという,結局読めないづくしの時計なのです。

 ラーメンタイマになるのがオチだという書き込みも2chにあったりしたほどですが,1日で数十秒もずれるラーメンタイマでは,ラーメンすら美味しく作れません。

 ある日私は,「それなら周波数カウンタで正確に合わせてみよう」と思い立ちました。プローブの容量で周波数が変わってしまうのを避けるため,わざわざ発振回路を作り,バッファを噛ませてから測定を行い,狙った周波数に合わせます。

 ・・・はて?合わせる?どの周波数に?

 取説を読むと,4.194340MHzとあります。でも,これでは分周しても正確な1秒を作れません。4.194304MHzの間違いじゃないのか?

 付属していた水晶発振子を見れば,4.19としかマーキングされていません。なんじゃそりゃ。これ,最初から精度なんてどうでもいいと思ってるでしょ。

 ところがこの水晶を使って,4.194304MHzには出来ませんでした。4.194349MHzにもうまく合わせる事が出来ず,この水晶はあきらめました。

 手持ちを探すと,自動車のECUに使われていたフィリップス謹製の4.194304MHzが出てきました。おお,これはすごい。これで発振回路を組んで,ばちっと4.194304MHzに合わせます。これで楽勝だと思って数時間後,派手にずれているではありませんか。

 ここで私は力尽きて,スクロールクロックはジャンク箱に放り込まれることとなりました。

 今回は,これを復活させようというわけです。そもそも,前回までの検討では,クロックの周波数の理論値が分からない上に,発振周波数も小数点2桁までしか記載がなく,温度特性も含んだ精度だっていい加減です。時計が狂うのは,何が原因か分からないじゃありませんか。

 そこでTCXOにSi5351Aです。これなら実力で1ppm以内の精度を作り出せます。

 まずは,取説のとおり,4.194340MHzを作ります。これで試してみると,24時間で7~8秒程度のズレが出てきました。ということは,4.194340MHzが理論値ではないということになります。

 なら,取説の誤記と考えて,カウンタを22段使えば1秒が作れる4.194304MHzにしてみましょう。それでも,3時間で数秒のズレがしまいました。どうやら,これも違うようです。

 なら,なにが正解なのか。ソースもありませんので,推測するしかありません。そもそも,このクロックをどんな風に使って1秒を作っているのかさえも解りません。空ループをまわして作っているんだとしたら,ちょっと心許ないです。

 ざっと計算すると,4.194340MHzの時,86400秒(24時間)で7秒ずれたわけですから,これがぴったり86400秒になるような周波数は,切りのいいところで4.194MHzです。

 この時計の設計者は,どうせ精度など追い込んでも仕方がないし,水晶発振子も4.19MHzまでしか書いていないようなものだから,とりあえす4.194MHzで作っとけ,あとは調整頑張れ,という軽いノリで作ったんじゃないかと思います。

 かくして,Si5351Aに4.194000MHzを設定。ちゃんとこの周波数が出ていることを確認して,スクロールクロックの電源を投入。

 24時間経過後,1秒ほどずれていました・・・こんなことをやっていたら切りがありません。24時間で1/100秒に追い込んでも,3ヶ月もすれば1秒ずれるわけです。しかも,それがわかるのは3ヶ月も先です。(これはこれで立派な精度なんですが)

 そもそも,こういうことが面倒だから,理論値をびしっと生成出来るSi5351Aがありがたいのですから,こんなやり方ではどうにもなりません。

 かなり投げやりな気持ちで4.19394MHzという適当な値を設定し,24時間経過後にすると0.8秒くらい遅れた感じです。

 もう面倒になったので,時計の機能として備わっている補正機能を使います。0.08秒ステップで調整出来るという事ですので,初期値60に対し,63だとちょっと進みます。62でちょっと遅れる感じです。

 そこで今は,4.19396MHzにして様子を見ています。長い目で見ていくしかなさそうですね。


 次に行った応用は,今回の本命,周波数カウンタのタイムベースなのですが,これは長くなるので次に。

Si5351Aを検討する その5

  • 2016/03/09 14:52
  • カテゴリー:make:

 前回までで,Si5351を使う環境は整いました。しかし,その周波数の素性が悪ければどうにもなりません。以前書いたように,長期的精度については問題はないと思いますが,原発が2ppmでも最終的に20ppmになってしまうようだと,これを使う意味がありません。

 少なくとも精度くらいは見ておきましょう。

 繰り返しになりますが,原発は26MHzのTCXOで初期精度が±2ppmです。そして設定後Si5351Aから出力された周波数は,CLK0から10MHz,CLK2から9.765625MHzが出るようにしてあります。

 ちょっといい周波数カウンタで測定してみたのですが,

CLK0からは9.99999586MHz
CLK2からは9.76562085MHz
原発の26MHzは25.999988MHz

 という感じでした。これを割合で計算してみます。

絶対精度(20℃,電源投入後5時間経過)
CLK0は10MHzに対し,-0.414ppm
CLK2は9.765625MHzに対し,-0.425ppm
原発は26MHzに対し,-0.46ppm

 こんな感じです。ここから言えることは,TCXOは十分仕様を満たしていること,Si5351Aの出力の精度は,そのまま原発の精度を引き継ぐこと,の2つです。これは狙い通りです。

 さて,気になったことが1つ。出力をオシロスコープで見たのですが,10MHzは短期的な周波数変動がなく,ぴたっと10MHzと表示されています。しかし9.765625MHzは,ふらふらと周波数が変動し,平均すると9,765625MHzに近づいていくという感じになりました。

 これ,Si5351の分数分周に起因する揺らぎではないかと思うのですが,実はオシロスコープのトリガのかかり方が,10MHzと違って不規則になるため,揺らいで見えるだけかも知れません。

 本来だとスペアナでスプリアスを見れば分かることだと思うのですが,私はスペアナを持っていませんので,あきらめました。

 他の方がスペアナを使ったレポートを上げてくれていたので見せて頂きましたが,分数分周でもスプリアスは小さく,無線にも使えるレベルだという話でした,

 まあ,分数分周の場合,分数比の設定でジッタやスプリアスの出方が変わって来ますので,この結果だけを見て判断出来ないのですが,とりあえず短期間での精度については分からないことが多くて,使う時には注意ということだけは,覚えておきましょう。

 それにしても,SI5351Aは面白いICです。いろいろ応用を考えています。安いし,しょーもない検討にも気兼ねなく使えます。

 ということで,次回はSi5351Aの応用についてです。

Si5351Aを検討する その4

  • 2016/03/08 14:01
  • カテゴリー:make:

 さて,貧乏生活が抜けきれない私は,50円の8ピンマイコン,ATtiny13Aを使って,Si5351Aを設定しようと企て,同じAVRだし楽勝だろうと思ってtiny2313のコードを移植したものの,まったく動いてくれません。

 はて,何がだめなんだろうと首を練っているところから,今回の日誌は始まります。

 なにせ,2313でちゃんと動いているコードで,しかも単なるGPIOの制御だけのものですから,これで動かないなんてのはちょっと考えにくいわけです。あれこれと試行錯誤をしますが,状況は変わらず。

 こうやって,適当に試行錯誤をすることは,私はそんなに無駄ではないと思っています。確かに理論的ではありませんが,そういう理由も理屈もない手当たり次第な方法によって,なにか変化が見つかれば,そこを手がかりにして尻尾をつかむことができます。

 分からないからといって何もしないと,何も前に進みません。こういうときは,余計なプライドは捨てて,初心者に戻るのです。

 で,コードに問題がないとすると,コンパイルオプションをいじってみようという話になりました。クロックの設定,最適化の設定を変えても変化はなし。この過程でヒューズビットの設定を誤り,ライタで書けない13Aを作ってしまったことは内緒です。(後日ヒューズリセッタを作って復活させましたのでご安心を)

 ところが,CPUの設定を13Aから2313に強引に変えると,なんとまあ動いてしまったではありませんか!これには驚きました。

 これはどう考えたらいんでしょうか。コードにミスがないから動いている,そして動かないのはコンパイラのオプションのせい,ということは,コンパイラのバグなのか!

 しかし,私の環境はAVR Stuidio4.19という古い物で,十分に枯れています。これでこんなバグがあるんだとしたら,世の中の13Aの大半は動かないんじゃないでしょうか。

 いや,でもコンパイラのバグというのは,案外あるものです。もうバグだと決めつけて,最新の環境に変えてみようとしたり,バグの情報を探して半日が過ぎました。しかし成果なし。誰もバグなんてことは言ってません。

 さらに手探りをします。それでは,2313以外に動くCPU設定はあるだろうか?

 試してみたら,これが案外あるんです。動く物と動かない物,かなり拮抗した感じです。ただ規則性があるようでありません。85Aでは動くけど45Aでは動かないとか,そういうよく分からない状況なのです。

 こんなに動く物と動かない物が出てきてしまうなら,もうコンパイラのバグのはずがありません。もう一度疑いの目を自分に向けて見ましょう。そうです,コンピュータというのは,指示されたとおりにしか動かないものなのです。

 ここで,ふと,13Aのメモリが小さいことに気が付きました。いや,プログラム格納用のフラッシュメモリが半分になっていることは分かっていましたが,RAMも半分,EEPROMも半分になっていることを,あまり意識していなかったのです。

 RAMはたったの64バイト。Cでコードが書けるギリギリのメモリと言ってもいいでしょう。

 この続きを,私が嫁さんに説明した会話を再現してみます。嫁さんはソフト屋で,こういう失敗談を笑い話として聞いてもらえる,貴重な相手なのです。

 ・・・

私:まず,I2Cで設定するレジスタの値は,配列にいれてあるわけよ。
嫁:うんうん。
私:ところが,私はこいつをconst宣言してなかった。
嫁:ぶーー(笑)。あんた何年組み込みやってんのよ。
私:そんなん,今どき広大なRAMがあるんやから,いちいちconstなんか宣言せえへんよ。
嫁:またそういう屁理屈を・・・まあええわ,それで?
私:ところが,const宣言しても,動かない。
嫁:ほー。
私:ここがAVRの特殊な事情で,const宣言してもRAMは使うのよ。つまりROMとRAMの両方に同じデータがおかれるわけ。
嫁:なんでそんな無駄な仕組みなのよ?普通const宣言すればRAMにはおかれないよね。
私:そう,これはAVRがハーバードアーキテクチャゆえ,データとプログラムが別々のメモリに配置されるようになっているから,なのね。置かれているものはプログラムだけという前提のROMにデータがおかれていても,それはデータとしてアクセス出来ない。それで結局RAMにコピーするわけ。
嫁:うーん。const宣言だけではだめのか・・・
私:まあ,そもそもconstなんてのはコンパイラに「定数ですよ」と教えて上げるだけで,そこから先はコンパイラ任せよね。「だからどうしたてやんでいバーローチキショー」と冷たいコンパイラやったら,ROMにもRAMにもおくわね。
嫁:ところで,そのレジスタの値は,何個あるのよ?
私:それが,100個ほど。
嫁:なるほどー。それで64バイトのRAMからはみ出すのか。
私:そう,だから128バイトのCPUを使うと,const宣言をしていないこのコードでも動いたわけよ。けどここであきらめる訳にもいかん。なんとかRAMを使わない方法で設定をしないといけないんで,google先生にすがってみたのよ。そうすると,先人達が便利な方法を考えてくれていて,配列をプログラムメモリにおき,使う時にこれを引っ張り出してくる方法を用意してくれてあった。プログラムメモリだけではなく,EEPROMにも置けるようになるという,素晴らしいもの。
嫁:それで,動いたの?
私:うん,動いた!
嫁:それはよかった。というより,本当に何年やってるのよ?組み込み。
私:でも,なんでCPUのオプションを変えると動くんだろうとおもわんか?
嫁:確かに。
私:実は,この設定値,後半の50個ほどは,ほとんどゼロ。意味のある設定値は前半の数十個だけなのね。
嫁:なるほど,RAMが大きいCPUの設定であれば,実メモリが存在しないところでもなんとなく動いて,ゼロを書いてくれたと。でも正しいCPUの設定では,そこで別のデータが読めてしまい,動かなかったと。
私:おそらく,そういうことやろうね。

 とまあ,こんなほほえましい夫婦の会話があって,結局AVRに特有の,定数の置き方を使う事にしました。

 この,AVRならではの方法ですが,プログラムメモリに置く方法とEEPROMのおく方法の2つがあります。どちらも,RAMからデータを取り出す命令とは異なる手順と命令を使いますから,使いやすいようにライブラリとして用意してくれてあるんですね。

 具体的には,最初にavr/pgmspace.hをincludeします。そして定数の定義には,

const PROGMEM unsigned char hoge[] = {xx,xx,xx...};

 読み出しには,

a = pgm_read_byte(&hoge[x]);

 とします。もしこれがプログラムメモリではなく,EEPROMの場合にはavr/eeprom.hをincludeした上で,

const EEMEM unsigned char hoge[] = {xx,xx,xx...};

 読み出しには,

a = eeprom_read_byte(&hoge[x]);

 とします。もしbyteではなくwordの場合には,byteの部分をwordに書き換えてやればOKです。

 当然ですが,前者は定数を変更する場合には再ビルドが必要です。一方後者はプログラムだけではなくEEPROMにもライタで書き込みを行わないと動きません。ヒューズでEEPROMを保護していないと,プログラムの書き込み時にEEPROMが消去されてるようですので,気をつけましょう。

 話を戻すと,tiny13は1kByteしかプログラムメモリがありません。だから定数は出来るだけEEPROMに追い出したいです。それに,プログラムをいちいちビルドしなくても,EEPROMの内容を書き換えるだけで,欲しい周波数の設定に書き換えることが出来ます。これはこれで便利でしょう。

 最後に,設定が完了したらLEDが点灯し,ブザーがかつての国民機のようにぴぽっと鳴るようにして,最後にSLEEPモードに入るという仕上げを行い,なんとかSi5351を任意の周波数発生器として使える環境が整いました。プログラムメモリは,およそ半分強使っています。

 こうしてやってみると,50円のAVRでも,それなりの事が出来るもんだなと思います。特にI2Cは2本しか使いませんので,8ピンのマイコンには最適です。

 I2Cがあれば,センサもディスプレイも発振器も,全部まとめて2本です。実際に使ってみてつくづく思ったのは,やっぱり8ピンというのは,回路を作るのが楽です。2313のように20ピンもあると,配線だけでも結構多いですから,面倒だし,ミスも起きます。

 Si5351Aも面白いのですが,8ピンの13Aも,いじりがいがある面白いマイコンです。

 ということで,次は,作った周波数の簡単な評価です。

Si5351Aを検討する その3

  • 2016/03/07 14:19
  • カテゴリー:make:

 さて,前回までで,SI5351AがTCXOで動き,しかもその精度を維持したまま任意の周波数を生成出来ることがわかりました。I2Cで設定するだけで動くのですが,そうはいってもI2Cですし,100バイトを超える設定値ですので,マイコンを使う以外の選択肢はありません。

 それでmbedを使いましたが,これでは大きすぎて,あるいはもったいなくて,組み込めません。安いマイコンを使いたいところです。

 私が慣れているAVRのATtiny2313を使えばいいと思っていましたが,これ,I2Cがありません。ソフトでエミュレーションして動かせばどうにかなるだろうと思ったのですが,もうAVRも長く使っていないので,頭がまわりません。

 google先生にいろいろ聞いてみたら,ありがたいことにサンプルコードがいくつか見つかりました。I2Cって,単純な書き込みであってもリードをしないといけない部分があるので,ソフトでの実装は案外面倒なのです。

 ちょっとした試行錯誤はありましたが,そこは使い慣れたAVRです。tiny2313でSi5351Aを設定する事に成功し,10MHzと9.765625MHzを生成することが出来ました。

 で,最新のtiny2313の値段を見てびっくりしたのですが,なんと随分値上がりして,230円になってるんですね。私は100円でたくさん買ったのですが,こんな値段になっているんだとすると,大切に使わないともったいないです。

 I2Cは2本で通信するものです。他にマイコンで制御しないなら,2313は確かにもったいないです。ならばと8ピンのtinyを探してみれば,tiny13Aというのがありました。50円。安い。

 これなら今回の目的にぴったりでしょう。ただし,メモリが小さいので,ちゃんと実装出来るかどうか不安ですが・・・

 とりあえず,tiny13Aを10個ほど入手。どうせ大した事はしていないので,そのままリビルドすれば動くだろうと思ったのですが,さっぱり動きません。

 ここからが長いのです。続きます。

Si5351Aを検討する その2

  • 2016/03/04 15:05
  • カテゴリー:make:

 前回は,Si5351Aと26MHzのTCXOを買い込み,設定値をツールで作り,I2Cにはmbedを使って試して見ようというところまで書きました。今回はその続きです。

 ともあれ,回路を作らねばなりません。SI5351Aは10ピンのSOPですので,0,5mmピッチの変換基板にのせて,DIPに変換します。こういう場合,0.1uFのパスコンをチップで一緒にのせてしまうとよく効くし,綺麗です。

 ついでに,TCXOものってけてしまいましょう。裏側にベタGNDがありますから,ここにTCXOをハンダ付け,ちょこっと配線をして完成です。さらにI2Cはプルアップ抵抗もここに取り付けてしまいます。

 これをブレッドボードに差し込み,mbedのI2Cと繋ぎます。

 mbedのサイトを見ていると,同じmbedのNXPのチップ用に,Si5351の設定プログラムがアップされていました。ありがたいことです。早速使わせてもらうことにし,STM32F401用に修正してコンパイルしました。

 動かしてみたところ,I2Cは動いているようなのですが,Si5351Aは黙ったまま。おかしいなあと見直して見ると,なんとVDDとVDDOが繋がっていません。VDDOというのは,出力ポートの電源で,本体のVDDとは分離されています。これで,クロックを与える相手の電源に合わせる事が出来るのですが,ここをうっかり配線するのを忘れていいました。

 繋いで見ると,あっけなく波形が出てきます。本当にあっけなくです。0.4ppm程のズレがありますが,それは原発の26MHzのズレがそのまま出ているようですので,気にしても仕方がありません。計算すると,とりあえず10MHzも9.765625MHzも,ちゃんと出ているようです。

 26MHzの原発:25.999988MHz
 10MHz:9.99999586MHz
 9.765625MHz:9.76562085MHz

 こんな感じです。どれも-0.4ppm程度です。

 ただし,オシロスコープで周波数を計ってみると,10MHzの周波数は変動しないのに,9.765625MHzはふらふらと周波数が変動するんです。

 どうやらこれが,分数分周の副作用のようです。

 分数分周というのは言葉の通り,分周比を分数で設定出来るものですが,普通にカウンタを回していたら2のn乗しか設定出来ません。

 これ,わかりやすく言うと,10段の階段を3回で登るにはどうするか,という話です。3-3-3で飛ばして登れば,1つ余ってしまいます。そこで3-3-4という具合に,1度だけ4段飛ばすんですね。そうすれば10段の階段を3回で登ることができます。

 しかし,3段と4段とでは飛ばした段数がちがいますので,3段と4段は同じ長さではありません。長い目で見れば10段分の長さですが,1回ごとに見れば,長さが違うわけです。

 今回の分数分周も同じような話で,長い目で見れば(つまり平均では)9,765625MHzなんだけども,短い目で見れば(つまり1周期や2周期では),9.765625Hzではないのです。これはつまり9,765625MHz以外の周波数成分,すなわちスプリアスを含んでしまうということです。

 最近は無線でこの技術がよく使われるため,特にスプリアスのない綺麗な波形が必要ですから,なんとデルタシグマを使ってスプリアスをぱーっと高い周波数に追いやったりするそうですが,Si5351Aがそういう高度なことをやっているかどうかは,わかりません。

 とはいえ,私の場合,周波数カウンタのタイムベースに使いたいわけですから,長期的な精度が出ていれば全然OK。分数分周の問題は,私にはあんまり関係ないと,逃げる事にしました。

 さて,ここでまた一区切り。ここまでで分かった事は,

・Si5351Aは外部クロックを入力しても動く。
・レジスタの設定値はSi5351Cで作って,ちょこっと修正。
・I2Cで書き込めば,さくっとお望みの周波数が出てくる。

 です。私は高周波をやりませんので,波形の純度はあまり関心がなく,長期レンジにおける精度だけ気にしていれば良いという,気軽なご身分ですので,基礎検討はここまで。

 あとは,これを実用的なシステムに完成させる検討です。そう,mbedをそのまま組み込めません。そもそも,100バイトほどのレジスタ設定をI2Cでやった後はなにもすることがなく寝ているだけなのですから,mbedはもったいない。

 ここは,安価なマイコンにやってもらうことにしましょう・・・続く。

ユーティリティ

2026年01月

- - - - 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

検索

エントリー検索フォーム
キーワード

ユーザー

新着画像

過去ログ

Feed