DCDCコン開発(54) TMR0割込み判定のノウハウ

写真は、夕方暗くなってきて、発電がほとんど停まりかけの時の状態。暗闇に白色LEDと緑色LEDがきれい。

部品を乗せたオーダーメイドのDCDCコンバータを太陽光パネルに繋いで調整開始。表示を液晶パネルからLEDに変更したのだけど、先ずは、きちんと設計通りに状態が表示できないと、動作状況が分らない。LEDは、電源用に白色1つ、動作状況表示用に3色LEDを一つ搭載している。動作状況は、正常状態は緑色、以上状態は赤色、特殊状態は青色で表示。それぞれの状態の違いは、点滅のパタンを変えて分るようにしている。

いざ、電源ON!  LED表示が変。。。。。

一度に複数の色を点灯させるとそれだけ余計に電流が流れるので、常に1つの色しか点灯しないようにしたはずなのに、青が点灯しっぱなしだし、緑と赤が同期して点滅している。なんだこりゃ。。。。

よくよくプログラムを見直したら、負論理と正論理が逆になっていた。先のレポートで、PICの入力端子を出力に使う方法を紹介したが、それだと、正論理でOK。ところが、通常の利用法だと、LEDのアノードコモンで5V電源と接続しているので、PICの出力がHiの時はLEDが消灯、Loの時が点灯と、論理が反転している。そんなことを、ころっと忘れていた。

そそくさと、修正して、再度試験。。。まだ変。。。。。

青LEDは消灯したが、赤と緑の同期点滅はそのまま。やっかいだぞ。。。。
バグ発生の場所を追掛けると、タイマー0割込みルーチンに入っていることをつきとめた。
タイマー0(TMR0)割込みは、8ms毎に電圧チェックして、モードを変更するために利用している。
タイマー1(TMR1)割込みは、250ms毎に、LEDの点滅を切換えるために使っている。
LEDの試験なので、TMR0割込みは、停止させているはずなのに、割込みルーチンに入るとはどういう事か???

// 割込みハンドラ
void interrupt handler(void ){
      static unsigned char disp_count;                                       // LED表示タイミングカウンタ
      // モード制御タイミング(TMR0割込み)の場合
      if(TMR0IF) {                                                                 // 電圧測定タイミング(TMR0)だったら
           TMR0IF = 0;                                                            // 割込みフラグクリア
      // モードに応じたPWM制御
      ・・・・・・・・
      }
      // LED表示及びMPPTターゲット再設定(TMR1割込み)の場合
      else if(TMR1IF) {                                                          // 表示タイミング(TMR1)だったら
           TMR1IF = 0;                                                            // 割込みフラグクリア
      // LED状態表示処理
      ・・・・・・・・
      }
}

PICのCプログラムでは、割込みハンドラは1つしかない。何かの割込みが発生すると、ハンドラの中で、どの割込みが発生したかを確認しながら、場合分けで論理を記述する。割込みの種類を判定するのは、XXIFというフラグビット。タイマー0割込みならTMR0IF、タイマー1ならTMR1IFがセットされているかで判定する。

割込み停めてるのに、何でフラグがセットされるんだよぅ~~~

初心に戻ってデータシートを熟読。最近、やっとPIC16F1823のデータシートが日本語化されたので、読むのは少し楽になったのだが。

ありましたありました。「タイマは動いている間は、割込みの発生にかかわらずエクスパイアしたときにフラグビットはセットされる。フラグはソフト的にクリアしなければならない」と。

つまりは、TMR0は8ms周期でエクスパイアするので、割込みルーチンで調べても当然セットされてるって事で、割込み判定できないじゃん。思案。。。。

割込み許可フラグ(TMR0IE)というものがあって、それをセットすることで割込み発生を許可する仕組み。普通は書込むフラグだけど、そのフラグの状態を確認すれば、割込み許可されていることが分るはず。よって、以下のようにしてやれば大丈夫なはず。

      if(TMR0IE&&TMR0IF) {                                              // 電圧測定タイミング(TMR0)だったら
           TMR0IF = 0;                                                            // 割込みフラグクリア
      // モードに応じたPWM制御
      ・・・・・・・・
この修正によって、無事にLEDが設計通りに点滅するようになったとさ。

本番時には、常にTMR0割込みは許可されているので、この判定は最終的には不要かも知れないけど、試験する際には、必要なものして記述しておく。またひとつノウハウが得られた。

T.Iさん、T.Sさん、T.Yさん、他5人が「いいね!」と言っています。

コメント:

M.S:設計の真髄を楽しく拝見しています。 2013/9/21 20:23

M.S:メーカ、製品間の設定差異は昔から問題でした。S/Wを知るH/W設計者による製品開発がより進むと良いですね 2013/9/21 21:03

創結マスター:CPUは、30年ぐらい前は80系と言われたインテル系と68系と言われたモトローラ系がありましたが、その後RISC系が加わり、複雑に派生してよくわからなくなってしまいました。学生時代には当時のメジャーなZ80や、Apple2で使われていた6502で、機械語で音声入力の自作ADコンバータの制御プログラムをつくって卒論とか修論を書いてました。
最近使っている組込み系のPICは、変な制御方法と一般の人には受けが悪いですが、私的には6502の0ページ命令に慣れ親しんでいたので、すんなりと理解できました。
使う方にとっては、CPUによって制御方法が微妙に異なることは開発効率やバグ混入で苦労するところです。
80円で入手できるCPUのマニュアルが500ページ近くあるので、ものすごく多くの機能を正確に理解するのには苦労してます。 2013/9/22 17:48

<前へ>                   <次へ>

タイトルとURLをコピーしました