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