huangyekan 发表于 2011-11-13 16:17:23

外部中断,求解答

下面这个程序,我有个疑问,当按键按下后,也就是中断产生后,它是如何进入HandleFIQ的??因为要调用EINT_Handle 这个中断函数,必须要有进入 HandleFIQ啊,是怎么进入的?

   
b   Reset


; 0x04: 未定义指令中止模式的向量地址

HandleUndef

    b   HandleUndef



; 0x08: 管理模式的向量地址,通过SWI指令进入此模式

HandleSWI

    b   HandleSWI


; 0x0c: 指令预取终止导致的异常的向量地址

HandlePrefetchAbort

    b   HandlePrefetchAbort


; 0x10: 数据访问终止导致的异常的向量地址

HandleDataAbort

    b   HandleDataAbort


; 0x14: 保留

HandleNotUsed

    b   HandleNotUsed


; 0x18: 中断模式的向量地址

    b   HandleIRQ


; 0x1c: 快中断模式的向量地址

HandleFIQ

    b   HandleFIQ


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, #0x53       ; 设置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

   

    ldr lr, =int_return             ; 设置调用ISR即EINT_Handle函数后的返回地址

    ldr pc, =EINT_Handle            ; 调用中断服务函数,在interrupt.c中

int_return

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

   

END



**************************************** (c)**************************************************

**                               中南林业科技大学 计算机与信息工程学院

**                                 通信工程2班

**                                          李仕贤

**                                 http://blog.sina.com.cn/lshix

QQ:254569356

**-------------------------------------------文件信息----------------------------------------

** 文   件   名:main.C

** 版   本: v1.0

** 日 期: 2011年6月24日

** 描 述: 初始化函数

**********************************************************************************************

#include "s3c24xx.h"




#define GPB5_out      (1<<(5*2))      // LED1

#define GPB6_out      (1<<(6*2))      // LED2

#define GPB7_out      (1<<(7*2))      // LED3

#define GPB8_out      (1<<(8*2))      // LED4


*

* K1-K4对应GPG11、GPG3、GPF2、GPF0

*

#define GPF1_eint       (2<<(1*2))   // K1,EINT1

#define GPF4_eint       (2<<(4*2))      // K2,EINT4

#define GPF2_eint       (2<<(2*2))      // K3,EINT2

#define GPF0_eint       (2<<(0*2))      // K4,EINT0

**********************************************************************************************

**函数原型 :disable_watch_dog(void)

**参数说明 :   无

**返回值 : 无

**说 明 : 关闭WATCHDOG,否则CPU会不断重启

**********************************************************************************************

void disable_watch_dog(void)

{

    WTCON = 0;// 关闭WATCHDOG很简单,往这个寄存器写0即可

}

**********************************************************************************************

**函数原型 :   init_led(void)

**参数说明 :   无

**返回值 : 无

**说 明 : 本函数用于初始化GPBCON ,设置相应引脚为输出模式,以控制led灯

**********************************************************************************************

void init_led(void)

{

//首先清零

    GPBCON &=~((3<<5*2)|(3<<6*2)|(3<<7*2)|3<<8*2);

    //设置为输出模式

    GPBCON = GPB5_out | GPB6_out | GPB7_out | GPB8_out ;

}

**********************************************************************************************

**函数原型 :   init_irq( )

**参数说明 :   无

**返回值 : 无

**说 明 : 初始化GPIO引脚为外部中断

* GPIO引脚用作外部中断时,默认为低电平触发、IRQ方式(不用设置INTMOD)

**********************************************************************************************

void init_irq( )

{

//首先清零

GPFCON &=~((3<<1*2)|(3<<4*2)|(3<<2*2)|3<<0*2);

//设置为中断 默认是低电平触发

    GPFCON= GPF1_eint | GPF4_eint|GPF2_eint | GPF0_eint;

   

   

    // 需要在EINTMASK寄存器中使能它们

    EINTMASK &= (~(1<<0)) & (~(1<<1)) & (~(1<<2))& (~(1<<4));

      

    //设置中断优先级

    PRIORITY = (PRIORITY & ((~0x01) | (0x3<<7))) | (0x0 << 7) ;


    // EINT1、EINT4、EINT2,EINT0使能

    INTMSK   &= (~(1<<0)) & (~(1<<1)) & (~(1<<2))& (~(1<<4));

}



**************************************** (c)**************************************************

**                               中南林业科技大学 计算机与信息工程学院

**                                 通信工程2班

**                                          李仕贤

**                                 http://blog.sina.com.cn/lshix

QQ:254569356

**--------------------------------------------文件信息----------------------------------------

** 文   件   名:interrupt.C

** 版   本: v1.0

** 日 期: 2011年6月24日

** 描 述: 按键控制 led 亮灭

**********************************************************************************************

#include "s3c24xx.h"

**********************************************************************************************

**函数原型 :   EINT_Handle()

**参数说明 :   无

**返回值 : 无

**说 明 : 中断处理函数

**********************************************************************************************

void EINT_Handle()

{

    unsigned long value = INTOFFSET;//读取当前的中断,也可以读取INTPEND

    switch( value)

    {

      // K4被按下

      case 0:

      {   

            GPBDAT |= (0x0f<<5);   // 所有LED熄灭

            GPBDAT &= ~(1<<8);      // LED4点亮

            

      }break;

      

      // K3被按下

      case 2:

      {   

            GPBDAT |= (0x0f<<5);   // 所有LED熄灭

            GPBDAT &= ~(1<<7);      // LED3点亮

         

      } break;


      // K2被按下

      case 4:

      {   

            GPBDAT |= (0x0f<<5);   // 所有LED熄灭

            GPBDAT &= ~(1<<6);      // LED2点亮

            EINTPEND|=(1<<4);

         

      } break;

      case 1:

      {   

            GPBDAT |= (0x0f<<5);   // 所有LED熄灭

            GPBDAT &= ~(1<<5);      // LED1点亮

            

      }break;

      


      default:

      {

          //其它的中断,暂时没用

      

      }break;

    }

    //清中断,从源头开始清零

EINTPEND = (1<<11) | (1<<19);   

SRCPND = 1<<value;

INTPND = 1<<value;


   

}



**************************************** (c)**************************************************

**                               中南林业科技大学 计算机与信息工程学院

**                                 通信工程2班

**                                          李仕贤

**                                 http://blog.sina.com.cn/lshix

QQ:254569356

**--------------------------------------------文件信息-------------------------------------------------

** 文   件   名:main.C

** 版   本: v1.0

** 日 期: 2011年6月24日

** 描 述: 等待中断的产生

**********************************************************************************************

#include"s3c24xx.h"

int main()

{

    GPBDAT|=(0X0F<<5);

    while(1);

    return 0;

}
页: [1]
查看完整版本: 外部中断,求解答