一、前言
中断是打断当前程序执行,快速响应突发事件的一种机制。中断的触发源有很多种,比如外部引脚电平变化以及外设的各种事件中断等等,当中断发生时,S3C2440 CPU的PC指针跳往固定的中断向量地址处,执行中断处理函数,之后再返回到原先的程序断点处继续执行程序。
二、实验目标
采用按键中断的方式,通过JZ2440开发板上的三个独立按键分别控制开发板上的三个LED的亮灭。
三、硬件连线
独立按键连线如下:
独立按键只用了三个,分别连接到了EINT0,EINT2,EINT11,即S3C2440的外部中断0,2和11。对应的真实物理引脚分别是GPF0,GPF2和GPG3。S3C2440的外部中断引脚不是随便选的,是定死了哪个引脚能用哪个外部中断的。这点上就比不上STM32这类单片机了,STM32是任意普通引脚都可以做外部中断的。而且STM32支持引脚功能的重映射,就是一个引脚上的各种功能可以映射到其他引脚上用,S3C2440貌似没看到有这个功能。又想了想,毕竟S3C2440是定位于跑操作系统的,和单片机的定位着重点不同,术业有专攻。
LED连线如下:
三个LED分别连接在GPF4,GPF5和GPF6上。
四、S3C2440中断体系
1、工作模式
ARM体系的CPU有以下7中工作模式:
(1)用户模式(usr):ARM处理器正常的程序执行状态。
(2)快速中断模式(fiq):用于高速数据传输或通道处理。
(3)中断模式(irq):用于通用的中断处理。
(4)管理模式(svc):操作系统使用的保护模式。
(5)数据访问终止模式(abt):当数据或指令预取终止时进入该模式,可用于虚拟存储即存储保护。
(6)系统模式(sys):运行具有特权的操作系统任务。
(7)未定义指令终止模式(und):当未定义的指令执行时进入该模式,可用于支持硬件协处理器的软件仿真。
以上的模式可通过软件来进行切换,发生各类中断的时候CPU也会自动进入相应的模式。除用户模式外,其他6种工作模式都属于特权模式。大多数程序运行于用户模式,进入特权模式是为了处理中断、异常、或者访问被保护的系统资源。
在S3C2440中,这些不同的模式都有一组寄存器(r0到r15,CPSR和SPSR)与各自模式相对应,这些寄存器有些是共用的,有些是某个模式下独有的(如上图带三角阴影的寄存器),虽然寄存器名字都一样,但只是该模式下使用。这些寄存器除r15外都是通用寄存器,其中r13到r15这3个寄存器有特殊的意义,r13称为栈指针寄存器(SP),就是C语言用到的那个堆栈指针;r14称为程序连接寄存器(subroutime Link Register)或连接寄存器,当执行汇编指令BL进行子程序跳转的时候,r14中会得到r15(程序计数器PC)的备份,当子程序返回的时候,r14(lr寄存器)的值会赋给r15(PC指针),这就使得程序能够回到断点位置继续向下执行了。
每个模式都有独立的r13和r14寄存器,即每个模式都有独立的堆栈指针(SP)和连接寄存器(lr)。在不同模式间跳转的时候,需要将上一个模式的所有公用寄存器进行压栈操作,以便在之后可以再出栈恢复这些寄存器的值,达到模式恢复的效果。其中快中断模式fiq从r8到r15都是独立的,在进入该模式的时候需要保存的寄存器数目更少(r0到r7),所以进入该中断会更快。
还有第17个寄存器CPSR,即“当前程序状态寄存器”(Current Program Status Register)。里面保存了各种状态位。如下:
这里挑几个重点说明:
(1)I位和F位:中断禁止位和快中断禁止位,当这些位置位时,CPU不响应这些中断。
(2)T位:置位时CPU处于Thumb状态,运行Thumb指令集;否则为ARM状态,运行ARM指令集,不同指令集这里不详细分析,在JZ2440上做实验基本都是用ARM指令集。
(3)M0到M4:工作模式位,表示CPU处于什么工作模式,修改这些位,可以使CPU进入对应的工作模式。
还有一个寄存器叫SPSR寄存器(Saved Program Status Register),功能是保存前一个工作模式的CPSR值,这样当要返回一个工作模式时,可以将SPSR的值恢复到CPSR中。
2、中断响应流程
有两类中断请求源:
(1)“Request sources(without sub register)”中的中断源被触发之后,SRCPND(中断请求状态)寄存器中相应位被置1,如果INTMSK(中断屏蔽控制)寄存器未将相应中断屏蔽的话,判断该中断是否是快速中断,如果且快速中断模式是使能的,CPU响应快速中断;如果是普通的中断,PRIORITY(IRQ优先级控制)寄存器的相应位被置1表示产生了该中断,之后INTPND(中断请求状态)寄存器挑出PRIORITY寄存器中的优先级最高的中断进行响应,注意,PRIORITY中可能标记了很多的中断需要处理,但是INTPND一次只挑出一个优先级最高的进行处理,在一个中断没处理完的时候,不响应其他的中断,
(2)“Request sources(with sub register)”这个中断源和(1)的区别可以理解为(1)的中断源是那些大模块比如DMA、定时器,串口等等的某个模块的总的中断请求,而串口模块又存在了RX或者TX中断,这些中断称为中断次级源。该类中断源发生时SUBSRCPND的相应位置位,如果SUBMASK的对应位没有置位来屏蔽这个中断,那么会引发SRCPND的对应位置位,之后的处理流程和(1)中一样。
注意点:
(1)S3C2440的快速中断(fiq)可以打断普通中断(irq),反之不行,普通中断不可以打断普通中断,快速中断也不可以打断快速中断,快速中断(fiq)只能设置一个,即不存在中断嵌套。快速中断(fiq)不引起INTPND和INTOFFSET寄存器的变化,所以这两个寄存器只在IRQ中断中有效。
(2)SUBSRCPND、SRCPND、PRIORITY、INTPND中相应位被置位后,CPU响应了对应的中断过后并不会自动清除这些位,所以需要我们在程序中人为清除对应的位,清除的方法是往对应位写1清除,简单的写法是“INTPND = INTPND”不清除的话该次中断结束之后会立刻进入相同的中断。
(3)不论SUBMASK或者MASK寄存器的相应位有没有置位屏蔽,只要产生了对应的中断,中断请求状态寄存器中都会置位表示有这个中断产生了,上不上报是后续流程的事。
(4)fiq中断由于只能设置一个,一旦产生用户就必定知道是哪个中断源引发的。irq中断有很多个,可以通过读取INTPND寄存器或者INTOFFSET寄存器来确定中断源。
3、中断优先级
S3C2440的中断优先级设置是要遵循固定的模式的,并不像STM32那样可以随意设置。这里的中断优先级设置只是对IRQ中断而言的,FIQ中断不受这个规则限制。
中断优先级通过7个仲裁器完成(ARBITER0到ARBITER6),包括6个一级仲裁器(ARBITER0到ARBITER5)和1个二级仲裁器(ARBITER6),说白了就是二级仲裁器从6个一级仲裁器中挑一个优先级最高的中断报上去给CPU处理,其中REQ0和QEQ5的优先级顺序是固定的,一个最高,一个最低,REQ1到REQ4可以通过配置更改它们的内部优先级顺序,下面贴上一张PRIORITY寄存器的定义表来说明:
通过设置ARB_SELn可以设置REQ1到REQ4的内部顺序,通过设置ARB_MODEn可以设置是否需要自动更改排序,就是处理完该组的一次中断请求后,把对应ARB_SELn的值加1取余4,自动轮换一下优先级顺序。为什么要搞个这个功能呢?我猜应该是解决某些中断长期占用导致另外一些中断难以响应的问题,试想一下如果开始优先级是REQ1到REQ4,用户把这四个中断同等重要来看待,然后REQ1有个中断一直都有请求,REQ2这时也来了个中断请求,但是由于REQ1优先级更高霸占了中断请求的处理资源,然后REQ2就一直得不到响应了。
接下来还是要提一点,REQ0到REQ5的优先级顺序只有4种排列方式,个人感觉还是不太灵活,能像STM32那样自由配置就好了。
4、中断处理代码
在进入或者退出中断时需要保存和恢复程序的运行环境。示例代码如下:
(1)IRQ中断,进入和退出的代码如下:
sub lr, lr, #4 @计算返回地址
stmdb sp!, {r0-r12,lr} @保存使用到的寄存器
... ... @处理中断
ldmia sp!, {r0-r12,pc}^ @中断返回
@^表示将spsr的值赋给cpsr,恢复之前的工作模式
(2)FIQ中断,进入和退出的代码如下:
sub lr, lr, #4 @计算返回地址
stmdb sp!, {r0-r7,lr} @保存使用到的寄存器
... ... @处理快速中断
ldmia sp!, {r0-r7,pc}^ @中断返回
@^表示将spsr的值赋给cpsr,恢复之前的工作模式
五、代码编写
接下来是具体的实验代码,分为以下几个文件:
head.S:启动文件。
main.c:初始化及各种C函数。
Makefile:编译代码。
各个文件的具体内容如下:
head.S
@*************************************************************************
@ File:head.S
@*************************************************************************
.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 HandleFIQ
Reset:
ldr sp, =4096 @设置堆栈,因为要调用C语言函数
bl disable_watch_dog @关WATCH DOG
msr cpsr_c, #0xd2 @ 进入中断模式
ldr sp, =3072 @ 设置中断模式栈指针
msr cpsr_c, #0xd3 @ 进入管理模式
ldr sp, =4096 @ 设置管理模式栈指针,
@ 其实复位之后,CPU就处于管理模式,
@ 前面的“ldr sp, =4096”完成同样的功能,此句可省略
bl init_led @ 初始化LED的GPIO管脚
bl init_irq @ 调用中断初始化函数
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 @ 调用中断服务函数
int_return:
ldmia sp!, { r0-r12,pc }^ @ 中断返回, ^表示将spsr的值复制到cpsr
main.c
#define BYTE unsigned char
#define WORD unsigned short
#define DWORD unsigned int
/* WOTCH DOG register */
#define REG_WTCON (*(volatile unsigned long *)0x53000000)
/* GPIO Configure*/
#define GPFCON (*(volatile unsigned long *)0x56000050)
#define GPFDAT (*(volatile unsigned long *)0x56000054)
#define GPFUP (*(volatile unsigned long *)0x56000058)
#define GPGCON (*(volatile unsigned long *)0x56000060)
#define GPGDAT (*(volatile unsigned long *)0x56000064)
#define GPGUP (*(volatile unsigned long *)0x56000068)
#define REG_EXTINT0 (*(volatile unsigned long *)0x56000088)
#define REG_EXTINT1 (*(volatile unsigned long *)0x5600008C)
/* interrupt Configure */
#define REG_EINTMASK (*(volatile unsigned long *)0x560000A4)
#define REG_INTMSK (*(volatile unsigned long *)0X4A000008)
#define REG_INTOFFSET (*(volatile unsigned long *)0x4A000014)
#define REG_EINTPEND (*(volatile unsigned long *)0x560000A8)
#define REG_SRCPND (*(volatile unsigned long *)0X4A000000)
#define REG_INTPND (*(volatile unsigned long *)0X4A000010)
// #define REG_INTSUBMSK (*(volatile unsigned long *)0x560000A8)
// #define REG_SUBSRCPND (*(volatile unsigned long *)0X4A000018)
void disable_watch_dog();
void init_led();
void init_irq();
void EINT_Handle();
/*上电后,WATCH DOG默认是开着的,要把它关掉 */
void disable_watch_dog()
{
REG_WTCON = 0;
}
void init_led()
{
GPFCON &= ~((DWORD)(3 << (2 * 4)) | (3 << (2 * 5)) | (3 << (2 * 6)));
GPFCON |= ((DWORD)(1 << (2 * 4)) | (1 << (2 * 5)) | (1 << (2 * 6))); //GPF4、GPF5、GPF6输出模式
GPFDAT |= (1 << 4) | (1 << 5) | (1 << 6); //输出高电平,LED全灭
}
void init_irq()
{
//配置为外部中断模式
GPFCON &= ~((DWORD)(3 << (2 * 0)) | (3 << (2 * 2)));
GPFCON |= ((DWORD)(2 << (2 * 0)) | (2 << (2 * 2)));
GPGCON &= ~((DWORD)(3 << (2 * 3)));
GPGCON |= ((DWORD)(2 << (2 * 3)));
//上拉
GPFUP |= (1 << 0) | (1 << 2);
GPGUP |= (1 << 3);
//设置下降沿触发
REG_EXTINT0 &= ~((DWORD)(7 << 0) | (7 << 8));
REG_EXTINT0 |= ((DWORD)(2 << 0) | (2 << 8));
REG_EXTINT1 &= ~((DWORD)(7 << 12));
REG_EXTINT1 |= ((DWORD)(2 << 12));
//使能EINT11中断
REG_EINTMASK &= ~((DWORD)1<<11);
//使能EINT0、EINT2、EINT11中断
REG_INTMSK &= ~((DWORD)(1 << 0) | (1 << 2) | (1 << 5));
}
void EINT_Handle()
{
BYTE bIntOffset = REG_INTOFFSET;
switch(bIntOffset)
{
case 0:
GPFDAT ^= ((DWORD)1 << 4); //电平翻转
上一篇:S3C2440裸机实验之timer(定时器)
下一篇:ARM中断基础知识
推荐阅读
史海拾趣
为了进一步加强对大陆市场的投资和管控,Bytesonic Corporation在1998年5月在英属维尔京群岛成立了控股公司——剑桥电子有限公司。这一举措不仅提升了公司的资本运作能力,也为其在全球范围内的业务拓展提供了更多的便利。
为了进一步扩大市场份额和影响力,CNC Tech公司积极实施全球化战略。公司通过参加国际展会、设立海外分支机构等方式,加强与全球客户的交流与合作。同时,CNC Tech还积极引进国际先进的技术和管理经验,不断提升自身的竞争力。在全球化战略的推动下,CNC Tech的产品和服务逐渐打入国际市场,赢得了全球客户的认可和信赖。
随着科技的不断发展,电子行业面临着日新月异的技术变革。为了保持竞争优势,双岭电子始终坚持创新驱动的发展理念。公司投入大量资金用于研发新技术、新产品,并鼓励员工提出创新性的想法和建议。通过不断的创新实践,双岭电子成功推出了MOS型场效应晶体管和CMOS集成电路等高端产品,进一步巩固了公司在行业中的领先地位。
企业文化是企业的灵魂和精神支柱。创都公司自创立之初就注重企业文化的建设与发展。他们倡导“创新、协作、务实、进取”的企业精神,鼓励员工勇于创新、敢于担当。同时,公司还注重员工培训和职业发展规划的制定与实施,为员工提供了广阔的发展空间和良好的职业前景。这些措施不仅激发了员工的积极性和创造力还增强了企业的凝聚力和向心力使得创都公司在激烈的市场竞争中始终保持着旺盛的发展势头。
企业文化是企业的灵魂和精神支柱。创都公司自创立之初就注重企业文化的建设与发展。他们倡导“创新、协作、务实、进取”的企业精神,鼓励员工勇于创新、敢于担当。同时,公司还注重员工培训和职业发展规划的制定与实施,为员工提供了广阔的发展空间和良好的职业前景。这些措施不仅激发了员工的积极性和创造力还增强了企业的凝聚力和向心力使得创都公司在激烈的市场竞争中始终保持着旺盛的发展势头。
1958年,Eagle-Picher公司的电池技术得到了重大的突破。在美国宇航局的探索者1号卫星上,Eagle-Picher的电池成功发射到太空,为卫星的运行提供了稳定的电源。这一里程碑式的事件标志着Eagle-Picher的电池技术在太空探索领域的应用达到了新的高度,也为公司赢得了更多的科研和商业机会。
我在12年前,偶然接触PLD,没有想到自己居然就在这个行当里安身下来。可是这个行业也的确是个飞速发展的行业,十多年过去后,从当初的接近十家主要供应商,到今天已经激烈搏杀后,只有差不多如论坛题目一样的,成为了今天三足鼎立的局面。想来想去, ...… 查看全部问答∨ |
|
一些公司IC设计方向面试题1、我们公司的产品是集成电路,请描述一下你对集成电路的认识,列举一些与集成电路 相关的内容(如讲清楚模拟、数字、双极型、CMOS、MCU、RISC、CISC、DSP、ASIC、FPGA 等的概念)。(仕兰微面试题目) 2、FPGA和ASIC的 ...… 查看全部问答∨ |
|
将自作的USB虚拟串口设备插入计算机后,计算机提示安装设备驱动,找到STM32 Virtual COM Port,但我刚在ST网站上下 ...… 查看全部问答∨ |
|
从信号发生器输出的一个正弦信号,通过什么方法能将其导入MIC接口,作为输入信号,将信号在ARM6410上编写的一个android的模拟示波器上显示出来。求知道的大侠们帮我一下 感激不尽!!… 查看全部问答∨ |
最近学习单片机编译器,但是却一直未能找到完整的c51的grammar file 。求大神分享!!(flex&bison描述的最好)预先谢谢大家啦… 查看全部问答∨ |