Date: 9-Nov-2011
1. 按键电路原理图
2.中断控制器控制框图
3.按键端口寄存器设置
static void Key_Port_Init(void){
//GPF0,2,3,4设置为外部中断口
rGPFCON &=~((3<<0)|(3<<4)|(3<<6)|(3<<8)) ;
rGPFCON |= ((2<<0)|(2<<4)|(2<<6)|(2<<8)) ; //Set GPF0,2,3,4 as EINT0,2,3,4
//设置EINT0,2为下降沿触发
rEXTINT0 &= ~(7<<0|7<<8);
rEXTINT0 |= (2<<0|2<<8); //EINT0,2 Falling edge triggered
}
4.中断控制器寄存器设置
static void INT_Port_Init(void){
//中断响应方式设置
rINTMOD &= ~(1<<0|1<<2); //IRQ mode
//中断响应优先级设置
rPRIORITY &= ~(1<<0); //Prority does not rotate
}
5.代码分析 KEY.c
#include "2440addr.h"
#include "2440lib.h"
#include "def.h"
#include "option.h"
#include "UART.h"
//按键端口寄存器设置
static void Key_Port_Init(void){
rGPFCON &=~((3<<0)|(3<<4)|(3<<6)|(3<<8)) ;
rGPFCON |= ((2<<0)|(2<<4)|(2<<6)|(2<<8)) ; //Set GPF0,2,3,4 as EINT0,2,3,4
rEXTINT0 &= ~(7<<0|7<<8);
rEXTINT0 |= (2<<0|2<<8); //EINT0,2 Falling edge triggered
}
//按键3/4扫描(轮询方式),如果按键未按下则返回NULL
static U8 Key_Scan( void ){
if( !(rGPFDAT&(1<< 3)) ){ //按键3被按下
return 3 ;
}
else{
if( (!rGPFDAT&(1<<4)) ) //按键4被按下
return 4 ;
else
return NULL; //按键3/4均未被按下,返回NULL
}
}
//按键中断处理程序
static void __irq Key_ISR(void){
U32 r;
//进入临界区,屏蔽所有中断
//void EnterCritical(U32 *pSave){
// __asm
// {
//读取当前CPSR并存入r0
//根据ATPCS汇编与C的参数传递规则,r0传递&r
// mrs r1, CPSR
// str r1, [r0]
// orr r1, r1, #NOINT
// msr CPSR_cxsf, r1
// }
//}
EnterCritical(&r);
//判断中断源并执行相应操作
if(rINTPND==BIT_EINT0) //按键0按下
{
//清除中断信号
//__inline void ClearPending(U32 bit)
//{
// rSRCPND = bit;
// rINTPND = bit;
//}
ClearPending(BIT_EINT0); //清除外部中断0信号
UART0_Printf( "Interrupt occured,Key1 is pressed!\n") ; //输出按键按下信息
}
else
{
if(rINTPND==BIT_EINT2) //按键2按下
{
ClearPending(BIT_EINT2); //清除外部中断2信号
UART0_Printf( "Interrupt occured,Key2 is pressed!\n") ; //输出按键按下信息
}
}
//离开临界区
//void ExitCritical(U32 *pSave){
// __asm
// {
// ldr r1, [r0] //读取原有保存的CPSR
// msr CPSR_cxsf, r1 //恢复中断前的CPSR
// }
//}
ExitCritical(&r);
}
void Key_Scan_Test(void){
U8 key;
Key_Port_Init(); //按键端口初始化
INT_Port_Init(); //中断控制器寄存器设置
//#define pISR_EINT0 (*(unsigned *)(_ISR_STARTADDRESS+0x20))
pISR_EINT0 = pISR_EINT2 = (U32)Key_ISR; //指定中断处理程序地址
//使能外部中断0/2
//#define EnableIrq(bit) rINTMSK &= ~(bit)
EnableIrq(BIT_EINT0|BIT_EINT2);
while(UART0_GetKey() != ESC_KEY)
{
if((key = Key_Scan()) != NULL ) //按键3/4被按下
{
UART0_Printf( "Key%d is pressed!\n", key ) ;
while((!(rGPFDAT & (1<<3)) )|(!(rGPFDAT & (1<<4)) )); //wait released
UART0_Printf( "Key%d is released!\n", key ) ;
}
}
//屏蔽外部中断0/2
//#define DisableIrq(bit) rINTMSK |= (bit)
DisableIrq(BIT_EINT0|BIT_EINT2);
}
6. 测试程序及结果
#include "UART.h"
#include "KEY.h"
int Main(void)
{
UART0_Port_Init(115200); //UART0端口初始化
Key_Scan_Test(); //按键扫描
while(1){
;
}
return 0;
}