学习bootloader制作的过程中,学到 “通过按键进入中断控制LED亮灭”的实验时,自己所用的开发板和视频讲解中的不同,于是琢磨了一下中断涉及到的各个寄存器,并进行编码尝试,最终完成了实验,达到了通过按键以中断方式控制LED亮灭的目的。2440属于非向量中断方式,和6410、210的向量中断方式对于中断的处理有一些不同,因此本文的讲解并不完全适合6410和210。
一、概念
中断分为两大类:外部中断和内部中断。
1、外部中断:S3C2440的24个外部中断占用GPF0~GPF7(EINT0~EINT7)、 GPG0~GPG15(EINT8~EINT23)。使用这些引脚作为中断输入时,必须将引脚配置为EINT模式,配置方法可参考datasheet。
2、内部中断:内部中断包括DMA中断、UART中断、IIC中断等等由内部外设触发的中断。
3、相关寄存器:S3C2440中断控制涉及到10个寄存器-- SRCPND、INTMOD、INTMSK、PRIORITY、INTPND、INTOFFSET、SUBSRCPND、INTSUBMSK、EINTMASK、EINTPEND,这10个寄存器的定义及其功能描述如下表一。对中断的控制无外乎配置和处理这10个寄存器中的某几个。
表一 与S3C2440中断相关的10个寄存器的信息
4、各寄存器的关系(工作流程)。根据中断源进行分类,中断的处理流程可用下图1表示:
图1 S3C2440中断处理流程图
由上图1可知,S3C2440的中断可分为四种情况:由外部中断源(EINT0~EINT3)触发的中断、由外部中断子中断源(EINT4~EINT23)触发的中断、由内部中断源(内部子中断)触发的中断和由内部中断源(非子中断)触发的中断。
5、中断的开启(中断初始化,INTMOD 和 PRTORITY使用默认值)
(a)如果是外部中断(EINT0~EINT3)和内部中断(不带子中断),需设置INTMSK,让它不屏蔽中断即可;
(b)如果是带子中断的内部中断,需设置INTSUBMSK 和 INTMSK,让它们不屏蔽中断即可;
(c)如果是外部中断(EINT4~EINT23),需设置EINTMASK 和 INTMSK,让它们不屏蔽中断即可;
注意:CPSR中的第7位I也需清除(在start.S中关闭了中断,这一步是针对在bootloader设计中进行EINT实验时的操作)
6、中断处理流程
(a)如果是外部中断(EINT0~EINT3)和 不带子中断的内部中断,发生中断后SRCPND相应位置1,如果没有被 INTMSK屏蔽,那么等待进一步处理;
(b)如果是带子中断的内部中断,发生中断后SUBSRCPND相应位置1,如果没有被INTSUBMSK屏蔽,则SRCPND相应位置1,如果没有被INTMSK屏蔽,那么等待进一步处理;
(c)如果是外部中断(EINT4~EINT23),发生中断后EINTPEND相应位置1,如果没有被EINTMASK屏蔽,则SRCPND相应位EINT4-7和EINT8~23置1,如果没有被INTMSK屏蔽,那么等待进一步处理;
三种中断都等待进一步处理了,接下来从SRCPND继续往前看,看看INTMSK,如果中断被屏蔽了,就不用说了(注意:快中断也能被屏蔽)。如果没有被屏蔽,那么会进一步到INTMOD。如果是快中断,那么直接出来,进入FIQ(即CPU进入快中断模式处理)。如果是普通中断,那么SRCPND可以有多位置1(FIQ只能有一个),这时就会经过PRIORITY选出一个优先级高的,然后根据选出的中断把INTPND相应位置1(注意:只能选出一个),进入IRQ,让CPU处理。
INTOFFSET寄存器用来表示INTPND中哪一位置1了,可以用来判断请求中断的中断源,但是,对于外部中断EINT4~EINT23是无法判断的,如EINT4~EINT7中任何一个中断源请求中断,都会将INTOFFSET中的位EINT4_7置1,所以要判断具体是哪个中断源请求的中断,可读取EINTPEND中的值进行判断。
7、中断的清除
(a)如果是外部中断EINT0~EINT3 和不带子中断的内部中断,只需清除SRCPND(注意:清除时对相应位写“1”);
(b)如果是带子中断的内部中断,需清除SRCPND和SUBSRCPND,注意先清除SUBSRCPND,再清除SRCPND。因为如果先清除SRCPND的话,在清除SUBSRCPND的过程中,SRCPND会以为又有中断发生,又会置1,也就是说一次中断会响应两次,所以必须先掐断源头,对它们同样是写“1”清除
(c)如果是外部中断EINT4~EINT23,需清除EINTPEND和SRCPND(同样注意顺序),写“1”清除。
二、按键中断实验
1、所使用开发板的按键与芯片连接示意如下图2,其中KEY1 --> GPF4, KEY2--> GPF5,KEY3 --> GPF6,KEY4 --> GPF7。
图2 按键与S3C2440连接示意
通过查阅s3c2440的datasheet可知,GPF4~GPF7对应外部中断EINT4~EINT7。所以对于中断初始化,需设置寄存器EINTMASK和INTMSK,取消中断屏蔽。中断处理过程中,可通过阅读EINTPEND寄存器的值判定触发中断的中断源。中断清除时,向EINTPEND和SRCPND中相应位写“1”,清除中断(注意顺序)。以下为实验的源代码:
/*interrupt registes*/
#define SRCPND (volatile unsigned long *)0x4a000000 //Interrupt request status
#define INTMOD (volatile unsigned long *)0x4a000004 //Interrupt mode control
#define INTMSK (volatile unsigned long *)0x4a000008 //Interrupt mask control
#define PRIORITY (volatile unsigned long *)0x4a00000c //IRQ priority control
#define INTPND (volatile unsigned long *)0x4a000010 //Interrupt request status
#define INTOFFSET (volatile unsigned long *)0x4A000014 //Interrupt request source offset
#define SUBSRCPND (volatile unsigned long *)0x4A000018 //Sub source pending
#define INTSUBMSK (volatile unsigned long *)0x4A00001c //Interrupt sub mask
#define EINTMASK (volatile unsigned long *)0x560000a4 //External interrupt mask register
#define EINTPEND (volatile unsigned long *)0x560000a8 //External interrupt pending register
/*******************************************************************
*函数名称:init_irq()
*功能描述:中断初始化(取消中断屏蔽)
*其他说明:按键中断对应的是外部中断EINT4~7,所以设置EINTMASK、INTMSK
*修改日期 版本号 修改人 修改内容
*------------------------------------------------------------------
*2015.12.5 V1.0
*******************************************************************/
void init_irq()
{
*(EINTMASK) &= ((~(1 << 4)) & (~(1 << 5)) & (~(1 << 6)) & (~(1 << 7))); //取消EINT4~7的子中断屏蔽(注意,这步必须在后面一步之前)
*(INTMSK) &= (~(1 << 4)); //取消EINT4~7的中断屏蔽
/***清除CPSR寄存器中的第7位I(IRQ disable),因为在start.S中关闭了中断****/
__asm__(
"mrs r0, cpsrn"
"bic r0, r0, #0x80n"
"msr cpsr_c, r0n"
:
:
);
}
/*******************************************************************
*函数名称:handle_int()
*功能描述:中断处理函数
*其他说明:
*修改日期 版本号 修改人 修改内容
*------------------------------------------------------------------
*2015.12.6 V1.0
*******************************************************************/
void handle_int()
{
/*判断产生中断的中断源*/
unsigned long value = *(INTOFFSET);
unsigned long value_offset = *(EINTPEND); //value_offset的值分别对应EINT4~EINT7
if (4 == value) //value = 4 表明EINT4 ~ EINT7请求中断 (这个条件不是必须的,可直接判断value_offset)
{
switch (value_offset)
{
case 0x00000010 : //EINT4 --> k1
led_on();
break;
case 0x00000020 : //EINT5 --> k2
led_on();
break;
case 0x00000040 : //EINT6 --> k3
led_off();
break;
case 0x00000080 : //EINT7 --> k4
led_off();
break;
default :
break;
}
}
/*清除中断标志*/
*(EINTPEND) = value_offset; //把EINTPEND中当前值重新赋给EINTPEND,即相当于对相应位置1清除(不过这
//样做的前提是可以明确只发生一个中断,不然有可能将其他的中断请求清除)
*(INTPND) = 1 << 4;
}
上一篇:Jlink调试2440进不了中断的看这里
下一篇:uboot-2011.12移植到S3C2440(三序)——MMU Cache/TLB/etc on/off functions
- 热门资源推荐
- 热门放大器推荐
设计资源 培训 开发板 精华推荐
- ESP32-CAM-WEB摄像头
- 使用符合 EN50121-3-2 标准的带有 EMC 滤波的 RP40-4805SFR DC/DC 转换器的典型应用(单输出)
- 黄淮学院创客空间立创杯电子设计大赛-刘向强-1002040A
- MAXREFDES1172:采用MAX17690的90%效率的小尺寸12V / 1A无光反激式DC-DC转换器
- BU4845电压检测IC BU48xx系列典型应用电路
- EVAL-ADM1065TQEB,评估 ADM1065ASU 电压监控器排序器的评估板
- LTC2172IUKG-12、12 位、65Msps 低功耗四通道 ADC 的典型应用电路
- RD-501,将 FAN5236 电流模式 PWM 控制器用于 DC-DC 电源应用的参考设计
- LTC3529 的典型应用 - 采用 2mm 3mm DFN 封装的 1.5A、1.5MHz 升压型 DC/DC 转换器
- LTC1261CS8-4 1mV 纹波、5V 输入、-4V 输出 GaAs FET 偏置发生器的典型应用电路
- USB Type-C® 和 USB Power Delivery:专为扩展功率范围和电池供电型系统而设计
- 景昱医疗耿东:脑机接口DBS治疗技术已实现国产替代
- 首都医科大学王长明:针对癫痫的数字疗法已进入使用阶段
- 非常见问题解答第223期:如何在没有软启动方程的情况下测量和确定软启动时序?
- 兆易创新GD25/55全系列车规级SPI NOR Flash荣获ISO 26262 ASIL D功能安全认证证书
- 新型IsoVu™ 隔离电流探头:为电流测量带来全新维度
- 英飞凌推出简化电机控制开发的ModusToolbox™电机套件
- 意法半导体IO-Link执行器电路板为工业监控和设备厂商带来一站式参考设计
- Melexis采用无磁芯技术缩小电流感测装置尺寸
- 千丘智能侍淳博:用数字疗法,点亮“孤独症”儿童的光