天嵌 ARM开发社区

 找回密码
 注册
查看: 1757|回复: 0

外部中断,求解答

[复制链接]
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函数,调用前需要设好栈

    bl  disable_watch_dog   ; 关闭WATCHDOG,否则CPU会不断重启

   

    msr cpsr_c, #0xd2       ; 进入中断模式

    ldr sp, =3072           ; 设置中断模式栈指针


    msr cpsr_c, #0xdf       ; 进入系统模式

    ldr sp, =4096           ; 设置系统模式栈指针,

                            ; 其实复位之后,CPU就处于系统模式,

                            ; 前面的“ldr sp, =4096”完成同样的功能,此句可省略


    bl  init_led            ; 初始化LED的GPIO管脚

    bl  init_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;

}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

i.MX8系列ARM cortex A53 M4 工控板上一条 /1 下一条

Archiver|手机版|小黑屋|天嵌 嵌入式开发社区 ( 粤ICP备11094220号 )

GMT+8, 2024-5-10 05:15 , Processed in 1.078125 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表