外部中斷作為處理器響應外部事件的通道,在控制系統中起着非常重要的作用。從前面的討論中我們知道,在NVIC中有8個外部中斷源,下面就來討論一下這8個外部中斷的使用情況。
LPC824的每一根引腳都可以響應一個外部中斷,所以理論上有多少個引腳就有多少個外部中斷。但由於LPC824采用了引腳掛接外部中斷源的形式,所以並不是所有的引腳都可以同時設置為外部中斷引腳。在LPC824中,可同時響應的外部中斷源只有8個(即NVIC的8路引腳中斷),所以同時只能有8個外部中斷引腳在工作,但這8個外部中斷引腳可選擇從PIO0_0至PIO0_28中的任意一根。
LPC824外部引腳中斷所涉及到的寄存器如下表所示。
__IO uint32_t ISEL;
__IO uint32_t IENR;
__O uint32_t SIENR;
__O uint32_t CIENR;
__IO uint32_t IENF;
__O uint32_t SIENF;
__O uint32_t CIENF;
__IO uint32_t RISE;
__IO uint32_t FALL;
__IO uint32_t IST;
__IO uint32_t PMCTRL;
__IO uint32_t PMSRC;
__IO uint32_t PMCFG;
} LPC_PIN_INT_Type;
#define LPC_PIN_INT_BASE 0xA0004000UL
#define LPC_PIN_INT ((LPC_PIN_INT_Type *) LPC_PIN_INT_BASE)

(2)第8到31位為保留位。

(2)第8到31位為保留位。

(2)第8到31位為保留位。

(2)第8到31位為保留位。

(2)第8到31位為保留位。

(2)第8到31位為保留位。

(2)第8到31位為保留位。

(2)第8到31位為保留位。

(2)第8到31位為保留位。

(2)第8到31位為保留位。

(2)第6到31位為保留位。
1、確定要配置為中斷模式的引腳,然后在SYSCON模塊的PINTSEL寄存器中進行選擇設置,一共可以配置8個外部中斷引腳。例如,執行“LPC_SYSCON->PINTSEL0 |= 0x01;”語句后,就把PIO0_1引腳設置為了外部中斷引腳。
2、確定是電平觸發還是邊沿觸發,通過ISEL寄存器進行選擇配置。例如,執行“LPC_PIN_INT->ISEL &= ~0x01;”語句后,就把PIO0_1引腳設置為邊沿觸發方式(其實默認就是邊沿觸發方式,此句也可不寫)。
3、若上一步配置成電平觸發,則需要確定是低電平觸發還是高電平觸發,若是邊沿觸發,則需要確定是上升沿觸發還是下降沿觸發,通過IENR或IENF寄存器進行執行配置。例如,執行“LPC_PIN_INT->IENR |= 0x01;”語句后,就把PIO0_1引腳設置為上升沿觸發方式;執行“LPC_PIN_INT->IENF |= 0x01;”語句后,就把PIO0_1引腳設置為下降沿觸發方式。
4、在第3步中,還可以通過訪問SIENR和CIENR寄存器來更改IENR寄存器中的某一位,通過訪問SIENF和CIENF寄存器來更改IENF寄存器中的某一位。SIENR、CIENR和SIENF、CIENF這四個寄存器其實是IENR和IENF寄存器的伴侶寄存器,用來優化位操作,以避免對IENR和IENF寄存器直接執行“讀—改—寫”的操作,提高效率。
5、使能NVIC中的相關外部中斷。例如,執行“NVIC_EnableIRQ(PIN_INT0_IRQn);”語句后,就使能了PIO0_1上的外部引腳中斷。
6、在中斷服務程序中,需要清除原有的外部中斷標記,以保證下一次外部中斷順利觸發,通過訪問RISE寄存器來清除上升沿中斷標記,通過訪問FALL寄存器來清除下降沿標記。例如,執行“LPC_PIN_INT->RISE |= 0x01;”語句后,PIO0_1原來的上升沿中斷標記就被清除了。執行“LPC_PIN_INT->FALL |= 0x01;”語句后,PIO0_1原來的下降沿中斷標記就被清除了。
7、在第6步中,也可以通過訪問IST寄存器來清除邊沿(包括上升沿和下降沿)觸發的標記。執行“LPC_PIN_INT->IST |= 0x01;”語句后,PIO0_1原來的邊沿中斷標記就被清除了。

void PIN_INT0_IRQHandler(void)
{
PINTSEL0中斷服務程序部分
}

#include <LPC82x.h>
//************************端口初始化***********************************
void Port_init(void)
{
LPC_GPIO_PORT->DIRSET0 = (1<<7) | (1<<13); //設置端口為輸出方向
LPC_GPIO_PORT->SET0 = (1<<7) | (1<<13); //熄滅LED
}
//***************************主函數************************************
int main(void)
{
Port_init(); //調用端口初始化
LPC_SYSCON->PINTSEL0 = 0x1;//選擇PIO0_1作為外部中斷引腳
LPC_SYSCON->PINTSEL1 = 0x4;//選擇PIO0_4作為外部中斷引腳
// LPC_PIN_INT->ISEL &= ~0x3; //邊沿觸發
LPC_PIN_INT->IENR |= 0x1; //PINTSEL0上升沿使能
LPC_PIN_INT->IENF |= 0x2; //PINTSEL1下降沿使能
NVIC_EnableIRQ(PIN_INT0_IRQn);//使能PINTSEL0中斷
NVIC_EnableIRQ(PIN_INT1_IRQn);//使能PINTSEL1中斷
while(1)
{
;
}
}
//*********************PINTSEL0中斷(S2)*****************************
void PIN_INT0_IRQHandler(void)
{
LPC_GPIO_PORT->NOT0 = 0x2000; //LED2取反
LPC_PIN_INT->RISE |= 0x1;
}
//*********************PINTSEL1中斷(S1)*****************************
void PIN_INT1_IRQHandler(void)
{
LPC_GPIO_PORT->NOT0 = 0x80; //LED1取反
LPC_PIN_INT->FALL |= 0x2;
}