一、首先要设置异常向量表地址为0(因为为0才可重映射)
再汇编中进行(由下图,在13位置零)

MRC p15, 0, <Rt>, c1, c0, 0 ; Read System Control Register
MCR p15, 0, <Rt>, c1, c0, 0 ; Write System Control Register
在_reset_handler当中加上
cpp
mrc p15, 0, r1, c1, c0, 0
orr r1, r1, #(1 << 12)
bic r1, r1, #(1 << 13)
mcr p15, 0, r1, c1, c0, 0
二、中断初始化
重映射异常向量地址
初始化GIC
cpp
void system_irq_init(void)
{
__set_VBAR(0x87800000);
GIC_Init();
}
三、配置中断源
1、引脚相关
配置引脚功能及其方向 GPIO_DIR
设置中断触发方式 ICR/IMR
ICR:中断配置寄存器,
|-------|----|
| 低电平触发 | 00 |
| 高电平触发 | 01 |
| 上升沿触发 | 10 |
| 下降沿触发 | 11 |
IMR:中断屏蔽寄存器
|---|------|
| 0 | 禁止中断 |
| 1 | 允许中断 |
2、GIC相关
GIC中断使能:GIC_EnableIRQ(IRQn_Type IRQn);
GIC中断优先级设置:GIC_SetPriority("中断号","优先级");
cpp
void key_irq_init(void)
{
IOMUXC_SetPinMux(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0);
IOMUXC_SetPinConfig(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0x10b0);
GPIO1->GDIR &= ~(1 << 18);
//设置中断触发方式
GPIO1->ICR2 |= (0x3 << 4);
//使能 GPIO 中断
GPIO1->IMR |= (1 << 18);
GIC_EnableIRQ(GPIO1_Combined_16_31_IRQn);
GIC_SetPriority(GPIO1_Combined_16_31_IRQn, 0);
}
3、异常处理
在汇编中结合c函数进行
前提须知

因此在iqr中要先给lr减4再入栈
cpp
_irq_handler:
sub lr,lr,#4
stmfd sp!,{r0-r12,lr}
//读取GIC中断号
mrc p15,4,r1,c15,c0,0
add r1,r1,#0x2000
ldr r0,[r1,#0x0c]
stmfd sp!, {r0,r1}
cps #0x1f
stmfd sp!, {r0-r12,lr}
bl system_irq_handler
stmfd sp!, {r0-r12,pc}
cps #0x12
ldmfd sp!, {r0,r1}
str r0, [r1,#0x10]
ldmfd sp!,{r0-r12,pc}^
cpp
void system_irq_handler(IRQn_Type irq_num)
{
if (irq_num == GPIO1_Combined_16_31_IRQn)
{
if (GPIO1->ISR & (1 << 18))
{
led_on();
tamper1_on();
GPIO1->ISR |= (1 << 18);
}
}
}