外部引脚中断
外部中断作为处理器响应外部事件的通道,在控制系统中起着非常重要的作用。从前面的讨论中我们知道,在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;
}