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