2440裸机编程之四 外部中断

2019-11-08来源: 51hei关键字:2440  裸机编程  外部中断

2440有60个中断源(有的中断源还有几个子中断源),中断原理如下图:



中断源使中断源请求寄存器(SRCPND)的相应位置一,中断模式寄存器(INTMOD)选择是IRQ还是FIQ模式,如果是IRQ,在中断屏蔽寄存器(INTMSK)不屏蔽的情况下,会产生中断,同时中断请求寄存器(INTPND)的相应位被置一。


2440 外部中断 编程步骤:
外部中断初始化()
{
引脚初始化: 设置相应引脚为外部中断功能 GPxCON
  选择相应触发模式    EXTINT

中断初始化: 清除SRCPNF、INTPND中的相应中断标志位
  中断例程地址 -> 中断向量表 pISR_EINTx
  使能相应中断 rINTMSK
}


中断例程()  __irq
{
  ……中断程序……
  清除SRCPNF(先)、INTPND(后)中的相应中断标志位
}


这是一个外部中断0的实验程序(GPF0作外部中断源):
//********************************************************************
void Main(void)
{     
    int i;
    ……硬件初始化……

Eint0_init();
while(1);

}

void  Eint0_init(void)  //EINT0初始化
{
Uart_Printf("n外部中断实验:Eint0n"); 
rGPFCON = rGPFCON & ~7 |  2  ; //设置GPF0 为 外部中断模式
rEXTINT0 = rEXTINT0 & ~7 | 2   ;//设置EINT0 为 下降沿触发

rSRCPND = 1;     //SRCPND写1清0
rINTPND = 1;     //INTPND写1清0
pISR_EINT0 = (U32)Eint0_ISR; //向向量表申请中断向量
rINTMSK = rINTMSK & ~(1);  //禁止EINT0的屏蔽
}


void   Eint0_ISR(void) __irq  //EINT0中断例程
{
Uart_Printf("你按了一次Eint0引脚的按键n"); 
rSRCPND = 1;  //清楚EINT0中断标志
rINTPND = 1; 
}

//*******************************************************************


运行结果如图:




注意中断标志的清除顺序:SUBSRCPND(如果有)->SRCPND->INTPND  ,如果不这样做,中断例程结束后,还会再次引起额外的中断
注意 pISR_EINT0 = (U32)Eint0_ISR;每一个中断例程运行之前,都要把它的地址交给中断向量表(此指60个中断源的eboot中断向量表,非地址0处的异常中断向量表,IRQ发生时,PC先指向异常中断向量表的IRQ位置,再跳转到eboot中断向量表),以在中断发生时,正确进入相应的中断例程,其实是把INTOFFSET中的中断号转换成(在eboot中断向量表的)偏移地址。




外部中断又24个,但不都是一致的,如下图:

EINT0、EINT1、EINT2、EINT3是四个独立的中断源,而EINT4~7组成一个中断源,EINT8~23组成一个中断源。
那么EINT4~7的中断程序如何写,显然不能用EINT0的方式,不然EINT4~EINT7的四个源相互之间无法被区分开,EINT8~23也同理。
所以为了区分它们,要用到EINTMASK和EINTPEND,EINTMASK每一位对应EINT4~EINT23的屏蔽,其他位保留;EINTPEND每一位对应EINT4~EINT23的中断请求,其他位保留;这样就可以顺利区分EINT4~EINT23了。


下面是Eint2和Eint11的中断程序
//********************************************************************
void Main(void)
{     
    int i;
    ……硬件初始化……

Uart_Printf("n外部中断实验:Eint2 和 Eint8_23n");

Eint2_init();
Eint8_23_init(); //EINT11初始化
while(1);

}

void  Eint2_init(void)  //EINT2初始化
{
rGPFCON = rGPFCON & ~3<<4 |  2<<4  ; //设置GPF2 为 外部中断模式
rEXTINT0 = rEXTINT0 & ~7<<8 | 4<<8   ;//设置EINT2 为 上升沿触发
rSRCPND = 1<<2;     //SRCPND写1清0
rINTPND = 1<<2;     //INTPND写1清0
pISR_EINT2 = (U32)Eint2_ISR;  //填入Eint2的中断向量
rINTMSK = rINTMSK & ~(1<<2);  //禁止EINT2的屏蔽
}


void   Eint2_ISR(void) __irq  //EINT2中断例程
{
Uart_Printf("你按了一次Eint2引脚的按键n"); 
rSRCPND = 1<<2;  //清楚EINT2中断标志
rINTPND = 1<<2;
}


void  Eint8_23_init(void)  //Eint8_23初始化
{
rGPGCON = rGPGCON & ~3<<6 |  2<<6  ; //设置GPG3 为 外部中断模式
rEXTINT1 = rEXTINT1 & ~7<<12 | 2<<12   ;//设置EINT11 为 下降沿触发
rEINTPEND = 1<<11;    //***EINTPEND中的 EINT11位 清0
rSRCPND = 1<<5;     //SRCPND中的 Eint8_23位 清0
rINTPND = 1<<5;     //INTPND中的 Eint8_23位 清0
pISR_EINT8_23 = (U32)Eint8_23_ISR;  //填入Eint8_23的中断向量
rEINTMASK = rEINTMASK & ~(1<<11);  //***禁止EINT11的屏蔽
rINTMSK = rINTMSK & ~(1<<5);  //禁止Eint8_23的屏蔽
}


