维C1° 发表于 2013-10-27 16:55:24

进不了中断,汇编文件如下,不知道哪里有问题?

本帖最后由 维C1° 于 2013-10-27 16:55 编辑

;@******************************************************************************
;@ File:head.S
;@ 功能:初始化,设置中断模式、系统模式的栈,设置好中断处理函数      
;@ 中断向量,本程序中,除Reset和HandleIRQ外,其它异常都没有使用,所以不用定义
;@******************************************************************************

      IMPORT disable_watch_dog
      IMPORT init_led
      IMPORT init_irq
      IMPORT main
      IMPORT EINT_Handle
      IMPORT close_leds
      
      AREA   head, CODE, READONLY   ;该伪指令定义了一个代码段,段名为head,属性只读

      ENTRY

    b   Reset                              
HandleUndef                                       
    b   HandleUndef               ;@ 0x04: 未定义指令中止模式的向量地址
HandleSWI   
    b   HandleSWI                        ;@ 0x08: 管理模式的向量地址,通过SWI指令进入此模式
HandlePrefetchAbort
    b   HandlePrefetchAbort      ;@ 0x0c: 指令预取终止导致的异常的向量地址
HandleDataAbort
    b   HandleDataAbort                ;@ 0x10: 数据访问终止导致的异常的向量地址
HandleNotUsed   
    b   HandleNotUsed                ;@ 0x14: 保留
   
    b   HandleIRQ                        ;@ 0x18: 中断模式的向量地址
HandleFIQ   
      b   HandleFIQ                        ;@ 0x1c: 快中断模式的向量地址

Reset               
    ldr sp, =4096         ;@ 设置栈指针,以下都是C函数,调用前需要设好栈
    bldisable_watch_dog   ;@ 关闭WATCHDOG,否则CPU会不断重启
    msr cpsr_c, #0xd2       ;@ 进入中断模式
    ldr sp, =3072         ;@ 设置中断模式栈指针

    msr cpsr_c, #0xdf       ;@ 进入系统模式
    ldr sp, =4096         ;@ 设置系统模式栈指针,
                            ;@ 其实复位之后,CPU就处于系统模式,
                            ;@ 前面的“ldr sp, =4096”完成同样的功能,此句可省略
    blinit_led            ;@ 初始化LED的GPIO管脚
    blinit_irq            ;@ 调用中断初始化函数,在init.c中
    msr cpsr_c, #0x5f       ;@ 设置I-bit=0,开IRQ中断
    ldr lr, = halt_loop   ; @ 设置返回地址
    ldr pc, = main         ;@ 调用main函数
   
halt_loop
   
    b   halt_loop

HandleIRQ
    sub lr, lr, #4               ; @ 计算返回地址
    stmdb   sp!,    { r0-r12,lr }; @ 保存使用到的寄存器
                                 ; @ 注意,此时的sp是中断模式的sp
                                 ; @ 初始值是上面设置的3072
    blclose_leds
    ldr lr, =int_return            ; @ 设置调用ISR即EINT_Handle函数后的返回地址
    ldr pc, =EINT_Handle         ; @ 调用中断服务函数,在interrupt.c中

int_return

    ldmia   sp!,    { r0-r12,pc }^ ; @ 中断返回, ^表示将spsr的值复制到cpsr
   
      END

其中中断初始化程序如下
void init_irq( )
{
    rGPFCON &=~(0x33f);
    rGPFCON |=0x22a;      //设置GPF0、1、2、4为中断输入功能
   
    rSRCPND = 0x17;                //清除ENIT0、1、2、4的中断标志位
    rINTPND = 0x17;                //清除ENIT0、1、2、4的中断标志位
    rEINTPEND=(1<<4);      //清除ENIT4的中断标志位
      
    rINTMSK &= ~0x17;      //ENIT0、1、2、4中断服务有效(这里就是使能外部中断)
    rEINTMASK &= ~(1<<4);//EINT4中断服务有
}

出现的问题:程序编译成功,下载到板子上,按下按键没有反应,程序进不了中断,是中断入口地址有问题吗?我在HandleIRQ工作模式下增加了一句 blclose_leds,关灯,来测试能否进入中断,但还是没有任何反应,另外,当发生异常时,程序是自动进入相应的工作模式的不是吗?
页: [1]
查看完整版本: 进不了中断,汇编文件如下,不知道哪里有问题?