割り込み (Interrupt)

レジスタ (Register)

割り込みの制御には、以下のレジスタが関与します。

この内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
Table 6-3: Special Function Registers Associated with Interrupt Controller (DS70053D)

デバイスのヘッダでは次のようにマクロが定義されています。このためこれらのレジスタのビットは、その名称の前にアンダーバー (_) を付けることで参照できます。

/* 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

割り込みサービスルーチン (Interrupt Service Routine : ISR)

割り込み発生時にそれを処理するのは、割り込み属性でタグ付けされた、引数および戻り値を持たない関数です。

たとえばタイマ1割り込みを処理するISRは、

void __attribute__((interrupt)) _T1Interrupt( void );

のように宣言します。または、

#define _ISR      __attribute__((interrupt))
#define _ISRFAST  __attribute__((interrupt, shadow))

のようなマクロが定義されているので、

void _ISR _T1Interrupt( void );

のようにも記述できます。このとき_T1InterruptIVTのPrimary名であり、おのおのの割り込みに使用する関数名は、そこで定義されています。

割り込み属性の構文

__attribute__( ( interrupt
  [, shadow      // 高速コンテキスト保存を行う
   | auto_psv    // PSV領域に変数を配置する (既定)
   | no_auto_psv // PSV領域に変数を配置しない
    (
    [ save( symbol-list ) ]  // 割り込み処理内で保存、回復する変数のリスト
    [, irq( irqid ) ]        // 割り込みベクタの指定
    [, altirq( altirqid ) ]  // 代替割り込みベクタの指定
    [, preprologue( asm ) ]  // コンパイラが生成する関数の直前に挿入するアセンブリコード
    ) ]
  ) )
※[ ]で囲まれた項目は省略可能です。またinterrupt__interrupt__は同等です。

PSV (Program Space Visibility)

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 不可能 早い
Chapter 7.10 - MPLAB C30 C Compiler Users Guide (DS51284F)

ISR記述の指針

  1. 引数なし、戻り値なしとする (必須)
  2. ISRを割り込み以外から呼び出さない (必須)

    ISRは関数から抜けるときに、通常のRETURN命令ではなくRETFIE (割り込みからの戻り命令) を使用します。このため割り込み以外から呼び出されると、関数を抜けるときにステータスレジスタなどを破壊します。≫dsPIC30F/dsPIC33F Instruction Set

  3. ISRから他の関数を呼び出さない (推奨)

    ISRから他の関数を呼び出すと、すべてのワーキングレジスタとリピートループカウンタの保存と復帰が行われます。これにより処理が遅延しますので、ISRから他の関数を呼び出すべきではありません。

割り込みフラグ (Interrupt Flags)

割り込み発生時に、割り込みフラグが1にセットされます。これは自動でクリアされないため、割り込みサービスルーチン (ISR) を抜ける前に明示的にクリアする必要があります。さもなくばISRを抜けた直後に再び割り込みが発生し、ループすることになります。

割り込みベクタテーブル (Interrupt Vector Table : IVT)

割り込みベクタテーブルには2種類あります。

  • 割り込みベクタテーブル : IVT (Interrupt Vector Table)
  • 代替割り込みベクタテーブル : AIVT (Alternate Interrupt Vector Table)

通常は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
TABLE 7-1: INTERRUPT VECTORS – dsPIC30F DSCs (NON-SMPS) (DS51284F)

割り込み優先順位 (Interrupt Priority Level)

IRQ (Interrupt Request) の割り込みの優先順位は、0~7の8レベルで指定します。既定値は4であり、0と指定することは割り込みを無効とすることと同義です。

同一順位を指定された割り込みは、割り込みベクタテーブルの上位で定義されているものが優先されます。

CPU割り込み優先順位 (CPU Interrupt Priority Level)

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であるため、初期状態ではすべての割り込みが有効となります。

割り込みの有効 / 無効 (Interrupt Enable)

各IRQ (Interrupt Request) に対して割り当てられた割り込み有効ビットを1に設定することで、割り込みが有効となります。厳密には、割り込み優先順位が0ではなく、CPU割り込み優先順位より高く設定されている必要もあります。

割り込みを有効にしたならば、それに対応した割り込みサービスルーチンを必ず設定します。さもなくば既定の_DefaultInterruptが呼ばれることになり、デバイスがリセットされます。

割り込みの発生条件

まとめると、割り込みが発生するには以下の条件を満たしている必要があります。

  1. 割り込み有効ビットが1に設定されている
  2. 割り込み優先順位が1以上に設定されている
  3. 割り込み優先順位がCPU割り込み優先順位より高く設定されている
  4. 割り込み優先順位が6以下のとき、割り込み無効化 (DISable Interrupts : DISI) 命令が無効とされている

トラップ (Traps)

エラーなどにより処理を続行できないときに発生する割り込みです。

  • Math Error Trap
  • Address Error Trap
  • Stack Error Trap
  • Oscillator Fail Trap

これらの割り込み優先順位8以上が設定されており、汎用の割り込みよりも常に優先されます。

参考

  • Section 6. Interrupts (DS70053D)
  • セクション6. 割り込み (DS70600C_JP)
    (dsPIC33E/PIC24Eファミリ リファレンス マニュアル)