微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 2440test中按键的分析

2440test中按键的分析

时间:12-02 来源:互联网 点击:
这里分析了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;
同样了,知道是哪个中断还得清一下标志位。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top