千家信息网

arm9中断结构是怎样的

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇文章主要讲解了"arm9中断结构是怎样的",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"arm9中断结构是怎样的"吧!S3C2440的中断分为两大类
千家信息网最后更新 2026年11月02日arm9中断结构是怎样的

这篇文章主要讲解了"arm9中断结构是怎样的",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"arm9中断结构是怎样的"吧!

S3C2440的中断分为两大类: 外部中断 和 内部中断.

一 外部中断

EXTINT[x]: 用来配置各个引脚的中断触发方式 (高电平触发、低电平触发、下降沿触发、上升沿触发), 注意该寄存器与中断源的对应关系

EINTPEND[x]: xxxPEND的寄存器都是状态寄存器, 初始化时先清除标志, 在清除中断的时候将寄存器的值赋值给本身即可

EINTMSK[x]: 1 屏蔽中断; 0 未屏蔽

SRCPEND[x]: 1 申请中断; 0 未申请中断

EINTFLT0~EINTFLT3: 配置滤波时钟和滤波宽度

INTMOD[x]: 1: FIQ, 0: IRQ

二 内部中断

内部中断分两种: 带子中断的中断 和 不带子中断的中断

  1. 不带子中断: 发生中断后 SRCPEND置位, 如果没有被 INTMSK屏蔽, 那么继续向下一步申请中断

  2. 带子中断: 发生中断之后, 先将 SUBSRCPEND 置位, 如果没有INTSUBMSK屏蔽则向 SRCPEND申请中断. 如果没有被INTMSK屏蔽则进一步向下申请中断


中断的优先级:

ARB_MODEx: 控制中断优先级是否轮转

ARB_SELx: 控制轮转顺序

中断的开启(xxxMSK):

1 外部中断: EINT4~23先初始化EINTMSK 和 INTMSK, 如果是EINT0~3直接初始化INTMSK

2 内部中断: 有子中断先初始化 INTSUBMSK 再初始化 INTMSK, 如果是不带子中断的内部中断直接初始化 INTMSK

中断的清除(xxxPEND):

1 外部中断: 如果是EINT4~23 先清除EINTPEND 再清除 INTPEND (注意顺序), 如果是 EINT0~3 直接清除SRCPEND. (不需要清除 INTPEND???)

2 内部中断: 带子中断, 先清除 SUBSRCPEND再清除SRCPEND(注意顺序); 不带子中断直接清除SRCPEND

3 清除中断是写 1 清除

三 代码解析

@******************************************************************************@ File:head.S@ 功能:初始化,设置中断模式、管理模式的栈,设置好中断处理函数@******************************************************************************.extern     main.text.global _start_start:@******************************************************************************@ 中断向量,本程序中,除Reset和HandleIRQ外,其它异常都没有使用@******************************************************************************    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   HandleFIQReset:    ldr sp, =4096           @ 设置栈指针,以下都是C函数,调用前需要设好栈    bl  disable_watch_dog   @ 关闭WATCHDOG,否则CPU会不断重启    msr cpsr_c, #0xd2       @ 进入中断模式    ldr sp, =3072           @ 设置中断模式栈指针    msr cpsr_c, #0xd3       @ 进入管理模式, reset之后就是管理模式, 所以这里的设置和reset下的ldr sp, =4096为一个作用, 本条代码可以省略    ldr sp, =4096           @ 设置管理模式栈指针,                            @ 其实复位之后,CPU就处于管理模式,                            @ 前面的"ldr sp, =4096"完成同样的功能,此句可省略    bl  init_led            @ 初始化LED的GPIO管脚    bl  init_irq            @ 调用中断初始化函数,在init.c中    msr cpsr_c, #0x5f       @ 设置I-bit=0,开IRQ中断    ldr lr, =halt_loop      @ 设置返回地址    ldr pc, =main           @ 调用main函数halt_loop:    b   halt_loopHandleIRQ:    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

注意: 1. 这里中断并不是根据名字来确定的, 而是根据中断向量的地址(0x0 / 0x4 / 0x8 / 0xc / 0x10...). IRQ正是0x18. 只需要在该位置放置一条跳转指令即可实现中断isr. 这是只要是IRQ都要从这一个入口进入中断, 然后再检查到底是哪个源申请了中断.

芯片在各个模式之下使用的是不同的sp和lr寄存器, reset之后就是管理模式, 所以管理模式的ldr sp, =4096是等价于reset下的那条sp语句

