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

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

PIC18F26J50 は高/ 低 2段階の優先度を設定することができます。高優先度割り込みが発生すると、プログラムは、現在実行している処理を中断し0008hに登録されたアドレスの高優先度割込み処理プログラムを実行します。割込み処理プログラムが終了すると、先ほど中断した元のプログラムに戻ります。低優先度割り込みの場合は、0018h番地に登録されたアドレスの低優先度割込み処理プログラムを実行します。高優先度の割り込みイベントは、低優先度割り込み処理中でも割り込みを行うことができます。
各割り込みを発生させるモジュールには、割込み動作に関連する以下の3つの信号があります。

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

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

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

レジスタ bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
RCON IPEN CM RI TO PD POR BOR
INTCON GIEH GIEL TMR0IE INT0IE RBIE TMR0IF INT0IF RBIF
INTCON2 RBPU INTEDG0 INTEDG1 INTEDG2 INTEDG3 TMR0IP INT3IP RBIP
INTCON3 INT2IP INT1IP INT3IE INT2IE INT1IE INT3IF INT2IF INT1IF
PIR1 ADIF RC1IF TX1IF SSP1IF CCP1IF TMR2IF TMR1IF
PIE1 ADIE RC1IE TX1IE SSP1IE CCP1IE TMR2IE TMR1IE
IPR1 ADIP RC1IP TX1IP SSPIP CCP1IP TMR2IP TMR1IP
PIR2 OSCFIF CM2IF CM1IF USBIF BCL1IF HLVDIF TMR3IF CCP2IF
PIE2 OSCFIE CM2IE CM1IE USBIE BCL1IE HLVDIE TMR3IE CCP2IE
IPR2 OSCFIP CM2IP CM1IP USBIP BCL1IP HLVDIP TMR3IP CCP2IP
PIR3 SSP2IF BCL2IF RC2IF TX2IF TMR4IF CTMUIF TMR3GIF RTCCIF
PIE3 SSP2IE BCL2IE RC2IE TX2IE TMR4IE CTMUIE TMR3GIE RTCCIE
IPR3 SSP2IP BCL2IP RC2IP TX2IP TMR4IP CTMUIP TMR3GIP RTCCIP

割り込みのプログラム例

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

<プログラム>

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

#include <xc.h>

#define   LED0   LATBbits.LATB0
#define   LED1   LATBbits.LATB1
//
     #pragma config WDTEN = OFF, PLLDIV = 2, STVREN = ON, XINST = OFF
     #pragma config CPUDIV = OSC1, CP0 = OFF
     #pragma config OSC = INTOSC, T1DIG = OFF
     #pragma config LPT1OSC = OFF, FCMEN = OFF, IESO = OFF
     #pragma config WDTPS = 32768
     #pragma config DSWDTOSC = INTOSCREF, RTCOSC = T1OSCREF
     #pragma config DSBOREN = OFF, DSWDTEN = OFF, DSWDTPS = 8192
     #pragma config IOL1WAY = OFF, MSSP7B_EN = MSK7
     #pragma config WPFP = PAGE_1, WPEND = PAGE_0, WPCFG = OFF
     #pragma config WPDIS = OFF

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

//----------------------メインプログラム-------------------------
void main(void){
    OSCCON = 0b01100010;       // 内部クロック4Mhz
    LATB = 0;                  // PortCのすべてのビットを「0」
    TRISB = 0b11110000;        // LEDの接続されているポートを出力に設定
    ANCON0 = 0xFF;             // すべてのピンをデジタルにする
    ANCON1 = 0xFF;             // すべてのピンをデジタルにする

    T1CON = 0b00100011;     	// Timer 1 設定(262mSecごと)
                            	// FOSC/4 PS_1/4 OSC1_OFF SYNC_ON 6BIT_RW
    T1GCON = 0;                 // ゲート機能を無効
    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 Hi_Isr(void){
    if(PIR1bits.TMR1IF){            //Timer1からの割込みを確認
        PIR1bits.TMR1IF = 0;        // 割込みフラッグをクリア
            LED0 = !LED0;           // LED0を反転
    }
}
//-----------------低優先割込みの処理------------------------
void interrupt low_priority Lo_Isr(void){
    if(PIR1bits.TMR2IF){            //Timer2からの割込みを確認
        PIR1bits.TMR2IF = 0;        // 割込みフラッグをクリア
        if(++T2Carry == 100){
            LED1 = !LED1;           // LED1を反転
            T2Carry = 0;
        }
    }
}