要想正确地碑文2440的外部中止,一般需求完结两个部分内容:中止初始化和中止处理函数。
在详细碑文中止之前,要初始化好要用的中止。2440的外部中止引脚EINT与通用IO引脚F和G复用,要想运用中止功用,就要把相应的引脚装备成中止形式,如咱们想把端口F0设置成外部中止,而其他引脚功用不变,则GPFCON=(GPFCON & ~0x3) | 0x2。装备完引脚后,还需求装备详细的中止功用。咱们要翻开某一中止的屏蔽,这样才干响应该中止,相对应的寄存器为INTMSK;还要设置外部中止的触发方法,如低电平、高电平、上升沿、下降沿等,相对应的寄存器为EXTINTn。别的咱们EINT4到EINT7共用一个中止向量,EINT8到EINT23也共用一个中止向量,而INTMSK只担任总的中止向量的屏蔽,要详细翻开某一详细的中止屏蔽,还需求设置EINTMASK。上面介绍的是最基本的初始化,当然还有一些其他的装备,如当需求用到快速中止时,要运用INTMOD,当需求装备中止优先级时,要运用PRIORITY等。
中止处理函数担任碑文详细的中止指令,除此以外还需求把SRCPND和INTPND中的相应的位清零(经过置1来清零),咱们当中止产生时,2440会主动把这两个寄存器中相对应的方位1,以一共某一中止产生,假如不在中止处理函数内把它们清零,体系会一向碑文该中止函数。别的仍是咱们前面介绍过的,有一些中止是共用一个中止向量的,而一个中止向量只能有一个中止碑文函数,因而详细是哪个外部中止,还需求EINTPEND来判别,并相同还要经过置1的方法把相应的位清零。一般来说,运用__irq这个关键词来界说中止处理函数,这样体系会为咱们主动保存一些必要的变量,并能够在中止处理函数碑文完后正确地回来。还需求注意的是,中止处理函数不能有回来值,也不能传递任何参数。
为了把这个中止处理函数与在2440发动文件中界说的中止向量表相对应上,需求先界说中止进口地址变量,该中止进口地址有必要与中止向量表中的地址共同,然后把该中止处理函数的首地址传递给该变量,即中止进口地址。
下面便是一个外部中止的实例。开发板上一共有四个按键,别离连到了EINT0,EINT1,EINT2和EINT4,咱们让这四个按键别离操控连接在B5~B8引脚上的四个LED:按一下键则LED亮,再按一下则灭:
#define _ISR_STARTADDRESS 0x33ffff00
#define U32 unsigned int
#define pISR_EINT0(*(unsigned *)(_ISR_STARTADDRESS+0x20))
#define pISR_EINT1(*(unsigned *)(_ISR_STARTADDRESS+0x24))
#define pISR_EINT2(*(unsigned *)(_ISR_STARTADDRESS+0x28))
#define pISR_EINT4_7(*(unsigned *)(_ISR_STARTADDRESS+0x30))
#define rSRCPND(*(volatile unsigned *)0x4a000000)//Interrupt request status
#define rINTMSK(*(volatile unsigned *)0x4a000008)//Interrupt mask control
#define rINTPND(*(volatile unsigned *)0x4a000010)//Interrupt request status
#define rGPBCON(*(volatile unsigned *)0x56000010)//Port B control
#define rGPBDAT(*(volatile unsigned *)0x56000014)//Port B data
#define rGPBUP(*(volatile unsigned *)0x56000018)//Pull-up control B
#define rGPFCON(*(volatile unsigned *)0x56000050)//Port F control
#define rEXTINT0(*(volatile unsigned *)0x56000088)//External interrupt control register 0
#define rEINTMASK(*(volatile unsigned *)0x560000a4)//External interrupt mask
#define rEINTPEND(*(volatile unsigned *)0x560000a8)//External interrupt pending
static void __irq Key1_ISR(void) //EINT1
{
int led;
rSRCPND = rSRCPND | (0x1<<1);
rINTPND = rINTPND | (0x1<<1);
led = rGPBDAT & (0x1<<5);
if (led ==0)
rGPBDAT = rGPBDAT | (0x1<<5);
else
rGPBDAT = rGPBDAT & ~(0x1<<5);
}
static void __irq Key2_ISR(void) //EINT4
{
int led;
rSRCPND = rSRCPND | (0x1<<4);
rINTPND = rINTPND | (0x1<<4);
if(rEINTPEND&(1<<4))
{
rEINTPEND = rEINTPEND | (0x1<<4);
led = rGPBDAT & (0x1<<6);
if (led ==0)
rGPBDAT = rGPBDAT | (0x1<<6);
else
rGPBDAT = rGPBDAT & ~(0x1<<6);
}
}
static void __irq Key3_ISR(void) //EINT2
{
int led;
rSRCPND = rSRCPND | (0x1<<2);
rINTPND = rINTPND | (0x1<<2);
led = rGPBDAT & (0x1<<7);
if (led ==0)
rGPBDAT = rGPBDAT | (0x1<<7);
else
rGPBDAT = rGPBDAT & ~(0x1<<7);
}
void __irq Key4_ISR(void) //EINT0
{
int led;
rSRCPND = rSRCPND | 0x1;
rINTPND = rINTPND | 0x1;
led = rGPBDAT & (0x1<<8);
if (led ==0)
rGPBDAT = rGPBDAT | (0x1<<8);
else
rGPBDAT = rGPBDAT & ~(0x1<<8);
}
void Main(void)
{
int light;
rGPBCON = 0x015550;
rGPBUP = 0x7ff;
rGPFCON = 0xaaaa;
rSRCPND = 0x17;
rINTMSK = ~0x17;
rINTPND =0x17;
rEINTPEND = (1<<4);
rEINTMASK = ~(1<<4);
rEXTINT0 = 0x20222;
light = 0x0;
rGPBDAT = ~light;
pISR_EINT0 = (U32)Key4_ISR;
pISR_EINT1 = (U32)Key1_ISR;
pISR_EINT2 = (U32)Key3_ISR;
pISR_EINT4_7 = (U32)Key2_ISR;
while(1)
;
}