历史上的今天
返回首页

历史上的今天

今天是:2024年09月02日(星期一)

正在发生

2021年09月02日 | S3c2440ARM异常与中断体系详解6---按键中断程序示例概述与初始

2021-09-02 来源:eefocus

在前面的视频里我们举了一个例子,母亲看书被声音打断,远处的声音来源有多种多样,声音传入耳朵,再由耳朵传入大脑,整个过程涉及声音来源耳朵大脑,为了确保这个母亲看书的过程能够被声音打断,我们必须保证声音来源可以发出声音,耳朵没有聋,脑袋没有傻。


中断处理流程

1、中断初始化:


①我们需要设置中断源,让它能够发出中断

②设置中断控制器,让它能发出中断给CPU

③设置CPU,CPSR有I位,是总开关


2、处理完之后清理中断


3、处理时,要分辨中断源,对于不同的中断源要执行不同的处理函数

下面开始写代码


打开start.S 先做初始化工作,先做第 3 设置CPU,CPSR有I位,是总开关


我们需要把CPSR寄存器 bit7给清零,这是中断的总开关,如果bit7设置为1,CPU无法响应任何中断

在这里插入图片描述

    /* 清除BSS段 */

    bl clean_bss


    /* 复位之后, cpu处于svc模式

     * 现在, 切换到usr模式

     */

    mrs r0, cpsr         /* 读出cpsr */

    bic r0, r0, #0xf     /* 修改M4-M0为0b10000, 进入usr模式 */


/*1

把bit7这一位清零

*/

    bic r0, r0, #(1<<7)  /* 清除I位, 使能中断 */

    msr cpsr, r0


    /* 设置 sp_usr */

    ldr sp, =0x33f00000


    ldr pc, =sdram

sdram:

    bl uart0_init


    bl print1

    /* 故意加入一条未定义指令 */

und_code:

    .word 0xdeadc0de  /* 未定义指令 */

    bl print2


    swi 0x123  /* 执行此命令, 触发SWI异常, 进入0x8执行 */


/*2 调用两个中断 */

    bl interrupt_init /*初始化中断控制器*/

    bl eint_init /*初始化按键,设为中断源*/


/*需要初始化上面这两个函数*/

    //bl main  /* 使用BL命令相对跳转, 程序仍然在NOR/sram执行 */

    ldr pc, =main  /* 绝对跳转, 跳到SDRAM */


halt:

    b halt


添加一个 interrupt.c文件,这个程序稍微有些复杂,我们先画个流程图

在这里插入图片描述

我们想达到按下按键灯亮松开按键灯灭,把下面四个按键全部配置为外部中断按键

在这里插入图片描述

打开芯片手册找到第九章 IO ports,直接搜索“’EINT0号中断和EINT2号中断”’,找配置寄存器 GPFCON

在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

为了简单操作


/* 1、初始化按键,设置为中断源 */ 


void key_eint_int()

{

/* 配置GPF0 GPF2 GPG3 GPG11中断引脚 */

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

GPFCON  |= ((2<<0) | (2<<4)); /* S2,S3被配置为中断引脚 */

GPGCON  &= ~((3<<22) | (3<<6));

GPGCON  |= ((2<<22) | (2<<6)); /* S4,S5被配置为中断引脚 */ 

}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

/* 1、初始化按键,设置为中断源 */ 


void key_eint_int()

{

/* 1、配置GPF0 GPF2 GPG3 GPG11中断引脚 */


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

GPFCON  |= ((2<<0) | (2<<4)); /* S2,S3被配置为中断引脚 */

GPGCON  &= ~((3<<22) | (3<<6));

GPGCON  |= ((2<<22) | (2<<6)); /* S4,S5被配置为中断引脚 */ 

/* 2、设置中断触发方式: (按下松开,从低电源变为高电源,或者从)双边沿触发 */

/*    设置EINT0 EINT2为双边沿触发                                   */

EXTINT0 |= ((7<<0) | (7<<8)) /* S2,S3 */

EXTINT1 |= (7<<12)           /* S4    */

EXTINT2 |= (7<<12)           /* S5    */

}


外部中断屏蔽寄存器EINTMASK,设置为1的话就禁止向外部发出中断信号,只有EINTMASK相应的位设置为0外部中断才能给中断控制器发信号


我们需要设置这个寄存器

在这里插入图片描述

把EINT11设置为0 把EINT19设置为0对于EINT0 和EINT2显示为保留,默认时使能的,可以直接发送给中断控制器,无需设置

在这里插入图片描述

设置EINTMASK使能eint11,19

EINTMASK &= ~((1<<11) | (1<<19));


读EINTPEND分辨哪个EINT产生(eint4~23)(并且要清除它)

清除中断时, 写EINTPEND的相应位

在这里插入图片描述

我们接下来需要阅读‘第14章 Interrupt Controller章节设置中断控制器我们只需要按照下面这张流程图设置就可以了

在这里插入图片描述

MASK 屏蔽寄存器

INTPND 等待处理,我们可以读这个寄存器,确定是那个中断产生了

