割り込みの制御には、以下のレジスタが関与します。
この内SRとCORCONは、SRのIPL<2:0>とCORCONのIPL<3>のビットを連結させて、CPU割り込み優先順位を決定します。
区分 | SFR名 | アドレス | Bit 15 | Bit 14 | Bit 13 | Bit 12 | Bit 11 | Bit 10 | Bit 9 | Bit 8 | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | リセット後の値 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
INTCONx (制御) |
INTCON1 | 0080 | NSTDIS | - | - | - | - | OVATE | OVBTE | COVTE | - | - | - | MATHERR | ADDRERR | STKERR | OSCFAIL | - | 0000 0000 0000 0000 |
INTCON2 | 0082 | ALTIVT | DISI | - | - | - | - | - | - | - | - | - | INT4EP | INT3EP | INT2EP | INT1EP | INT0EP | 0000 0000 0000 0000 | |
IFSx (割り込みフラグ) |
IFS0 | 0084 | CNIF | MI2CIF | SI2CIF | NVMIF | ADIF | U1TXIF | U1RXIF | SPI1IF | T3IF | T2IF | OC2IF | IC2IF | T1IF | OC1IF | IC1IF | INT0 | 0000 0000 0000 0000 |
IFS1 | 0086 | IC6IF | IC5IF | IC4IF | IC3IF | C1IF | SPI2IF | U2TXIF | U2RXIF | INT2IF | T5IF | T4IF | OC4IF | OC3IF | IC8IF | IC7IF | INT1IF | 0000 0000 0000 0000 | |
IFS2 | 0088 | - | - | - | FLTBIF | FLTAIF | LVDIF | DCIIF | QEIIF | PWMIF | C2IF | INT4IF | INT3IF | OC8IF | OC7IF | OC6IF | OC5IF | 0000 0000 0000 0000 | |
IECx (割り込み有効/無効) |
IEC0 | 008C | CNIE | MI2CIE | SI2CIE | NVMIE | ADIE | U1TXIE | U1RXIE | SPI1IE | T3IE | T2IE | OC2IE | IC2IE | T1IE | OC1IE | IC1IE | INT0IE | 0000 0000 0000 0000 |
IEC1 | 008E | IC6IE | IC5IE | IC4IE | IC3IE | C1IE | SPI2IE | U2TXIE | U2RXIE | INT2IE | T5IE | T4IE | OC4IE | OC3IE | IC8IE | IC7IE | INT1IE | 0000 0000 0000 0000 | |
IEC2 | 0090 | - | - | - | FLTBIE | FLTAIE | LVDIE | DCIIE | QEIIE | PWMIE | C2IE | INT4IE | INT3IE | OC8IE | OC7IE | OC6IE | OC5IE | 0000 0000 0000 0000 | |
IPCx (割り込み優先順位) |
IPC0 | 0094 | - | T1IP<2:0> | - | OC1IP<2:0> | - | IC1IP<2:0> | - | INT0IP<2:0> | 0100 0100 0100 0100 | ||||||||
IPC1 | 0096 | - | T31P<2:0> | - | T2IP<2:0> | - | OC2IP<2:0> | - | IC2IP<2:0> | 0100 0100 0100 0100 | |||||||||
IPC2 | 0098 | - | ADIP<2:0> | - | U1TXIP<2:0> | - | U1RXIP<2:0> | - | SPI1IP<2:0> | 0100 0100 0100 0100 | |||||||||
IPC3 | 009A | - | CNIP<2:0> | - | MI2CIP<2:0> | - | SI2CIP<2:0> | - | NVMIP<2:0> | 0100 0100 0100 0100 | |||||||||
IPC4 | 009C | - | OC3IP<2:0> | - | IC8IP<2:0> | - | IC7IP<2:0> | - | INT1IP<2:0> | 0100 0100 0100 0100 | |||||||||
IPC5 | 009E | - | INT2IP<2:0> | - | T5IP<2:0> | - | T4IP<2:0> | - | OC4IP<2:0> | 0100 0100 0100 0100 | |||||||||
IPC6 | 00A0 | - | C1IP<2:0> | - | SPI2IP<2:0> | - | U2TXIP<2:0> | - | U2RXIP<2:0> | 0100 0100 0100 0100 | |||||||||
IPC7 | 00A2 | - | IC6IP<2:0> | - | IC5IP<2:0> | - | IC4IP<2:0> | - | IC3IP<2:0> | 0100 0100 0100 0100 | |||||||||
IPC8 | 00A4 | - | OC8IP<2:0> | - | OC7IP<2:0> | - | OC6IP<2:0> | - | OC5IP<2:0> | 0100 0100 0100 0100 | |||||||||
IPC9 | 00A6 | - | PWMIP<2:0> | - | C2IP<2:0> | - | INT41IP<2:0> | - | INT3IP<2:0> | 0100 0100 0100 0100 | |||||||||
IPC10 | 00A8 | - | FLTAIP<2:0> | - | LVDIP<2:0> | - | DCIIP<2:0> | - | QEIIP<2:0> | 0100 0100 0100 0100 | |||||||||
IPC11 | 00AA | - | - | - | - | - | - | - | - | - | - | - | - | - | FLTBIP<2:0> | 0000 0000 0000 0100 |
デバイスのヘッダでは次のようにマクロが定義されています。このためこれらのレジスタのビットは、その名称の前にアンダーバー (_) を付けることで参照できます。
/* INTCON1 */ #define _OSCFAIL INTCON1bits.OSCFAIL #define _STKERR INTCON1bits.STKERR #define _ADDRERR INTCON1bits.ADDRERR #define _MATHERR INTCON1bits.MATHERR #define _COVTE INTCON1bits.COVTE #define _OVBTE INTCON1bits.OVBTE #define _OVATE INTCON1bits.OVATE #define _NSTDIS INTCON1bits.NSTDIS /* INTCON2 */ #define _INT0EP INTCON2bits.INT0EP #define _INT1EP INTCON2bits.INT1EP #define _INT2EP INTCON2bits.INT2EP #define _DISI INTCON2bits.DISI #define _ALTIVT INTCON2bits.ALTIVT /* IFS0 */ #define _INT0IF IFS0bits.INT0IF #define _IC1IF IFS0bits.IC1IF #define _OC1IF IFS0bits.OC1IF #define _T1IF IFS0bits.T1IF #define _IC2IF IFS0bits.IC2IF #define _OC2IF IFS0bits.OC2IF #define _T2IF IFS0bits.T2IF #define _T3IF IFS0bits.T3IF #define _SPI1IF IFS0bits.SPI1IF #define _U1RXIF IFS0bits.U1RXIF #define _U1TXIF IFS0bits.U1TXIF #define _ADIF IFS0bits.ADIF #define _NVMIF IFS0bits.NVMIF #define _SI2CIF IFS0bits.SI2CIF #define _MI2CIF IFS0bits.MI2CIF #define _CNIF IFS0bits.CNIF /* IFS1 */ #define _INT1IF IFS1bits.INT1IF #define _IC7IF IFS1bits.IC7IF #define _IC8IF IFS1bits.IC8IF #define _T4IF IFS1bits.T4IF #define _T5IF IFS1bits.T5IF #define _INT2IF IFS1bits.INT2IF #define _C1IF IFS1bits.C1IF /* IFS2 */ #define _PWMIF IFS2bits.PWMIF #define _QEIIF IFS2bits.QEIIF #define _FLTAIF IFS2bits.FLTAIF /* IEC0 */ #define _INT0IE IEC0bits.INT0IE #define _IC1IE IEC0bits.IC1IE #define _OC1IE IEC0bits.OC1IE #define _T1IE IEC0bits.T1IE #define _IC2IE IEC0bits.IC2IE #define _OC2IE IEC0bits.OC2IE #define _T2IE IEC0bits.T2IE #define _T3IE IEC0bits.T3IE #define _SPI1IE IEC0bits.SPI1IE #define _U1RXIE IEC0bits.U1RXIE #define _U1TXIE IEC0bits.U1TXIE #define _ADIE IEC0bits.ADIE #define _NVMIE IEC0bits.NVMIE #define _SI2CIE IEC0bits.SI2CIE #define _MI2CIE IEC0bits.MI2CIE #define _CNIE IEC0bits.CNIE /* IEC1 */ #define _INT1IE IEC1bits.INT1IE #define _IC7IE IEC1bits.IC7IE #define _IC8IE IEC1bits.IC8IE #define _T4IE IEC1bits.T4IE #define _T5IE IEC1bits.T5IE #define _INT2IE IEC1bits.INT2IE #define _C1IE IEC1bits.C1IE /* IEC2 */ #define _PWMIE IEC2bits.PWMIE #define _QEIIE IEC2bits.QEIIE #define _FLTAIE IEC2bits.FLTAIE /* IPC0 */ #define _INT0IP IPC0bits.INT0IP #define _IC1IP IPC0bits.IC1IP #define _OC1IP IPC0bits.OC1IP #define _T1IP IPC0bits.T1IP #define _INT0IP0 IPC0bits.INT0IP0 #define _INT0IP1 IPC0bits.INT0IP1 #define _INT0IP2 IPC0bits.INT0IP2 #define _IC1IP0 IPC0bits.IC1IP0 #define _IC1IP1 IPC0bits.IC1IP1 #define _IC1IP2 IPC0bits.IC1IP2 #define _OC1IP0 IPC0bits.OC1IP0 #define _OC1IP1 IPC0bits.OC1IP1 #define _OC1IP2 IPC0bits.OC1IP2 #define _T1IP0 IPC0bits.T1IP0 #define _T1IP1 IPC0bits.T1IP1 #define _T1IP2 IPC0bits.T1IP2 /* IPC1 */ #define _IC2IP IPC1bits.IC2IP #define _OC2IP IPC1bits.OC2IP #define _T2IP IPC1bits.T2IP #define _T3IP IPC1bits.T3IP #define _IC2IP0 IPC1bits.IC2IP0 #define _IC2IP1 IPC1bits.IC2IP1 #define _IC2IP2 IPC1bits.IC2IP2 #define _OC2IP0 IPC1bits.OC2IP0 #define _OC2IP1 IPC1bits.OC2IP1 #define _OC2IP2 IPC1bits.OC2IP2 #define _T2IP0 IPC1bits.T2IP0 #define _T2IP1 IPC1bits.T2IP1 #define _T2IP2 IPC1bits.T2IP2 #define _T3IP0 IPC1bits.T3IP0 #define _T3IP1 IPC1bits.T3IP1 #define _T3IP2 IPC1bits.T3IP2 /* IPC2 */ #define _SPI1IP IPC2bits.SPI1IP #define _U1RXIP IPC2bits.U1RXIP #define _U1TXIP IPC2bits.U1TXIP #define _ADIP IPC2bits.ADIP #define _SPI1IP0 IPC2bits.SPI1IP0 #define _SPI1IP1 IPC2bits.SPI1IP1 #define _SPI1IP2 IPC2bits.SPI1IP2 #define _U1RXIP0 IPC2bits.U1RXIP0 #define _U1RXIP1 IPC2bits.U1RXIP1 #define _U1RXIP2 IPC2bits.U1RXIP2 #define _U1TXIP0 IPC2bits.U1TXIP0 #define _U1TXIP1 IPC2bits.U1TXIP1 #define _U1TXIP2 IPC2bits.U1TXIP2 #define _ADIP0 IPC2bits.ADIP0 #define _ADIP1 IPC2bits.ADIP1 #define _ADIP2 IPC2bits.ADIP2 /* IPC3 */ #define _NVMIP IPC3bits.NVMIP #define _SI2CIP IPC3bits.SI2CIP #define _MI2CIP IPC3bits.MI2CIP #define _CNIP IPC3bits.CNIP #define _NVMIP0 IPC3bits.NVMIP0 #define _NVMIP1 IPC3bits.NVMIP1 #define _NVMIP2 IPC3bits.NVMIP2 #define _SI2CIP0 IPC3bits.SI2CIP0 #define _SI2CIP1 IPC3bits.SI2CIP1 #define _SI2CIP2 IPC3bits.SI2CIP2 #define _MI2CIP0 IPC3bits.MI2CIP0 #define _MI2CIP1 IPC3bits.MI2CIP1 #define _MI2CIP2 IPC3bits.MI2CIP2 #define _CNIP0 IPC3bits.CNIP0 #define _CNIP1 IPC3bits.CNIP1 #define _CNIP2 IPC3bits.CNIP2 /* IPC4 */ #define _INT1IP IPC4bits.INT1IP #define _IC7IP IPC4bits.IC7IP #define _IC8IP IPC4bits.IC8IP #define _INT1IP0 IPC4bits.INT1IP0 #define _INT1IP1 IPC4bits.INT1IP1 #define _INT1IP2 IPC4bits.INT1IP2 #define _IC7IP0 IPC4bits.IC7IP0 #define _IC7IP1 IPC4bits.IC7IP1 #define _IC7IP2 IPC4bits.IC7IP2 #define _IC8IP0 IPC4bits.IC8IP0 #define _IC8IP1 IPC4bits.IC8IP1 #define _IC8IP2 IPC4bits.IC8IP2 /* IPC5 */ #define _T4IP IPC5bits.T4IP #define _T5IP IPC5bits.T5IP #define _INT2IP IPC5bits.INT2IP #define _T4IP0 IPC5bits.T4IP0 #define _T4IP1 IPC5bits.T4IP1 #define _T4IP2 IPC5bits.T4IP2 #define _T5IP0 IPC5bits.T5IP0 #define _T5IP1 IPC5bits.T5IP1 #define _T5IP2 IPC5bits.T5IP2 #define _INT2IP0 IPC5bits.INT2IP0 #define _INT2IP1 IPC5bits.INT2IP1 #define _INT2IP2 IPC5bits.INT2IP2 /* IPC6 */ #define _C1IP IPC6bits.C1IP #define _C1IP0 IPC6bits.C1IP0 #define _C1IP1 IPC6bits.C1IP1 #define _C1IP2 IPC6bits.C1IP2 /* IPC9 */ #define _PWMIP IPC9bits.PWMIP #define _PWMIP0 IPC9bits.PWMIP0 #define _PWMIP1 IPC9bits.PWMIP1 #define _PWMIP2 IPC9bits.PWMIP2 /* IPC10 */ #define _QEIIP IPC10bits.QEIIP #define _FLTAIP IPC10bits.FLTAIP #define _QEIIP0 IPC10bits.QEIIP0 #define _QEIIP1 IPC10bits.QEIIP1 #define _QEIIP2 IPC10bits.QEIIP2 #define _FLTAIP0 IPC10bits.FLTAIP0 #define _FLTAIP1 IPC10bits.FLTAIP1 #define _FLTAIP2 IPC10bits.FLTAIP2/MPLAB C30/support/dsPIC30F/h/p30F4012.h
割り込み発生時にそれを処理するのは、割り込み属性でタグ付けされた、引数および戻り値を持たない関数です。
たとえばタイマ1割り込みを処理するISRは、
void __attribute__((interrupt)) _T1Interrupt( void );
のように宣言します。または、
#define _ISR __attribute__((interrupt)) #define _ISRFAST __attribute__((interrupt, shadow))
のようなマクロが定義されているので、
void _ISR _T1Interrupt( void );
のようにも記述できます。このとき_T1Interrupt
はIVTのPrimary名であり、おのおのの割り込みに使用する関数名は、そこで定義されています。
__attribute__( ( interrupt [, shadow // 高速コンテキスト保存を行う | auto_psv // PSV領域に変数を配置する (既定) | no_auto_psv // PSV領域に変数を配置しない ( [ save( symbol-list ) ] // 割り込み処理内で保存、回復する変数のリスト [, irq( irqid ) ] // 割り込みベクタの指定 [, altirq( altirqid ) ] // 代替割り込みベクタの指定 [, preprologue( asm ) ] // コンパイラが生成する関数の直前に挿入するアセンブリコード ) ] ) )※[ ]で囲まれた項目は省略可能です。また
interrupt
と__interrupt__
は同等です。
MPLAB C30 v3.0以降では、変数の配置場所にPSV領域を使用するかどうかを指定する必要があります。これを明示しないと、
warning: PSV model not specified for '_T1Interrupt'; assuming 'auto_psv' this may affect latency
のように警告が表示され、auto_psvが指定されたものとして処理されます。この警告を抑制するには、
void __attribute__((interrupt, auto_psv)) _T1Interrupt( void );
のようにPSVについて明示します。
const変数への 割り込みハンドラ内からのアクセス |
割り込みの呼び出し | |
---|---|---|
auto_psv | 可能 | 遅い |
no_auto_psv | 不可能 | 早い |
ISRは関数から抜けるときに、通常のRETURN命令ではなくRETFIE (割り込みからの戻り命令) を使用します。このため割り込み以外から呼び出されると、関数を抜けるときにステータスレジスタなどを破壊します。≫dsPIC30F/dsPIC33F Instruction Set
ISRから他の関数を呼び出すと、すべてのワーキングレジスタとリピートループカウンタの保存と復帰が行われます。これにより処理が遅延しますので、ISRから他の関数を呼び出すべきではありません。
割り込み発生時に、割り込みフラグが1にセットされます。これは自動でクリアされないため、割り込みサービスルーチン (ISR) を抜ける前に明示的にクリアする必要があります。さもなくばISRを抜けた直後に再び割り込みが発生し、ループすることになります。
割り込みベクタテーブルには2種類あります。
通常はIVTのプライマリ名を使用し、デバッグなどで一括して割り込み処理を変更する場合などにAIVTの代替名を使用します。いずれが使用されるかは、ALTIVT制御レジスタ (INTCON2<15>) により決定されます。
IRQ# | プライマリ名 (IVT) |
代替名 (AIVT) |
ベクタ関数 |
---|---|---|---|
なし | _ReservedTrap0 | _AltReservedTrap0 | 予約 Reserved |
なし | _OscillatorFail | _AltOscillatorFail | Oscillator異常 トラップ Oscillator fail trap |
なし | _AddressError | _AltAddressError | アドレスエラー トラップ Address error trap |
なし | _StackError | _AltStackError | スタックエラー トラップ Stack error trap |
なし | _MathError | _AltMathError | 算術エラー トラップ Math error trap |
なし | _ReservedTrap5 | _AltReservedTrap5 | 予約 Reserved |
なし | _ReservedTrap6 | _AltReservedTrap6 | 予約 Reserved |
なし | _ReservedTrap7 | _AltReservedTrap7 | 予約 Reserved |
0 | _INT0Interrupt | _AltINT0Interrupt | INT0 外部割り込み0 INT0 External interrupt 0 |
1 | _IC1Interrupt | _AltIC1Interrupt | IC1 入力キャプチャ1 IC1 Input capture 1 |
2 | _OC1Interrupt | _AltOC1Interrupt | OC1 出力比較1 OC1 Output compare 1 |
3 | _T1Interrupt | _AltT1Interrupt | TMR1 タイマ1 期限切れ TMR1 Timer 1 expired |
4 | _IC2Interrupt | _AltIC2Interrupt | IC2 入力キャプチャ2 IC2 Input capture 2 |
5 | _OC2Interrupt | _AltOC2Interrupt | OC2 出力比較2 OC2 Output compare 2 |
6 | _T2Interrupt | _AltT2Interrupt | TMR2 タイマ2 期限切れ TMR2 Timer 2 expired |
7 | _T3Interrupt | _AltT3Interrupt | TMR3 タイマ3 期限切れ TMR3 Timer 3 expired |
8 | _SPI1Interrupt | _AltSPI1Interrupt | SPI1 SPI1 Serial peripheral interface 1 |
9 | _U1RXInterrupt | _AltU1RXInterrupt | UART1 受信 UART1RX Uart 1 Receiver |
10 | _U1TXInterrupt | _AltU1TXInterrupt | UART1 送信 UART1TX Uart 1 Transmitter |
11 | _ADCInterrupt | _AltADCInterrupt | ADC 変換完了 ADC convert completed |
12 | _NVMInterrupt | _AltNVMInterrupt | NMM NVM 書き込み完了 NMM NVM write completed |
13 | _SI2CInterrupt | _AltSI2CInterrupt | スレーブ I²C Slave I2C interrupt |
14 | _MI2CInterrupt | _AltMI2CInterrupt | マスター I²C Master I2C interrupt |
15 | _CNInterrupt | _AltCNInterrupt | CN 入力変化 CN Input change interrupt |
16 | _INT1Interrupt | _AltINT1Interrupt | INT1 外部割り込み0 INT1 External interrupt 0 |
17 | _IC7Interrupt | _AltIC7Interrupt | IC7 入力キャプチャ7 IC7 Input capture 7 |
18 | _IC8Interrupt | _AltIC8Interrupt | IC8 入力キャプチャ8 IC8 Input capture 8 |
19 | _OC3Interrupt | _AltOC3Interrupt | OC3 出力比較3 OC3 Output compare 3 |
20 | _OC4Interrupt | _AltOC4Interrupt | OC4 出力比較4 OC4 Output compare 4 |
21 | _T4Interrupt | _AltT4Interrupt | TMR4 タイマ4 期限切れ TMR4 Timer 4 expired |
22 | _T5Interrupt | _AltT5Interrupt | TMR5 タイマ5 期限切れ TMR5 Timer 5 expired |
23 | _INT2Interrupt | _AltINT2Interrupt | INT2 外部割り込み2 INT2 External interrupt 2 |
24 | _U2RXInterrupt | _AltU2RXInterrupt | UART2 受信 UART2RX Uart 2 Receiver |
25 | _U2TXInterrupt | _AltU2TXInterrupt | UART2 送信 UART2TX Uart 2 Transmitter |
26 | _SPI2Interrupt | _AltSPI2Interrupt | SPI2 SPI2 Serial Peripheral Interface 2 |
27 | _C1Interrupt | _AltC1Interrupt | CAN1 複合IRQ CAN1 combined IRQ |
28 | _IC3Interrupt | _AltIC3Interrupt | IC3 入力変化3 IC3 Input capture 3 |
29 | _IC4Interrupt | _AltIC4Interrupt | IC4 入力変化4 IC4 Input capture 4 |
30 | _IC5Interrupt | _AltIC5Interrupt | IC5 入力変化5 IC5 Input capture 5 |
31 | _IC6Interrupt | _AltIC6Interrupt | IC6 入力変化6 IC6 Input capture 6 |
32 | _OC5Interrupt | _AltOC5Interrupt | OC5 出力比較5 OC5 Output compare 5 |
33 | _OC6Interrupt | _AltOC6Interrupt | OC6 出力比較6 OC6 Output compare 6 |
34 | _OC7Interrupt | _AltOC7Interrupt | OC7 出力比較7 OC7 Output compare 7 |
35 | _OC8Interrupt | _AltOC8Interrupt | OC8 出力比較8 OC8 Output compare 8 |
36 | _INT3Interrupt | _AltINT3Interrupt | INT3 外部割り込み3 INT3 External interrupt 3 |
37 | _INT4Interrupt | _AltINT4Interrupt | INT4 外部割り込み4 INT4 External interrupt 4 |
38 | _C2Interrupt | _AltC2Interrupt | CAN2 複合IRQ CAN2 combined IRQ |
39 | _PWMInterrupt | _AltPWMInterrupt | PWM 周期一致 PWM period match |
40 | _QEIInterrupt | _AltQEIInterrupt | QEI ポジションカウンタ比較 QEI position counter compare |
41 | _DCIInterrupt | _AltDCIInterrupt | DCI CODEC 転送完了 DCI CODEC transfer completed |
42 | _LVDInterrupt | _AltLVDInterrupt | PLCD 定電圧検出 PLVD low voltage detected |
43 | _FLTAInterrupt | _AltFLTAInterrupt | FLTA MCPWM 異常A FLTA MCPWM fault A |
44 | _FLTBInterrupt | _AltFLTBInterrupt | FLTA MCPWM 異常B FLTB MCPWM fault B |
45 | _Interrupt45 | _AltInterrupt45 | 予約 Reserved |
46 | _Interrupt46 | _AltInterrupt46 | 予約 Reserved |
47 | _Interrupt47 | _AltInterrupt47 | 予約 Reserved |
48 | _Interrupt48 | _AltInterrupt48 | 予約 Reserved |
49 | _Interrupt49 | _AltInterrupt49 | 予約 Reserved |
50 | _Interrupt50 | _AltInterrupt50 | 予約 Reserved |
51 | _Interrupt51 | _AltInterrupt51 | 予約 Reserved |
52 | _Interrupt52 | _AltInterrupt52 | 予約 Reserved |
53 | _Interrupt53 | _AltInterrupt53 | 予約 Reserved |
各IRQ (Interrupt Request) の割り込みの優先順位は、0~7の8レベルで指定します。既定値は4であり、0と指定することは割り込みを無効とすることと同義です。
同一順位を指定された割り込みは、割り込みベクタテーブルの上位で定義されているものが優先されます。
CPU自体にも割り込みの優先順位を設定でき、全体の割り込みを制御するのに使用します。
このCPU割り込み優先順位は、マクロを使用して
SET_CPU_IPL( 7 );
のように設定できます。このマクロは、プロセッサ ヘッダファイル内で
#define SET_CPU_IPL(ipl) { \ int DISI_save; \ \ DISI_save = DISICNT; \ asm volatile ("disi #0x3FFF"); \ SRbits.IPL = ipl; \ DISICNT = DISI_save; } (void) 0; #define SET_AND_SAVE_CPU_IPL(save_to, ipl) { \ save_to = SRbits.IPL; \ SET_CPU_IPL(ipl); } (void) 0; #define RESTORE_CPU_IPL(saved_to) SET_CPU_IPL(saved_to)
のように定義されています。
なおCPU割り込み優先順位の既定値は0であり、IRQのそれは4であるため、初期状態ではすべての割り込みが有効となります。
各IRQ (Interrupt Request) に対して割り当てられた割り込み有効ビットを1に設定することで、割り込みが有効となります。厳密には、割り込み優先順位が0ではなく、CPU割り込み優先順位より高く設定されている必要もあります。
割り込みを有効にしたならば、それに対応した割り込みサービスルーチンを必ず設定します。さもなくば既定の_DefaultInterrupt
が呼ばれることになり、デバイスがリセットされます。
まとめると、割り込みが発生するには以下の条件を満たしている必要があります。
エラーなどにより処理を続行できないときに発生する割り込みです。
これらの割り込み優先順位は8以上が設定されており、汎用の割り込みよりも常に優先されます。