最近BBSでちょっとした騒動が起きた。これは、PICを使う人に有益になると思うので、ブログでも紹介しておくとしよう。
その後、PICの事で以前からお世話になっている
natuさんより設定に違いがあるご指摘を受けることになる。
設定値はマイナス1してCCP1に設定
これが今回の焦点となった。
何度かBBSにてやり取りを行い、私も簡単ながら途中で検証も行った。MPLABにはソフトウェアシミュレータMPSIMが搭載されていて、ステップ実行やステップ時間をブレークをかけて検証ができる便利な機能がある。
まずこの機能での表示をが正しいと思い込んだのが、今回の真偽を惑わされてしまった原因になってしまった。上記は、計算値をそのままCCPレジスタにセットしてインターバルタイマーとした時のMPSIMの結果である。計算通りの割り込みで、一切の疑いも掛けていなかった。ところが、それをマイナス1すると、当然この結果が変わってくる。
チップでも試してみた。このチップは「ES」(エンジニアリングサンプル)で、知人が何か不完全な機能があるから注意してといって貰った物。そしてこのチップのDIP版があったので、会社の空いた時間にササッと確認。このES品の内蔵クロックが±5%の範囲にはいっておらず、更に現象を不確定にすることに。
とにかく、natuさんは古くからBBSなどに来る方の質問に答えて頂いたりしている御方である。
適当にアドバイスする事など考えられない。ひとつひとつ事実を知る事が大事である。
まずは、実機作成だ。といってもブレッドボードであるが、不確定要素を排除するために、高精度の水晶発信器KTXO12.8MHz(秋月の絶品)を使用。デバイスは16F877Aを使用し、PICkit2でオンラインでバッグ出来るようにする。もちろん、電源周りにも配慮し、最短距離配線とパスコンは欠かさない。1時間程度で組み上げる。
出来上がり。これにRC0出力で割り込みが入る毎にポートを反転させるようにした。
覚書:LCDを延長でつなぐとき、2,1,4,3,6,5,・・・という数え方になる。
タイマー関係のセットCCP1CON=0x0b
そして、タイマー値を計算値の0x0fa0からマイナス1した 0x0f9fをセット。
RC0出力を利用してここにオシロスコープをあてて周波数を観測。
20ms、つまり50Hz出ればOK。
まずは、MPSIMで動作させてみる。
9.991250mSEC
あと1カウント足りない。何度コンティニューしてもそうだ。
では、実際に動かしてみる。
ジャスト50Hz! 一寸の狂いも無し。 マイナス1するのが正解という証拠である。
1msも試してみた。同じ様にマイナス1。これも正しい。
ちなみに、それぞれマイナス1しなかった場合は、この周波数より高めになる。
【結論】
・CCP1を使ったコンペアーモードでタイマーを動かすときは、設定値-1とする。
・MPSIMの計測はバグである。実機で確認が必要。
・MPLABは神様ではない。過信しない。
・精度の高いデバイスで測定する事。
・そもそも、決めつけないで柔軟な発想で考える事。
私が公開したプログラムは、実際使われているが、30秒程のイベントを10ms単位で動作させる装置で使用していて、その誤差が4000/3999 ≒ 1.00025 であったので、問題が出なかったが、もし、今回この問題が明るみにならなかったら、きっとまた使う所だっただろう。
今回は、勉強させられた一件であった。
------------------------------------------------------
natuさんに助言を頂いたのにも関わらず、私の思い込みも加担して、数日間気持ちが晴れない状態を過ごされたと思います。大変失礼しました。また、
embeddedarkさんには、情報が不完全であったことをお詫びします。
コメントをどうぞ
※メールアドレスとURLの入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。
※投稿には管理者が設定した質問に答える必要があります。