PIC18F14K50の基本動作から応用プログラムまでを学びます。

ホーム
16F18313
16F18325
16F18346
16F1619
Curiosity
---
---
    
12F1822
16F1455
16F1459
18F14K50
18F26J50
dsPIC
その他
割込

PIC18F14K50 は高/ 低 2段階の優先度を設定することができます。高優先度割り込みが発生すると、プログラムは、現在実行している処理を中断し0008hに登録されたアドレスの高優先度割込み処理プログラムを実行します。割込み処理プログラムが終了すると、先ほど中断した元のプログラムに戻ります。低優先度割り込みの場合は、0018h番地に登録されたアドレスの低優先度割込み処理プログラムを実行します。高優先度の割り込みイベントは、低優先度割り込み処理中でも割り込みを行うことができます。

各割り込みを発生させるモジュールには、割込み動作に関連する以下の3つの信号があります。

フラグビット(XXXIF):
割り込みイベントが発生した事を示します。
イネーブルビット(XXXIE):
フラグビットがセットされたときに、割り込み処理の開始を許可します。
優先度ビット(XXXIP):
割り込みの高・低優先度を選択します。

高/低 2段階の優先度割り込み機能は、IPENビットをセットすると有効になります。2段階の優先度割り込み機能を有効にした場合の信号の流れを右図に示します。

割り込みに関連するレジスター一覧を下表に示します。

レジスタ bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
RCON IPEN SBOREN RI TO PD POR BOR
INTCON GIE/GIEH PEIE/GIEL TMR0IE INTIE RABIE TMR0IF INT0IF RABIF
INTCON2 RABPU INTEDG0 INTEDG1 INTEDG2 TMR0IP RABIP
INTCON3 INT2IP INT1IP INT2IE INT1IE INT2IF INT1IF
PIR1 - ADIF RCIF TXIF SSP1IF CCP1IF TMR2IF TMR1IF
PIE1 - ADIE RCIE TXIE SSP1IE CCP1IE TMR2IE TMR1IE
IPR1 ADIP RCIP TXIP SSPIP CCP1IP TMR2IP TMR1IP
PIR2 OSCFIF C1IF C2IF EEIF BCLIF USBIF TMR3IF CCP2IF
PIE2 OSCFIE C1IE C2IE EEIE BCLIE USBIE TMR3IE CCP2IE
IPR2 OSCFIP C1IP C2IP EEIP BCLIP USBIP TMR3IP CCP2IP

割り込みのプログラム例

サンプルで作成したプログラムは、Timer1の高優先度割り込みとTimer2からの低優先度割込みにより、LEDを点滅さてしまいます。

*注意*
XC-8コンパイラーのバージョンにより割り込み関数の記載方法が異なります。このプログラムは最新のver2.20の方法です。以前のver1.x用の関数の書き方は、プログラムリスト内にコメントとして示してあります。使用する環境に合うよう書き換えてください。

<プログラム>

//  File name: interrupt
//  Description: Timer interrupt example
//  Timer1で内部クロック(4MHz)をカウントし、
//    カウントオーバー(262mS)で割込みが発生する
//    割込み処理ルーチンで、LED0を反転し点滅させる。
//  Timer2で内部クロック(4MHz)をプリスケラで1/4にして、
//    カウントし、プリセット値(250)と一致で
//    さらにポストスケラで1/10にしたのちに
//    割込みが発生する(10mS毎)
//    割込み、100回ごとにLED1を反転し点滅させる。
//  Notes: 4MHz内部クロック
//        LED RC0
//        LED RC1
//    Language: MPLABX XC8
//    Target: PIC18F14K50

#include <xc.h>

#define LED0 LATCbits.LATC0
#define LED1 LATCbits.LATC1

#pragma config FOSC = IRC        //  内部クロック
#pragma config USBDIV = OFF, CPUDIV = NOCLKDIV
#pragma config IESO  = OFF, FCMEN = OFF, PLLEN  = ON
#pragma config BORV  = 30,  BOREN = OFF, PWRTEN = OFF
#pragma config WDTPS = 32768, WDTEN = OFF
#pragma config MCLRE = OFF, HFOFST = OFF, XINST  = OFF
#pragma config BBSIZ = OFF, LVP    = OFF, STVREN = ON
#pragma config CP1  = OFF, CP0  = OFF, CPD  = OFF, CPB  = OFF
#pragma config WRT1 = OFF, WRT0 = OFF, WRTB = OFF, WRTC = OFF
#pragma config EBTR1 = OFF, EBTR0 = OFF, EBTRB  = OFF


// ----------------------------------------------
char T2Carry;    //変数の宣言と初期値の設定

//----------------------メインプログラム-------------------------
void main(void){
    OSCCON = 0b01010010;    //  内部クロック4Mhz
    ANSEL = 0;              //  Port Cをデジタル出力
    LATC = 0;
    TRISC = 0;

    T1CON  = 0b10100001;               // Timer 1 設定(262mSecごと)
                                       // 16BITRW モード PS_1/4
                                       // 内部クロックをカウント
    IPR1bits.TMR1IP = 1;    // Timer 1 からの割込みを高優先に設定
    PIR1bits.TMR1IF = 0;    // Timer 1 からの割込みフラッグをクリア
    PIE1bits.TMR1IE = 1;    // Timer 1 からの割込みを許可

    T2CON  = 0b01001101;               // Timer 2 設定
                                       // Post 1/10 Pre_1/4
    PR2 = 249;              // Timer2 のカウントが249でリセット
    IPR1bits.TMR2IP = 0;    // Timer2 からの割込みを低優先に設定
    PIR1bits.TMR2IF = 0;    // Timer2 からの割込みフラッグをクリア
    PIE1bits.TMR2IE = 1;    // Timer2 からの割込みを許可
    T2Carry = 0;

    RCONbits.IPEN=1;        // 2段階の割込みに設定
    INTCONbits.GIEH=1;      // 高優先割込みを許可
    INTCONbits.GIEL=1;      // 低優先割込みを許可
    while(1);
}


//----------------------高優先割込み------------------------
void __interrupt(high_priority) Hi_Isr(void){   // xc8 ver2.x用
//void interrupt Hi_Isr(void){                  // xc8 ver1.x用
    if(PIR1bits.TMR1IF){            //Timer1からの割込みを確認
        PIR1bits.TMR1IF = 0;        // 割込みフラッグをクリア
            LED0 = !LED0;           // LED0を反転
    }
}

//-----------------低優先割込みの処理------------------------
void __interrupt(low_priority) Lo_Isr(void){    // xc8 ver2.x用
//void interrupt low_priority Lo_Isr(void){     // xc8 ver1.x用
    if(PIR1bits.TMR2IF){            //Timer2からの割込みを確認
        PIR1bits.TMR2IF = 0;        // 割込みフラッグをクリア
        if(++T2Carry == 100){
            LED1 = !LED1;           // LED1を反転
            T2Carry = 0;
        }
    }
}