SRCPND不同的中断类型不可以直接到达这里执行


我们来看一下外部中断属于哪一种


打开芯片手册,从上往下读

在这里插入图片描述

由上图可得 EINT4_7 EINT8_23合用一条中断线ARB1


也就是可以直接到达SRCPND不需要设置SUBSRCPND和SUBMASK这两个寄存器


我们使用的外部中断源只需要设置SRCPND MASK INTPND这三个就可以

在这里插入图片描述

SRCPND表明中断请求状态标志位

SRCPND寄存器由32位组成,每一位都与中断源相关。如果相应的中断源生成中断请求并等待相应的中断服务,则将每个位设置为1,该寄存器指示哪个中断源正在等待服务请求。注意,SRCPND寄存器的每个位都是由中断源自动设置的,而不管INTMASK寄存器中的maskina位是什么。此外,SRCPND寄存器不受中断控制器优先级逻辑的影响。

在这里插入图片描述

 /* SRCPND 用来显示哪个中断产生了, 需要清除对应位,我们只需要关心

  * bit0对应eint0

  * bit2对应eint2

  * bit5对应eint8_23(表明bit5等于1的时候 eint8_23中的某一个已经产生,我们需要继续分辨

  * 读EINTPEND分辨率哪个EINT产生)

  */


INTMOD寄存器 ,模式选择,默认值为IRQ模式即可,不需要设置

在这里插入图片描述

INTMASK寄存器 ,决定哪个中断被屏蔽,需要设置为0

在这里插入图片描述

 /* INTMSK 用来屏蔽中断, 1对应masked屏蔽中断,我们需要设置相应位设置为0

  * bit0-eint0

  * bit2-eint2

  * bit5-eint8_23

  */


同时可能有多个中断产生,这么多个中断经过优先级以后,只会有一个通知CPU,是哪一个中断优先级最高,可以读INTPAD就能知道当前处理的唯 一 一个中断是那一个

INTPAD寄存器中的32位中的每一位都显示了对应的中断请求是否被解除屏蔽,并等待中断被服务。拥有最高优先级。由于INTPND register位于优先级逻辑之后,因此只能将一个位设置为1 ,而中断请求将生成IRQ到CPU。在中断服务程序为IRQ。您可以读取这个寄存器来确定在32个中断源中哪个中断源得到了服务。

在这里插入图片描述

1 表示这个中断已经产生,需要配置相应的位

INTPND 用来显示当前优先级最高的、正在发生的中断, 需要清除对应位

bit0-eint0

bit2-eint2

bit5-eint8_23


INTOFFSET寄存器 是用来显示INTPND寄存器中哪一位正在等待处理

在这里插入图片描述

INTPND中bit0等于0的话INTOFFSET就等于0

INTPND中bit1等于1的话INTOFFSET值就等于1

INTOFFSET : 用来显示INTPND中哪一位被设置为1


SUBSRCPND我们用不到

在这里插入图片描述
在这里插入图片描述

某一位等于1时INT_UART0它的来源可能有多个,这是串口0的中断,串口0的中断产生时有可能是接收到了数据(INT_RXD0),有可能是发送了数据(INT_TXD0),也有可能是产生了错误,那么到底是哪一个呢?


需要去读取SUBSRCPND下一级的源寄存器


我们只需要设置INTMSK寄存器 这个寄存器


SRCPND和INTPND 只有发生中断才需要设置


/* 初始化中断控制器 */

void interrupt_init(void)

{

    //1是屏蔽我们需要清零,外部中断0 外部中断2 外部中8_23里面还有外部中断11到19

    INTMSK &= ~((1<<0) | (1<<2) | (1<<5));


}


修改start.S

删除

bl interrupt_init /* 初始化中断控制器 /

bl key_eint_init / 初始化按键, 设为中断源 */


能使用c语言就使用C语言,在main.c文件中添加调用C函数


int main(void)

