Arduino-UNO 割り込み処理のミスあれこれ:計時処理
皆さんのスケッチを見ていて、どうしても一言いたくって・・・
「割り込み禁止での排他制御」、重要です。
■誤表示の可能性
タイマー割り込みで時計処理していて、読み出し時に
割り込み禁止していないので、桁上がりタイミングと
表示処理が重なると誤表示の可能性があります。
・Arduinoでタイマー割り込み:Lightning Brains
▲スケッチ
// 経過時刻表示
void loop() {
char buf[18]; // 表示バッファ
sprintf(buf, "%02d:%02d:%02d.%03d", hh, mm, ss, ms);
setCursor(2, 1);
sendText(buf, strlen(buf));
}
※時刻データ「hh, mm, ss, ms」は1msのタイマー割り込みで
カウントアップ。
▲状況
sprintfで4つの時刻データ(int値)を文字列に変換しています。
※「hh, mm, ss, ms」の読み出しはどのタイミングで
行われるか、どの順番でされるのか分かりません。
「hh, mm, ss, ms」の順だと仮定して、
「23:59:59.999」の時に「時と分」まで読み出したとすると、
文字列bufには「23:59」が入ります。
この直後にタイマー割り込みが入って1ms桁がカウントアップ
したら時刻データは「00:00:00.000」になります。
すると、「時分」に続く時刻データ「ss,ms」の読み出しは
「00.000」となってしまい、文字列bufは
「23:59:00.000」となり、ミス表示が出現します。
しかし、loop()処理だからすぐに次の表示が行われるので、
このミスには気が付きにくいでしょう。
表示が「チラ」と変化するだけですから。
▲対策
割り込み禁止状態「cli()実行」にして「hh, mm, ss, ms」を
別の変数にコピーします。
その後、「sei()」で割り込み有効状態に戻します。
そして、sprintfにはコピーした変数を食わせます。
コピーした値は割り込みが入っても変化しません。
面倒でもこうしないと、いつミスが生じるかわかりません。
表示だと実害は無いかもしれませんが、タイマー値を何かの制御
や計算に使っていたら「たまにおかしくなる」が発生します。
見つけにくいバグになってしまいます。
▲補足
これは8bitマイコンの1バイトでしか読み書きできない問題
ではなく、16bit、32bitマイコンでも発生するミスです。
▲補足2
もう一つ気になるのが、アウトプット・コンペアレジスタの
設定値です。
OCR1A = 62500;
OCR1A = 250;
のように、分周値をそのまま入れられてます。
「分周値 - 1」つまり「TOP値」でないと、1クロック余計に
カウントしてしまい、正しい周波数(周期)が得られません。
▲参考に
・『アトミック操作』・・・8bitマイコンに限り何か別の言い方なかったか?
・割り込みで処理させるwordデータの扱い
・Arduinoのタイマー OCRレジスタは「n」じゃなく「n - 1」の値を設定せよ
・Arduinoのタイマー処理
・Arduinoから「タイマー0」を取り上げる(ユーザーが使う)
※体言止めを書き直しました。
| 固定リンク
「Arduino」カテゴリの記事
- Arduino UNO R3で周波数を計る(2025.05.16)
- Arduino UNO R3のクロック精度を1MHzパルスで確かめる(2025.04.28)
- Arduino、analogWriteは捨てちゃえ。ちゃんとしたPWMの例(2025.03.22)
- パルスジェネレータをI2C液晶で動かす(2025.01.28)
- EEPROMを使ったシリアル受信バッファ 512kバイトに増設(2024.12.26)
「重箱の隅」カテゴリの記事
- 1/1023監視団 活動中!(2025.03.10)
- DIPのLMC6482えらい高くなった(2025.03.07)
- 因縁のボリューム記号 トランジスタ技術2025年3月号(2025.02.17)
- ボリューム記号のボヤキ、トラ技2025年3月号の別冊付録に再掲載(2025.02.10)
- NECは3段タイプの発振回路をすすめてる(2025.01.31)
「割り込み処理」カテゴリの記事
- 1クロックでも速くしたい 割込を「ISR_NAKED」で(2024.09.30)
- 1クロックでも速くしたい DDS方式の2相パルス発生器(2024.09.27)
- 最適化処理のせいで悩んだぞ 呪文volatile再び(2024.06.06)
- I2C液晶のアクセス、割り込みで処理しないようにすると(2024.04.12)
- I2C液晶のアクセス、割り込み処理で遅れる原因らしきもの(2024.04.07)
コメント