Arduinoのタイマー OCRレジスタは「n」じゃなく「n - 1」の値を設定せよ
ミスが広まる 1/1023 vs 1/1024は、Arduino-UNO(ATmega328pマイコン)
のA/Dコンバータ・スケーリングのお話しでしたが、今回はタイマーのコンペアマッチ
レジスタのお話しです。
Arduinoのタイマーを直接操作する時(例えばMsTimer2などのタイマー
ライブラリーを使わずにタイマー割り込みを使いたい時など)、CTCモードで
アウトプットコンペアレジスタにタイマーの最大カウント値を設定します。
※Arduinoから「タイマー0」を取り上げる(ユーザーが使う) では
「1m秒」割り込みを例にしました。
1msつまり1kHzの割り込み周期を得るには、
・CTCモードに。 (コンペアマッチでカウンタゼロクリアー)
・16MHzのクロックをプリスケーラーで1/64して250kHzに。
・それを1/250して1kHzに。
この1/250するのがアウトプットコンペアレジスタへの設定です。
↑の例では
OCR0A = 250 - 1; // 250カウントで1kHzを
の所。
1/250なんで「250 - 1」を設定しています。
これをミスして「-1していない」プログラム例や解説を見かけるのです。
なぜ「n - 1」なのかは、このタイミング図を見れば分かるかと。
TOP値がOCR:コンペアレジスタへの設定値。
そして、CTCモードだとBOTTOM値はゼロになります。
TOP値を検出した次のサイクルがゼロとなるわけです。
例えば「1/4」したい時、TOP値つまりコンペアレジスタの値を
「4」にしてしまうと・・・
「0 1 2 3 4 0 1 2 3 4 0・・・」と繰り返しが「5」になってしまいます。
TOP値としてOCRに設定するのは「カウント周期 - 1」でなければいけません。
「-1」しないと、「1/4」が欲しいのに「1/5」になってしまうという
スカタンが発生します。
これに気付かない原因の推測ですが、
・とりあえず、それらしい動きをしてるから。
・16ビットタイマーであるタイマー1に対して、大きな値をセットしてる。
そのままの値と-1した場合とで、タイマー周期にほとんど違いが出ない
から気がつかない。
・8ビットタイマーでも、ミスを測定する手段を持ってない、あるいは
積極的に結果を計ろうとしていない。
※周波数カウンタやオシロスコープなどの測定器をつなぎ
テストパルスを出せばすぐに気がつくはず。
・ハードウェアの非同期カウンタを思い浮かべている。
※1/10カウンタなら、7→8→9→[10=0]→1→2→
と、10検出で直ちにリセットされて0になるので。
こんなところかと。
※見かけたミスの例
・ArduinoのTimerを初心者が1からなんとなくわかるためのメモ - Qiita
16MHzクロックを1/256し、「OCR1A = 62500;」として「1秒」としている。
・Arduinoでtimerを使った割込み処理の方法 ? 自作のいろいろ
「OCR2A=100; //100カウントごと(50μs)毎」と。。。
・Timer1 - FreeStyleWiki
ちょっと違う。
・タイマー割り込みを使う - arduino始めました
惜しいような。。。
・Timer0 & 1
アセンブラでもミス。
多くの正しい解説もありますが、ミスしたのが目立っちゃいます。
そして、もうひとつ気になるのが割り込み処理内で走らせるプログラム。
「呼んですぐに戻ってくる関数」が基本。
そして、それがメインの処理とぶつからないこと。
他の割り込み処理に影響(長い時間待たせる)を与えてもダメ。
割り込みの中で「Serial.println(xxx)」を使ってる例を見かけるのですが、
これはいかがなものかと・・・。
| 固定リンク
「Arduino」カテゴリの記事
- Arduino UNO R3で±19.9V表示電圧計(2023.10.14)
- 「御詠歌プレーヤー」の製作 (MP3-TF-16Pモジュールの使用例)(2023.08.10)
- Arduino UNO R3のソケット・・思えば違和感がぁ(2023.07.07)
- 初めて買ったArduino UNO・・・今は(2023.05.25)
- 液晶表示コントローラ HD44780で迎撃(2023.05.16)
「割り込み処理」カテゴリの記事
- 初めて買ったArduino UNO・・・今は(2023.05.25)
- 8ビットマイコンの割り込み処理・・・1バイトに収まるなら1バイトに(2023.03.01)
- 8bitマイコンにも16bitのメモリ読み書き命令があった(2022.10.14)
- 何度も言うぞ! Arduino(8bitマイコン)の割り込みには気をつけろ!(2022.10.11)
- ロータリーエンコーダーのチャタリング波形(2022.09.11)
コメント
注目されてます。
PIC AVR 工作室 ブログ:あぁ、タイマーの設定値、-1するの忘れがちなんだ
よなぁ。
https://brown.ap.teacup.com/nekosan0/4150.html
投稿: 居酒屋ガレージ店主(JH3DBO) | 2020年2月 9日 (日) 21時57分
オーバーフロー割り込みでのお話。
http://igarage.cocolog-nifty.com/blog/2021/12/post-4a81b7.html
Arduinoで使われているATmega328P、8bitタイマーでオーバーフロー割り込みが発生するのは「255の次のクロック」。
投稿: 居酒屋ガレージ店主(JH3DBO) | 2021年12月25日 (土) 10時24分