「PIC AVR 工作室」サイトの日記的なブログです。
サイトに挙げなかった他愛ないことを日記的に書き残してます。
PIC AVR 工作室 ブログ



まじめにコードを追ってみる事に。arduinoの
MsTimer2の件。

まずはarduinoコアの元々のタイマー関係処理について
どうなっているのかを整理。コードを追ってみた結果
はこんな感じです。


[TIMER0関係の処理]

・初期化処理にて、高速PWMに設定(ここ注意)
・オーバーフロー割り込み処理は1024us(16Mhz時)もしくは
 2048us(8Mhz時)ごとに1回発生に設定
・オーバーフロー割り込みをオン
とした上で、

16MHZの場合
・割り込み発生ごとに「ミリ秒」を1カウントアップ…(a)
・併せて、24usの誤差を蓄積
・誤差がミリ秒単位に達している場合、(a)に加えて
 1カウントアップ

 →1ミリ秒より少し長い時間ごとに「ミリ秒」がカウント
  アップされていくが、蓄積誤差が1ミリ秒に達した時
  にはいっぺんに2ミリ秒カウントされる
  (およそ41~42回のオーバーフロー割り込みごとに
   2ミリ秒カウントされるケースが発生する)

8MHZの場合
・オーバーフロー割り込み処理自体は2048usごとに1回発生
・割り込み発生ごとに「ミリ秒」を2カウントアップ…(b)
・併せて48usの誤差を蓄積
・誤差がミリ秒単位に達している場合、(b)に加えて
 1カウントアップ

 →2ミリ秒より少し長い時間ごとに「ミリ秒」がカウント
  アップされていくが、蓄積誤差が1ミリ秒に達したとき
  はいっぺんに3ミリ秒カウントされる
  (およそ20~21回のオーバーフロー割り込み毎に3ミリ秒
   カウントされるケースが発生する)

16MHZ、8MHZどちらも、長時間に渡って誤差は1クロック
単位で累積しないまた、PWM(アナログ出力)とタイマー
割り込みが両立する様に設定されている


[TIMER1関係の処理]

・位相補償PWMを使用(ここ注意)
・割り込みは使用しない
・プリスケーラ値64でフリーラン
・入出力ピンはノーマル動作状態(PWMの出力が未接続)

(注)TCCRxAの値はイニシャル値=0のため、初期化の
   直後は入出力ピンにはPWMの出力が取り出されて
   おらず、普通のデジタルI/Oになっている


ということで、タイマー0についてはアナログ出力用の
設定を行いつつミリ秒ごとに経過時間を計測している
けど、瞬間的には最大で1ミリ秒(8Mhz機の場合2ミリ秒)
ほどの誤差が生じている可能性がある…ということに
なります。ただ、誤差は蓄積していかず、こまめに補正
されています。

仮にタイマー0のミリ秒計測…millis() 関数…を使って
時計を作るとしたら、理論上は1ミリ秒の誤差が瞬間的
に生じるけど、蓄積誤差は水晶発振の1クロック単位で
ゼロということになります。

なお、タイマー2も初期化時にPWM(アナログ出力)の設定を
行いつつ、I/Oは通常のデジタルI/Oのままとなっています。


さてこれらを踏まえ、MsTimer2ライブラリを取り込むと
どういうことになるのか…

[MsTimer2の処理]

・プリスケーラは16Mhz時8Mhz時とも64に設定(変化無し)
・位相補償PWMに設定(変化無し)

としてから、MsTimer2::start() にて

・オーバーフロー割り込みを許可
・割り込の都度TCNT2をプログラム上でクリア(※要注意)
・指定したミリ秒経ったか判断して、経過していれば
 指定の関数を呼び出し

という感じです。オーバーフロー割り込みが発生してから
TCNT2のクリア処理を行うまでに64クロック以上経過
している場合、やはり遅延を生じることとなり、この
遅延は時間経過にしたがって蓄積していきます。

(長くなってきたので次の記事に続きます)

(追記:MsTimer2は位相補償PWMじゃなくて、ノーマル
 タイマーですね…訂正してお詫びします)



コメント ( 0 )