这儿剖析了4个按键,还有 ENIT8 和 EINT19没有,不过原理相同的。
4个按键,分别是
EINT11 / GPG3
EINT13 / GPG5
EINT14 / GPG6
EINT15 / GPG7
外部上拉电阻。
EINT 8-23 共用一个IRQ向量。
初始化过程
1,设置IO的功用,00 输入 01输出 02 第二功用 P292
设置的方法是
rGPGCON &= ~(3<<3*2 | 3<<5*2 | 3<<6*2 | 3<<7*2);
rGPGCON |= (2<<3*2 | 2<<5*2 | 2<<6*2 | 2<<7*2);
2,设置 EXTINT 系列寄存器,设定中止触发的类型 P301
其间这次用到的 EINT11 13-15是散布在 EXTINT1 中
触发类型
000 低电平 001 高电平 01x 下降弦 10x 上升弦 11x 边际触发
rEXTINT1 &= ~(7<<12 | 7<<20 | 7<<24 | 7<<28);
rEXTINT1 |= (2<<12 | 2<<20 | 2<<24 | 2<<28);
3,设置 EINTPEND,P306
假如产生中止,该寄存器对应的方位一,没有中止则为0
清零的方法比较特别,对对应方位一的话表明清零。
所以这儿要这样做:
rEINTPEND |= (1<<11)|(1<<13)|(1<<14)|(1<<15);
4,设置 EINTMASK 寄存器,P305
0表明答应对应位中止,1表明制止对应位中止,默许是制止的
rEINTMASK &= ~((1<<11)|(1<<13)|(1<<14)|(1<<15));
5,先清一下IRQ中止
作为初始化,需求先清一下,留意,方才 EINTPEND 是清次中止,
EXTINT 8-23 都递归于 IRQ的中止号 5,所以这儿清的是主IRQ中止
ClearPending(BIT_EINT8_23);
其间 ClearPending(); 是一个内联函数,原型在 2440addr.h
由于在头文件里边不适宜放函数的完成,所以这次移植将函数体放到
2440lib.c 里边,而 2440addr.h 保存函数的界说
__inline void ClearPending(int bit)
{
register i;
rSRCPND = bit;
rINTPND = bit;
i = rINTPND;
}
函数很简略,跟前面相同,在 INTPND对应方位1就能铲除该位的中止
标志了。SRCPND能够有多方位1表明多个产生中止,INTPND 表明通过
优先级判决之后,所以同一时间只能有1位是置一的。
参阅 datasheet P391
#define BIT_EINT8_23(0x1<<5)
初始化的时分有必要将这两个东西都清一下
6,设置 IRQ Handleer履行中止使命
#define pISR_EINT8_23(*(unsigned *)(_ISR_STARTADDRESS+0x34))
pISR_EINT8_23 = (U32)Key_ISR;
这部分的原理在中止移植的时分现已剖析过了。这儿能够简略的理解为
当外部中止8-23产生的时分,履行中止服务程序 Key_ISR 。
留意这个函数的原型,中止服务程序,所以不能有参数,也不能回来。
void Key_ISR(void)
7,答应中止
EnableIrq(BIT_EINT8_23);
这个宏也在方才的 2440addr.h 里边,原型是:
#defineEnableIrq(bit)rINTMSK &= ~(bit)
很简略,便是设置 INTMSK 对应的位罢了。
8,剖析按键中止处理函数 Key_ISR
首要
EnterCritical(&r); 看姓名也大约猜出是什么东西了,玩过uCOS应该很
了解,进入临界区,临界区这儿的意思是不答应其他中止,也便是说在
处理的过程中制止其他的IRQ中止,也便是说IRQ中止不能嵌套,这样做
的话就便利很多了。
.globalEnterCritical
EnterCritical:
mrsr1, cpsr
strr1, [r0]
orrr1, r1, #NOINT
msrcpsr_cxsf, r1
MOV_PC_LR
在 2440slib.s 中界说汇编函数,其实功用十分简略,先读出 cpsr,保存
到R0中,由于这儿是依据ATPCS的汇编和C的参数传递规矩,R0中应该放的
是参数 &r,也便是说,r寄存器的地址,然后将 I 方位一(1表明制止,
0表明敞开),最终回来。
那么相对应的 ExitCritical 函数也就没啥悬念了。
.globalExitCritical
ExitCritical:
ldrr1, [r0]
msrcpsr_cxsf, r1
MOV_PC_LR
将 r 寄存器的数值读出来,康复到 cpsr中
至于 cpsr_cxsf 是什么东西,百度一下就知道了。
if(rINTPND==BIT_EINT8_23)
首要判别当时的 IRQ 中止是否 EINT 8-23,是的话再根绝 EINTPEND 剖析
是哪个外部中止源。
ClearPending(BIT_EINT8_23); 每次中止都要清一下的,以便能承受下一次
中止,
if(rEINTPEND&(1<<11))
这儿就很简略了,判别 EINTPEND 对应的位是否为1则能判别出是否该路
rEINTPEND |= 1<< 11;
相同了,知道是哪个中止还得清一下标志位。