掲示板でご指摘いただく。
以前書いたarduinoのMsTimer2ライブラリの精度について。
クリスタルの周波数と分周比のことばかり考えていた
ので、そもそもの動作モードのことをすっかり意識から
除外してました。
MsTimer2ライブラリって、CTCじゃなくてノーマルモード
で動いていて、オーバーフロー割り込み時に変数の
カウントアップってカタチで処理してるので、
オーバーフロー割り込みルーチン内の処理時間が
徐々に蓄積して誤差が出る構造になっていました。
つまり
「正確にミリ秒を計測できてない」
ってことです。
というわけで、急いでwebページ上の文章を見直し
しないといけないところなんですが、その前に類似の
時間関係機能についてもうちょっと横展開調査。
まずは寄贈ライブラリの中で。metroライブラリが
機能的には類似するところアリだな、と。
これは、定期的に割り込みを発生させてくれるような
機能は無いんだけど、こまめにこまめに参照すると、
一定周期で「指定時間が経過したよ」と教えてくれる
ライブラリ。
このライブラリ内部ではmillis()関数を使って経過時間
を監視ししてます。
ライブラリ関係ではこのMsTimer2とmetroの2つくらい。
あとは標準機能としてのmillis()があるんだけど、
millis()にしてもmetroにしても、その精度はともに
millis()内部処理に因る訳です…と。
で、そこが問題。millis()は確かtimer0モジュールを
使っているはずなんですが、mega8についてはtimer0
にそもそもCTCが搭載されていないはず。
うーん。ってことは元々millis()も正確な時間を
計測できるわけじゃないってことか???
それとも、分周比から考えるとどうなんだろう?
16Mhz動作の場合、分周比は64が適用されるんだけど、
そうするとオーバーフローが発生してから次のカウント
が行われるまでに64クロック必要なはずだから、
64クロック以内にカウンタ値の塗り替えが済むなら
誤差無しになりそうだけど(プリスケーラ内のカウンタ
までクリアしませんよねぇ?…調査要)、レジスタの多い
AVRだけに、割り込み自のpush/popって結構オーバーヘッド
が大きいと思うんだよな…
もっと致命的なのは、mega8ってtimer0にCTCが無い!!!
これだと手の打ちようがないのかな?
timer0ってインプットキャプチャーあったかなぁ?
その辺も併せて本体のソースを読んでみないと
わからなそう。
ってことで、すぐには修正内容も確定できないので、
「おかしいです」ってことだけ記しておきます。
できるだけ早めに修正したいと思います。
|