{

/************1/

    interrupt_init();  /* 初始化中断控制器 */

    key_eint_init();   /* 初始化按键, 设为中断源 */

*******/    

    puts("nrg_A = ");

    printHex(g_A);

    puts("nr");

推荐阅读

史海拾趣

AEM [ American Electronic Materials]公司的发展小趣事

AEM深知人才是企业发展的核心竞争力。因此,公司一直注重人才培养和团队建设。AEM建立了完善的人才培养和激励机制,吸引和培养了一批高素质、专业化的员工队伍。同时,公司还为员工提供了良好的工作环境和发展空间,鼓励员工不断创新和进取。

在团队建设方面,AEM注重团队合作和沟通协作能力的培养。通过定期的团队建设活动和内部培训,AEM打造了一支团结、高效、富有战斗力的团队,为公司的持续发展提供了有力保障。

这五个故事从不同角度展示了AEM公司在电子行业中的发展历程和取得的成就。通过不断创新、合作与拓展,AEM已经成为电子行业中具有重要影响力的企业之一。未来,随着技术的不断进步和市场的不断变化,AEM将继续保持其领先地位,为电子行业的发展贡献更多力量。

Galaxy ( Bel )公司的发展小趣事

AEM深知人才是企业发展的核心竞争力。因此,公司一直注重人才培养和团队建设。AEM建立了完善的人才培养和激励机制,吸引和培养了一批高素质、专业化的员工队伍。同时,公司还为员工提供了良好的工作环境和发展空间,鼓励员工不断创新和进取。

在团队建设方面,AEM注重团队合作和沟通协作能力的培养。通过定期的团队建设活动和内部培训,AEM打造了一支团结、高效、富有战斗力的团队,为公司的持续发展提供了有力保障。

这五个故事从不同角度展示了AEM公司在电子行业中的发展历程和取得的成就。通过不断创新、合作与拓展,AEM已经成为电子行业中具有重要影响力的企业之一。未来,随着技术的不断进步和市场的不断变化,AEM将继续保持其领先地位,为电子行业的发展贡献更多力量。

亿宝科技(CNIBAO)公司的发展小趣事

品质是亿宝科技的生命线。公司始终坚持严格的质量管理体系,从原材料采购到生产流程,再到成品检验,每一个环节都严格把控。在一次客户反馈中,亿宝科技发现某批次产品存在细微的质量问题。公司立即启动紧急预案,召回所有相关产品并进行全面检查。经过一系列的改进措施,亿宝科技成功解决了问题,并赢得了客户的信任和好评。

AMI [American Megatrends Inc]公司的发展小趣事

亿宝科技在成立初期,就明确了以技术创新为核心的发展战略。公司创始人带领研发团队,深入研究市场需求,不断推出具有竞争力的电子产品。在一次偶然的机会中,他们成功研发出一款具有高性能、低功耗特点的芯片,这一创新技术迅速获得了市场的认可。此后,亿宝科技不断加大研发投入,形成了一套完整的自主研发体系,为公司后续的发展奠定了坚实的基础。

Cellergy公司的发展小趣事

在电子行业的快速发展中,Cellergy公司以一项创新技术打破了行业内的常规。该公司成功研发出了一种新型电容器,其性能远超市场上同类产品。这一技术突破不仅为Cellergy公司赢得了大量订单,还使其在电子行业中的地位得到了显著提升。随着技术的不断完善和市场的不断拓展,Cellergy公司逐渐成为了电容器领域的佼佼者。

General Diode Corp公司的发展小趣事
保护气体流量不足或漏气。

问答坊 | AI 解惑

1602LCD模块的几个疑问,请教各位了.

在论坛上看了几位高手的例子,下载了不得1602的资料和ICCAVR的代码,弄了一块1602回来,在双龙的SL-MEGA8板子上测试,但1602什么都不显示,现有几个问题请教; 1:1602是否已经自带了标准的字库,以至于我们向1602按一定的时序发送某个字符时,1602会自动 ...…

查看全部问答>

L298N的第1和15脚的具体用法和意义

最近看了L298N的数据手册,关于第1和15脚,上面说接一个检测电阻,可以用来作为过压的输出信号,从而起到保护芯片的作用。那位大虾知道的,说一下…

查看全部问答>

ActivateDeviceEx如何加载指定目录下的dll ?

ActivateDeviceEx加载驱动时是默认的windows\\目录下的DLL,这样需要DLL与内核一块打包成NK。 如何加载我应用程序目录下的dll ?这样可以使驱动程序和应用程序一块打包。…

查看全部问答>

flash擦除不了请看是什么问题

今天新做了个板 用jtag下载到擦flash时候过不去了 重新编了以后加入调试语句发现擦了flash的block 0后去判断status寄存器 得到的值是0x00a800a8 好象说供电不足 但是拿万用表量了一下Vpen得到3.3v 不懂是什么问题了,而且flash的id读到也对…

查看全部问答>

SRAM里的读出放大器问题

小弟是个菜鸟,不知道SRAM里的读出放大器电路是什么组成的?PC的cache里的放大器是什么组成的?一般书上的运算放大器可以吗?哪种的功耗比较低啊?谢谢!…

查看全部问答>

NDIS6.0的filter怎么丢包?

微软例子里的 VOID FilterSendNetBufferLists(         IN  NDIS_HANDLE        FilterModuleContext,         IN  PNET_BUFF ...…

查看全部问答>

单片机和嵌入式

我是从软件转到嵌入式的,最近在学习S3C2440(ARM9T),想自己写一个类似Uboot的程序,于是开始看芯片技术文档。发现看不懂,阅读uboot的原代码,那些芯片的配置也已经让我焦头烂额了,现在是举步维艰。还请高人给指条路。先谢过了。…

查看全部问答>

SLC nand flash 速度

SLC nand flash 最快速度可以达到多少啊? 可以是理论上的,单个plane,不是Micron那么多通道的???????????????…

查看全部问答>

EVC 窗口继承

为了保持窗口风格一致,并在编辑的时候更为方便。我想做一个模板窗口,让其它窗口都继承这个窗口的风格,如何实现?…

查看全部问答>

vs2005开发,怎样作为子窗体打开?

有子窗体吗? 没有的话,大家可以用什么方法代替子窗体?…

查看全部问答>