// init.c: 初始化LED及 中断#include "s3c24xx.h"// LED1,LED2,LED4对应GPF4、GPF5、GPF6#define GPF4_out        (1<<(4*2))#define GPF5_out        (1<<(5*2))#define GPF6_out        (1<<(6*2))#define GPF4_msk        (3<<(4*2))#define GPF5_msk        (3<<(5*2))#define GPF6_msk        (3<<(6*2))/* * S2,S3,S4对应GPF0、GPF2、GPG3 */#define GPF0_eint     (0x2<<(0*2))#define GPF2_eint     (0x2<<(2*2))#define GPG3_eint     (0x2<<(3*2))#define GPF0_msk    (3<<(0*2))#define GPF2_msk    (3<<(2*2))#define GPG3_msk    (3<<(3*2))// 关闭WATCHDOG,否则CPU会不断重启void disable_watch_dog(void){    WTCON = 0;  // 关闭WATCHDOG很简单,往这个寄存器写0即可}void init_led(void){    // LED1,LED2,LED4对应的3根引脚设为输出    GPFCON &= ~(GPF4_msk | GPF5_msk | GPF6_msk);    GPFCON |= GPF4_out | GPF5_out | GPF6_out;}/* 初始化GPIO引脚为外部中断 * GPIO引脚用作外部中断时,默认为低电平触发、IRQ方式(不用设置INTMOD) */void init_irq( ){    // S2,S3对应的2根引脚设为中断引脚 EINT0,ENT2    GPFCON &= ~(GPF0_msk | GPF2_msk);    GPFCON |= GPF0_eint | GPF2_eint;    // S4对应的引脚设为中断引脚EINT11    GPGCON &= ~GPG3_msk;    GPGCON |= GPG3_eint;    // 对于EINT11,需要在EINTMASK寄存器中使能它    EINTMASK &= ~(1<<11);    /*     * 设定优先级:     * ARB_SEL0 = 00b, ARB_MODE0 = 0: REQ1 > REQ3,即EINT0 > EINT2     * 仲裁器1、6无需设置     * 最终:     * EINT0 > EINT2 > EINT11即K2 > K3 > K4     */    PRIORITY &= ((((~0x01) | (0x3<<7))) | (0x0 << 7)) ;    // EINT0、EINT2、EINT8_23使能    INTMSK   &= (~(1<<0)) & (~(1<<2)) & (~(1<<5));}

中断初始化步骤:

(1) 设置好 IRQ 和 FIQ 的栈

(2) 准备中断处理函数

1. 异常向量中设置好跳转函数

2. 中断服务程序(ISR)

3. 清除中断

4. 保护现场, 恢复现场

(3) 根据中断源设置相关外设

  1. 外部中断: 设置引脚为"外部中断", 设置中断触发方式, 开启对应的屏蔽寄存器, EINTMSK

  2. 内部中断: 将INTSUBMSK开启

(4)确定中断的使用方式: IRQ 或 FIQ

  1. FIQ: 在 INTMOD 设置相应的bit为1

  2. IRQ: 在PRIORITY寄存器中设置优先级, 将 INTMSK中设置为0 (FIQ不受INTMSK影响)

(5) 置位 CPSR中的 I-bit(IRQ) 或 F-bit(FIQ)

#include "s3c24xx.h"void EINT_Handle(){    unsigned long oft = INTOFFSET;//INTPND[X]为1,则INTOFFSET为x     unsigned long val;        switch( oft )    {        // S2被按下        case 0:         {               GPFDAT |= (0x7<<4);   // 所有LED熄灭            GPFDAT &= ~(1<<4);      // LED1点亮            break;        }                // S3被按下        case 2:        {               GPFDAT |= (0x7<<4);   // 所有LED熄灭            GPFDAT &= ~(1<<5);      // LED2点亮            break;        }        // K4被按下        case 5:        {               GPFDAT |= (0x7<<4);   // 所有LED熄灭            GPFDAT &= ~(1<<6);      // LED4点亮                            break;        }                //K1 或 K2 被按下, 假设K1 k2 接在EINT8~23, 查询INTPEND[5]之后还要查询EINTPEND[x]来确定EINT8~EINT23        case 5:        {            GPBDAT |= (0x0f << 5);//所有LED熄灭                        //需要进一步判断是k1 还是 k2, 或是 同时按下            val = EINTPEND;            if (val & (1 << 11))            {                GPBDAT &= ~(1 << 6);//K2            }            if (val & (1 << 19))            {                GPBDAT &= ~(1 << 5);//K1            }            break;        }        default:            break;    }    //清中断    if( oft == 5 )  //如果是外部中断则要多清除EINTPEND这个寄存器         EINTPEND = (1<<11);   // EINT8_23合用IRQ5,SRCPND[5], INTPND[5]            SRCPND = 1<

这里oft表示INTOFFSET寄存器的值, INTPND[x]为1, oft就是x. 该值为5表示 EINT8-23的中断源, 这时再查看 EINTPEND来确定到底是哪个引脚.

感谢各位的阅读,以上就是"arm9中断结构是怎样的"的内容了,经过本文的学习后,相信大家对arm9中断结构是怎样的这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

模式 寄存器 地址 向量 函数 管理模式 管理 带子 结构 就是 指令 方式 优先级 指针 电平 顺序 中设 学习 不断 代码 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网络科技 嘟嘟瓜互联网科技 广州凡科互联网科技 互联网科技logo 互联网科技类展会 中国的互联网科技企业的崛起 互联网科技有哪些公司 互联网金融科技名词解释 保险科技服务互联网营销体系 为客找房互联网科技公司怎么样 互联网第三次科技革命特征 杭州披云加互联网科技有限公司 有人说阿里系是互联网科技企业 互联网时代科技型公司的机会 容联科技互联网电商 广州三三互联网科技有限公司 北京军民互联网科技公司 互联网科技品牌 北京品多多互联网科技有限公司 互联网大会出现的黑科技 手冲咖啡和咖啡机区别 互联网下的科技发展 互联网公司 科技公司 为想互联网科技 互联网科技视频素材 科技大学互联网专业好不好 中国互联网公司排名锤子科技 沐思想互联网科技有限公司 云鲸互联网络科技有限公司 数字互联网科技有限公司
0