STM8S-discoveryで作る高精度な時計
sorry. japanese only.
古いコンテンツだけど,まあ秋月でもSTM8SのMCU単体を扱っているから。多少は?ね?
--
[STmicroの製品ページ]
[番外編STM8S-discovery]
RTC(DS3231)を乗っけて時計をばこさえた
[製作の経緯]
先日,秋葉へ出向いたときに秋月でSTM8S-Discovery評価キットが目に入ったので,
使い道も考えずとりあえず入手してみた。
MCUはSTM8S105C6(ROM32KB/RAM2KB)というAVRのATmegaと真っ向からぶつかるような
レンジの製品を使っている。こちらは懐かしいアキュムレータアーキテクチャだけどw
まぁ,いろいろググってみると本来の評価対象となるこのMCUなんかよりは,
USB-SWIM(ST-LINK)アダプタのMCUとして同ボードに搭載されているSTM32F103C8の方が
立派でCortex-M3として使い手がある。という情報が割とあって笑ってしまった。
ともあれ,折角入手したのだから,STM8Sをいじってみようと思う。
STM8Sの供養が終わったら,STM32もいじれば二度楽しめてお得な感じだ。
→ 供養も終わり,STM32を再利用してMaple-mini互換ボードをこさえてみました。
[調査&準備]
ハードをいじるには最低限に以下の3つを見ればいいと思う。
・ユーザーズマニュアル:ボード自体のマニュアル(回路やコネクタの説明など)
・STM8S105xx MCU製品ガイド:STM8S105C6の固有情報(割り込みベクタなど)
・STM8Sシリーズ リファレンスマニュアル:STM8Sシリーズの周辺機器の解説(メモリマップや各種レジスタの情報など)
ほかにアセンブラで逝ってみよう!!という人は,こちらも参考にするといいでしょう。
・STM8Sシリーズ プログラミングマニュアル:STM8Sシリーズの命令語解説
C言語での開発には,メーカー提供のIDEとしてST Visual development toolsと,
Cコンパイラ(Cosmic社製とレゾナンス社製があるが,当方では評価版でも
オブジェクト32KBまで生成できるCosmic社製の評価版を使うことにした)が必要。
インストールやCコンパイラの評価版レジスト方法は,適当にググるといいでしょう。
開発環境を入れたら,Developing and debugging your STM8S-DISCOVERY application code
もダウンしておくと,その中にあるレジスタ定義ヘッダ(stm8s.hなど)が使えて便利。
(かつてstm8s_fwlibと呼ばれていたものだと思う)
アセンブラとリンカはIDEに含まれているから,それで十分な剛の兵ならIDEだけでOK。
[ハード製作]
さて。これでLEDも点滅させることができた。ハハハ,一見大成功!!
まぁ準備も整ったわけだが,取りあえず表題のとおり,時計でも作ってみよう。
RTCは,ジャンク基板から剥がしてきたDS3231(今はなきDallas製)を,評価ボードの
SOPのスペアランドに貼り付けて,スーパーキャパシタでバックアップ。
これで万事OKダワ!!
ついでに入力用のタクトスイッチ2個とデバッグ用にシリアル出力を付けて...
さらには完成後にSTM32S部分を切り離してもいいように電源用の端子を付けておく。
評価ボードからは,ピンヘッダでほとんどの信号が出せるようになっているので,
バラのピンコネケーブルでCLCDと接続。汎用のCLCDを使うので電源は5Vとすりゅ。
ハードはこれだけ。
と思ったが,まさか!そんな!まさか!!
実際に動作させて見るとTIM1のインプットキャプチャが動かないのさ。
んで,よくよくユーザーズマニュアルの回路を見てみると,TIM1のキャプチャ入力
ch1&ch2が,ヘンテコなタッチセンサに使われている。SB3,SB4という半田ブリッジ
(0オームのチップジャンパが乗ってる)を切り替えておかねばならなかった。
きっとジュラル星人の仕業に違いない!!
まー,タッチセンサなんて操作性の悪い入力デバイスは使わないので迷うことなく,
半田ブリッジにコテを入れてOFFにした。
接続図(時計動作に必要な部分のみ記載)
実際の外観(CLCDはバラのピンコネケーブルで接続)
[ソフト製作]
ハードができたらファームウェアを作る。
ただの時計ではアレなので,折角RTCがTCXOで精度を稼げるみたいだから,
微調整して狂いの少ない時計を目指してみようかと思う。
TCXOの微調整自体,このRTCのAgingOffsetレジスタをいじることでデジタル的に簡単に
行える。確度誤差が±3℃の内部温度センサもおまけで付いている。
ネ,ネ,温度表示もやるだろう?
☆くぅん?温度表示は見世物ではないし,そんな無闇に見せることは許されないんDa!
あとは, 微調整の方法だけど,目標はなるべく手間かけずに(最長でも1日くらいで)
GPSのPPSを使ってTCXOを1ppmくらいまで追い込めるようにしたつもり。
(まぁ,TCXOと言っても温度で数ppm動くから調整直後だけなんだけどね...)
微調整のための測定の方法は,周波数カウンタ使ってもかったるいし,精度も高が
知れてるので,GPSのPPSとRTCの1HzSQW出力の位相を測る方法でやることにした。
位相を測るにはMCUのタイマを使ってのインプットキャプチャで,測定時に外部PPS
を評価ボードに入れてやるだけとした(前述したハードのTIM1のインプットキャプチャ
の動作テストはこれをやるため)。
GPSのPPSoutは揺らぎが±1usあるので,TIM1のカウンタはus(MHz)単位で回すことに
した。
時刻あわせや精度測定のための設定は,追加したタクトスイッチだけでできるよう
にしてみた。
で,できたのがこれ。
・プロジェクトツリーと接続図画像の詰合わせ
[評価]
SW-1を押すことで,時刻などの変更する項目にカーソルが移動して,SW-2をそこで
押すことで対象の値を変更するというシンプルな操作。
ギミック的機能で,SW-2を押しながらSW-1を押すとアジャストや早送りが行える。
簡易時刻あわせとして, 時刻表示中にはSW-2だけを押しても反応しないが,SW-2を
押しながら,SW-1を押すことで00秒アジャスト(0-29秒なら0秒へ戻し,30-59秒なら
次の分の0秒へ進める)できるようにした。
微調整用のAgingOffset以外にも,PPSソースの変更に対応できるように,キャプチャ
条件でPPSパルスの立ち上がり/下がりエッジの変更やTIM1の精度変更(プリスケール
を1/1〜1/200のレンジで段階選択)できるようにした。
(デフォルトでは,TIM1プリスケール1/2(1MHz),RTCPPS=FallEdge,GPSPPS=RiseEdge)
ボタン操作で,微調整モードに入るには,SW-1を何度か押して時刻調整画面で,
カーソルを2行目の最右端に移動(その際に'>'が表示される)した状態で,SW-2を押下
すると微調整モードに入る(ここでSW-1を押すと通常の時刻表示に戻る)。
微調整モードからの復帰は,同じくカーソルを1行目の端(右でも左でも)に移動し,
そこでSW-2を押下すればよい。
時刻調整でも,微調整でも値を変更したらカーソルを移動させるコト。カーソルが
変更された項目から移動することで反映するようになっている。
動作中の様子(上:時刻表示,中:時刻調整中,下:TCXO微調整中)
↑微調整中の画像でdt:xxxxの項目がRTCとGPSのPPSの位相差を16進数表示している。
ついでに画面では,ch1がRTCのSQW1Hz出力でfallエッジ,ch2がGPSのPPSでriseエッジ
で位相差を計測する設定を表している,2行目右端の数字がTIM1プリスケールのイン
デクス値を表し,同じく2行目左端の1BはAgingOffsetの値(16進数値)を示している。
TCXOの周波数偏差は,基準となる時刻のdt値と,ある程度の経過時刻でのdt値との
差を,経過時刻(s)で除した値で表すことができる。
TIM1プリスケールインデクスが1の場合には,TIM1のクロックが1MHzとなり,dtが
1usで表され,その場合にはそのまま算出値をppm値とすることができる。
つまり,ある時刻でdtがD9ACであり,その3600秒後にdtがD7F1となった場合には,
(0xd7f1 - 0xd9ac) / 3600 = -0.123ppm となることを表している。
この場合に負値はTCXOがGPSのPPS基準からの位相進み(高い周波数への偏差)を表す。
RTCの内部分周による1HzとGPSのPPSの位相差だけで測定するため,ある程度dtの推移
傾向が掴めれば,STM8Sも止めてRTCのバックアップ動作における調整もできる。
当然GPSのPPS入力は,計測時のみ接続すればよい。
ただし,RTCの内部分周カウンタが時刻の秒を変更するとリセットされるため,時刻の
秒を変更するとdt値がジャンプするので,その点は留意する必要がある。
このRTCは内蔵された温度センサとAgingOffsetの値を基に,内蔵のクリスタルに接続
された帰還容量を変化させて調整するコトでTCXOとして機能する様になっている。
dtの値が時間経過によってもなるべく変化しない状態を保つようにAgingOffset値を
調整変更することで,TCXOの周波数偏差を微調整することができるわけだ。
ちなみにAgingOffset値(-128(0x80)〜+127(0x7f))が大きいほどTCXOの周波数が低く
なる。ついでにVccが高くなると高くなる。なるほど,RTCのデフォルト3.3Vだが,
今回製作の回路では,電源が5Vなので上昇分だけ低く調整せねばならないわけだな。
この微調整機能を試すために数日使ってみたが,意外に温度の変化の影響を受ける
ことが分かった。これは常温域(0〜40℃)でも±2ppmだから当たり前だの想定内事項。
それ以外に,しばらく寒い日が続き,室内暖房をつけたり切ったりで割と大きい
寒暖差となっていたが,温度変化への追従に数分程度のラグがあることが分かった。
それとAgingOffsetの値を変更して,効果が現れるのにも同程度のタイムラグがある。
なんでかと思いながら,つらつらとRTCのデータシート眺めてたら内部温度センサは
放っておいても64秒に1回,温度を基に温度レジスタ値を更新するということらしい。
AgingOffset設定後のタイムラグはこのタイミングの影響のようだ。
というかズバリAgingOffsetを変更したら,CONVビットをセットすることで即反映される
と書いてあるので,温度レジスタ更新のタイミングで反映されると見てよさそうだ。
とまぁ,温度によってAgingOffsetを調整するように手を入れれば,精度的にかなり
行けそうな期待があったが,短時間での安定性では少々当てが外れた感。
ここまでで,結論を急ぐと微調整初期時で室温なら年間誤差5秒くらいは特に何もせず
に追い込める。自動調整を視野に入れてさらに追い込むことを考えると,温度変化と
経時変化を加味しての調整の結果を採取してフィードバックする必要があるということ
になりそうだ。長期安定性を狙うなら素直にGPSか電波時計を使うべきだろうな。
→1秒未満の安定性はあまりよろしくない。観測値で20us(20ppm)程度は,平気で動く。
1年ほど使用してみたが調整次第では,年レベルの超長期では秒未満の誤差に出来る
(個体差にもよるだろうが)可能性がある。
参考までに,現在の設定状態での傾向としては,大体1日当たり約2ms〜10msの偏差レベル
で稼動している(AgingOffsetの値は0x1bに設定,内部センサ読み16〜27度程度の範囲)。
ちなみに今は亡き秋月TCXOを使って作った時計も同じ部屋で使っているが,どんなに
調整しても温度調整なしだと簡単に月2〜3秒くらいずれることを考えると,初期調整
のみの温度調整なしでこの精度が出るとは意外であった。
(いかに温度管理が発振器の周波数精度に影響するかを改めて認識させられた...というか
秋月TCXOで植えつけられたTCXOとは所詮こんなもんかという固定観念が払拭できたw)
精度の良い使いやすいRTCなので,DS3231とNVRAM付きのDS3232を通販でいくつか購入する
ことにしようと思っている。
[結論的な戯言]
作成してから,ちょうど1年経過したので,作った時計の精度に関して報告する。
GPS時計に対して,目視による時刻差異は見られない(RTCのAgingOffset=0x1b)。つまり,
2011年の1年間の室温の変化など環境の変化に対しては,この時計は,ほぼ0秒の誤差と
なった。元旦に(つーか正月になにやってんだよw)GPSとRTCのPPS同士の差をMDA(HP53310A)
で追いかけてみたが,一日の間でも約1msを越えるふらつきがある(たぶん主なふらつきは,
RTCの方だと思いたいが)にも関わらず年間通しで誤差が1秒未満...累積したら誤差が0。
こういうことも現実にあるのかと,酒を飲みながら驚いた次第。
夏に1秒ちょい遅れだったけど,ちゃんと冬になってから取り返した感じだなw
たぶん,また春先までは進み傾向になるねコレw
電波時計も止まることがあるし,電源周波数も無思慮な計画停電があるし,GPSは空が見え
ないとアレだし...つまるところローカルで最低限の精度を確保することが重要だよね。
そんで人間が使う時計の精度でクロノグラフ以上の精度って...すごく精神衛生にいいですw
まあ,AVRで時計作っちゃったんで,今更アレだけど...時計作るなら,RTCはDS323xが絶対
オススメ。電子工作時計マニアのマストアイテム(笑)である。いやホント。マジでマジで。
[ご注意]
・このページの記載事項については,一切無保証です。