void   Eint8_23_ISR(void) __irq  //EINT2中断例程
{
Uart_Printf("你按了一次Eint8_23引脚的按键n");
rEINTPEND = 1<<11;    //***EINTPEND中的 EINT11位 清0
rSRCPND = 1<<5;     //SRCPND中的 Eint8_23位 清0
rINTPND = 1<<5;     //INTPND中的 Eint8_23位 清0
}

//*******************************************************************


结果如下:


关键字:2440  裸机编程  外部中断 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic479390.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:S3C2410启动代码从ADSv1.2移植到KEIL For ARM uV4的方法
下一篇:2440裸机编程之三 通用I/O口

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

重拾MINI2440板子,各种问题,小结
注意:下载SUPERVIVI后,如果SUPERVIVI运行成功,现象是:       LED1:闪烁       LED2:熄灭       LED3:常亮       LED4:熄灭    1:JLINK连接后,为什么要使用它内部的SRAM?    JLink 的调试功能、烧写Flash 的功能都很强大,但是对于S3C2410、S3C2440 的Flash 操作有些麻烦:烧写Nor Flash 时需要设置SDRAM
发表于 2019-11-20
重拾MINI2440板子,各种问题,小结
platform驱动模型编程总结(基于mini2440平台的LED驱动)
,那么总线会立即匹配与绑定这时的同名的设备与驱动,再调用驱动中的probe函数等;如果是驱动先注册,同设备驱动一样先会匹配失败,匹配失败将导致它的probe函数暂不调用,而是要等到设备注册成功并与自己匹配绑定后才会调用。接下来讲解如下实现platform驱动与设备的详细过程。实现platform驱动的详细过程1:定义驱动实例 mini2440_led_platform_driver static struct platform_driver mini2440_led_platform_driver = {.probe  = mini2440
发表于 2019-11-19
platform驱动模型编程总结(基于mini2440平台的LED驱动)
u-boot-1.3.4 移植到S3C2440
一.预备知识:1. 首先,U-Boot1.3.4还没有支持s3c2440,移植仍是用2410的文件稍作修改而成的。2. 2440和2410的区别:2440和2410的区别主要是2440的主频更高,增加了摄像头接口和AC‘97音频接口;寄存器方面,除了新增模 块的寄存器外,移植所要注意的是NAND FlASH控制器的寄存器有较大的变化、芯片的时钟频率控制寄存器(芯片PLL的寄存器)有一定的变化。其他寄存器基本是兼容的。3. 你开发板的boot方式是什么,开发板上电以后是怎么执行的。一般来说三星的开发板有三种启动方式:nand、nor、ram。具体用那一种方式来启动决定于CPU的0M[0:1]这两个引脚,具体请参考S3C2440
发表于 2019-11-18
S3C2440中断过程详解(ADS,TQ2440)
下面以串口UART0接收中断为例:串口接收中断初始化时有这么一句:pISR_UART0=(unsigned)__irq UART0 _GetInt   /把 UART0 _GetInt这个中断服务子程序的入口地址放到pISR_TICK,S3C2440addr.h中#define pISR_UART0  (*(unsigned *)(_ISR_STARTADDRESS+0x90)) option.inc中_ISR_STARTADDRESS EQU 0x33ffff00 //也就是中断服务子程序的入口地址放到0x33ffff00+0x90这个地址单元,即放入相应的中断向量表中,当中断
发表于 2019-11-18
S3C2440中断过程详解(ADS,TQ2440)
2440裸机编程之二 C语言调用汇编语言编程
;***************************************************过程说明:main调用n = test(2,4,6),使2、4、6分别通过R0、R1、R2传递给汇编函数test,然后test调用C程序add,R0、R1、R2分别传给a、b、c,然后求和结果用R0返回test,test又将R0返回main函数,所以最后 n = 12;如图:注意汇编程序中IMPORT和EXPORT的用法:IMPORT add:进口,指add在外部文件中,当前文件要调用EXPORT test:出口,指test在当前文件中,可以给外部文件调用同样在C文件中,如果要调用外部文件,使用extern关键字申明函数,如:extern
发表于 2019-11-18
2440裸机编程之二 C语言调用汇编语言编程
2440裸机编程之一 C语言调用汇编语言编程
一、内嵌汇编的方式,使用关键字__asm{汇编指令……},这种方式操作简单,但是限制很多,比如:不能写PC、不支持标号表达式等等,许多正常的汇编指令和伪指令都不用。下面是个例子://******************************************int x = 3;int y = 5;int z;int main(void){__asm{  MOV R0,x  MOV R1,y  ADD R0,R0,R1  MOV z,R0}while(1);}//******************************************结
发表于 2019-11-18
2440裸机编程之一 C语言调用汇编语言编程
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved