PIC ことはじめ ~ 外部割り込み

Posted by
ぴろり
Posted at
2012/01/02 17:30
Trackbacks
関連記事 (0)
Post Comment
コメントできます
Category
電子工作 カテゴリ
カバーイメージ

 PIC の外部割り込みを利用して、スリープ状態から復帰するプログラムの習作。メインループで入力ポートをずっとポーリングするよりも、ボタンの入力待ちになったらマイコンをスリープし、ボタン入力をトリガに割り込みを掛ける方が、ずっと低消費電力でチップを駆動することができるので、是非とも習得しておきたいテクニックです。

この記事を Delicious に追加する   このエントリーをはてなブックマークに追加  

概要

  • PIC16F819 を用いて外部ポートによる割り込みの方法を習得する
  • 外部ポートに接続されたスイッチをポーリングする替わりに割り込みを利用する
  • 割り込みが発生するたびに出力ポートのオンオフを反転する

ソースコード その1

#include <htc.h>
 
__CONFIG (
        FOSC_INTOSCIO   // 内蔵オシレータ
      & WDTE_OFF        // WDT 無効
      & PWRTE_OFF       // PWRT 無効
      & MCLRE_OFF       // MCLR 使用しない
      & BOREN_OFF       // BOD 無効
      & LVP_OFF         // Low-Voltage Programming 使用しない
      & CPD_OFF         // Data memory code protection 無効
      & DEBUG_OFF       // In-Circuit Debugger 使用しない
      & CP_OFF          // Program Memory code protection 無効
);



// メインルーチン
void main ()
{
    // RB<7:1> をデジタル出力に設定
    // RB0/INT はデジタル入力
    TRISB = 0b00000001;

    // 割り込み許可
    OPTION_REGbits.INTEDG = 1; // RB0ポートのL→Hのエッジを検出する
    INTCONbits.INTE = 0b1;     // RB0/INT 割り込みを許可
    INTCONbits.GIE = 0b1;      // グローバル割り込み許可

    // ポート初期化、最初 LED は点灯している
    PORTB = 0b11110000;

    // メインループではなにもせずにスリープするだけ
    while (1)
    {
        SLEEP();
        NOP();                  // SLEEP から復帰すると次の1命令は実行される
    }
}

// 割り込みルーチン
static void interrupt isr (void)
{
    if (INTCONbits.INTF) {
        INTCONbits.INTF = 0;    // 割り込みフラグをクリアするのはソフトウェアの仕事
        PORTB = ~PORTB;         // ポートのオンオフを反転する
    }
}

 プログラムはタイマ割り込みの例よりも、タイマの動作に関する設定が無い分だけ簡単になっています。また、割り込みが発生した際に、割り込み処理ルーチン(isr)の中で、割り込み要因を調べて処理を行うのも同じです。
 メインループは実際には何の処理も行わず、ただ SLEEP を繰り返すだけになっています。メインループ内でボタンの押下をポーリングし続ける場合、ずっと CPU が動作し続けますが、SLEEP 中は CPU が休止状態になり、割り込みを待つだけの状態になるため、チップの消費電力が劇的に下げることができます。

ソースコード その2

#include <htc.h>
 
__CONFIG (
        FOSC_INTOSCIO   // 内蔵オシレータ
      & WDTE_OFF        // WDT 無効
      & PWRTE_OFF       // PWRT 無効
      & MCLRE_OFF       // MCLR 使用しない
      & BOREN_OFF       // BOD 無効
      & LVP_OFF         // Low-Voltage Programming 使用しない
      & CPD_OFF         // Data memory code protection 無効
      & DEBUG_OFF       // In-Circuit Debugger 使用しない
      & CP_OFF          // Program Memory code protection 無効
);



// メインルーチン
void main ()
{
    // RB<7:1> をデジタル出力に設定
    // RB0/INT はデジタル入力
    TRISB = 0b00000001;

    // 割り込み許可
    OPTION_REGbits.INTEDG = 1; // RB0ポートのL→Hのエッジを検出する
    INTCONbits.INTE = 0b1;     // RB0/INT 割り込みを許可

    // ポート初期化、最初 LED は点灯している
    PORTB = 0b11110000;

    // メインループではスリープして割り込みを待つ
    while (1)
    {
        SLEEP();
        NOP();                  // SLEEP から復帰すると次の1命令は実行される
        INTCONbits.INTF = 0;    // 割り込みフラグをクリアするのはソフトウェアの仕事
        PORTB = ~PORTB;         // ポートのオンオフを反転する
    }
}

 ソースコード その2は、非常に簡潔になりましたが動作は先と同じです。注目すべきは、INTCONbits.GIE ビットを立てていないため、外部割込みが発生した際に、SLEEP から復帰した後、割り込み関数に飛ばずに、そのまま処理が継続されるという点です。すなわち、SLEEP は、実質、外部からの割り込みをポーリングしていると見なしてプログラムを書くことができるようになります。

この記事を Delicious に追加する   このエントリーをはてなブックマークに追加  


この記事を読んだ人はこんな記事も読んでいます記事リコメンデーションについて

カバー画像:PIC ことはじめ ~ タイマ割り込み

関連記事/トラックバック

関連記事/トラックバックはまだありません

この記事にトラックバックを送るには?

コメントを投稿する

 
 (必須, 匿名可, 公開, トリップが使えます)
 (必須, 匿名可, 非公開, Gravatar に対応しています)
 (必須)
スパム コメント防止のため「投稿確認」欄に ランダムな数字 CAPTCHAについて を入力してから送信してください。お手数ですがご協力のほど宜しくお願いいたします。