硬件电路: 

 

 寄存器:

 

 

 

 

 

 

 

 

 中断程序:

#define    GPX1CON         (*(volatile unsigned int *)0x11000C20)
#define    EXT_INT41CON    (*(volatile unsigned int *)0x11000E04)
#define    EXI_INT41_MASK  (*(volatile unsigned int *)0x11000F04)
#define    ICDISER1_CPU0   (*(volatile unsigned int *)0x10490104)
#define    ICDDCR          (*(volatile unsigned int *)0x10490000)
#define    ICCICR_CPU0     (*(volatile unsigned int *)0x10480000)
#define    ICCPMR_CPU0     (*(volatile unsigned int *)0x10480004)
#define    ICDIPTR14_CPU0  (*(volatile unsigned int *)0x10490838)
#define    ICCIAR_CPU0     (*(volatile unsigned int *)0x1048000C)
#define    EXI_INT41_REND  (*(volatile unsigned int *)0x11000F44)
#define    ICDICRPR1_CPU0  (*(volatile unsigned int *)0x10490284)
#define    ICCEOIR_CPU0    (*(volatile unsigned int *)0x10480010)

#define    GPA1CON    (*(volatile unsigned int *)0x11400020)
#define    ULCON2     (*(volatile unsigned int *)0x13820000)
#define    UCON2      (*(volatile unsigned int *)0x13820004)
#define    UBRDIV2    (*(volatile unsigned int *)0x13820028)
#define    UFRACVAL2  (*(volatile unsigned int *)0x1382002c)
#define    UTXH2      (*(volatile unsigned int *)0x13820020)
#define    UTRSSTAT2  (*(volatile unsigned int *)0x13820010)




void interrupt_init(void)
{
    GPX1CON = (GPX1CON & ~(0x0f << 4)) | (0x0f<<4);
    EXT_INT41CON = (EXT_INT41CON & ~(0x07<<4)) | (0x02<<4);
    EXT_INT41_MASK = (EXT_INT41_MASK & ~(0x01<<1));
    
    ICDISER1_CPU0 = ICDISER1_CPU0 | (1<<25);    //EINT9 (GPX1_1) GIC中断使能
    ICDIPTR14_CPU0 = 0x01010101;
    ICDDCR = ICDDCR | 1;    //GIC分发总使能
    ICCICR_CPU0 = 1;        //CPU0 中断使能
    ICCPMR_CPU0 = 0xff;     //设置CPU0的优先级门槛为最低
}

void do_irq(void)
{
    int irq_num;
    irq_num = ICCIAR_CPU0 & 0x3ff;    //中断号ID
    switch(irq_num)
    {
        case 57:
            putc('q');
            EXI_INT41_PEND = EXT_INT41_PEND | (1<<1);    //清GPX1_1中断标志
            ICDICPR1_CPU0 = ICDICPR1_CPU0 | (1<<25);    //清GIC GPX1_1中断标志
            break;
        default:
            putc('y');
            break;
    ICCEOIR_CPU0 = (ICCEOIR_CPU0 & 0x3FF) | irq_num;
    }
}

int main(void)
{
    uart_init();
    interrupt_init();
    while(1)
    {
        putc('a');
        delayis();
    }
    return 0;
}

汇编:

    .glabal    delayis
    .text
    .global    _start

_start:
    b      reset                        @0x00
    ldr    pc,_undefined_instruction    @0x04
    ldr    pc,_softwate_interrupt
    ldr    pc,_prefetch_abort
    ldr    pc,_data_abort
    ldr    pc,_not_used
    ldr    pc,_irq                      @0x18
    ldr    pc,_fiq

_undefined_instruction:
    .word    _undefined_instruction

_software_interrupt:
    .word    _software_interrupt

_prefetch_abort:
    .word    _prefetch_abort

_data_abort:
    .word    _data_abort

_not_used:
    .word    _not_used

_irq:
    .word    irq_handler

_fiq:
    .word    _fiq

irq_handler:
    sub lr,lr,#4
    stmfd sp!,{r0,r12,lr}     @进栈保存现场
    bl do_irq

irq_handler_end:
    ldmfd sp!,{r0 - r12,pc}^    @出栈恢复现场

reset:
    ldr r0,=0x40008000            @设置异常向量表的启动地址为0x40008000



中断过程

     中断初始化

             管脚初始化

           中断控制器初始化

    中断向量表

           中断发生后,硬件自动跳转

           现场保护

           调用中断处理

    中断处理

           根据中断号做相应处理

           清中断

           现场恢复