PIC32で状態変化割り込みによるLチカ

Change notice interrupt on PIC32MX
 
前回のタイマープログラムでPIC32マイコンの割り込み処理の基本を学んでいれば、ほかの種類の割り込みをプログラミングするのも難しくありません。今回はピンの状態が変化したときに割り込み処理が発生するプログラムを作ってみましょう。

状態変化検出モジュールによる割り込み関数を実行するには、以下の設定をすべて有効にします。


PIC32MX1XX/2XXの場合、ポートB状態変化検出モジュールのベクタ番号は34番(_CHANGE_NOTICE_VECTOR)となります。また、割り込み優先度は「IPC8bits」の「CNIP」および「CNIS」で定義します。

タクトスイッチに連動してLEDが点灯するサンプルプログラムを記述します。
マイコン内部には抵抗が組み込まれているので、「CNPUxbits.CNPUxn」で対象ピンのプルアップ抵抗を有効にすると、スイッチ回路に外部抵抗を継ぎ足すことなく、安定した情報を取得できます。
main.c
#include <p32xxxx.h>
#include <sys/attribs.h>

// 外部の8MHz水晶発振器から40MHzのクロックを生成するための設定
#pragma config FNOSC = PRIPLL // 発信源 = 主外部発振器
#pragma config POSCMOD = XT // 主発振の方法 = 外部高精度発振器を使う
#pragma config FPLLIDIV = DIV_2 // PLL入力分数 = x1/2
#pragma config FPLLMUL = MUL_20 // PLL逓倍比 = x20
#pragma config FPLLODIV = DIV_2 // PLL出力分数 = x1/2
#pragma config FPBDIV = DIV_1 //周辺モジュールクロック倍数 : x1/1

// 割り込みレベル4、34番(ポートB入力変化)ベクタ
void __ISR(_CHANGE_NOTICE_VECTOR, IPL4AUTO) OnPortChanged(void) 
{
    LATBbits.LATB0 = ~PORTBbits.RB1;
}

int main(void)
{
    ANSELB = 0x00;        // ポートBをすべてデジタルモードにする
    TRISBbits.TRISB0 = 0; // B0を出力にする
    PORTBbits.RB0 = 0;    // B0 = off
    
    TRISBbits.TRISB1 = 1; // B1を入力にする
    PORTBbits.RB1 = 1;    // B1の初期状態を設定
    
    INTCONbits.MVEC = 1;  // マルチベクタ割り込みを有効にする

    CNCONBbits.ON = 1;    // ポートBの状態変化検出モジュールを使用
    CNENBbits.CNIEB1 = 1; // B1の検出を有効
    CNPUBbits.CNPUB1 = 1; // B1のプルアップ抵抗を使用
    
    IPC8bits.CNIP = 4;    // 割り込み優先度(0-7)
    IPC8bits.CNIS = 3;    // 副優先度(0-3)
    IFS1bits.CNBIF = 0;   // 割り込みフラグをリセット
    IEC1bits.CNBIE = 1;   // 状態変化Bの割り込みを許可
       
    __builtin_enable_interrupts();  // マイコンにおける割り込みの有効

    while(1) ;
}
2018/09/25