您的位置:首页 > 其它

数码相框项目模块【三】 KEY

2010-07-30 11:48 405 查看
按键有两种方式:查询和中断

按键查询操作

一、首先在电路图中找到按键SW1、SW2、SW3 和 SW4,分别对应相应的信号口为 EINT0、EINT2、EINT11、EINT19,在核心板电路图上找到相应的端口 GPF0,GPF2,GPG3 和 GPG11,接下来需要进行配置的寄存器是 GPFCON、GPFUP、GPGCON、GPGUP,因为使用按键查询操作,所以设置为 Input

二、按键的查询操作类似于LED灯的操作,当你按下哪个按键时,就可以将按键值赋给它,以便查询后面的操作

三、按键查询的去抖动和去重复的操作

按键中断操作

一、找到 I/O控制寄存器对其进行相应的设置,设置为特定功能 EINT[0]、EINT[2]、EINT[11]、EINT[19]

二、配置EXTINT0寄存器,设置中断的触发方式时选择下降沿触发,这样能够保证按键及时准确

三、按键3和按键4共享一个中断源,所以外部中断屏蔽和挂起也需要进行相应的设置,即EINTMASK和EINTPEND要进行配置

四、按键1~4 要进行屏蔽、源挂起和中断挂起的操作,配置寄存器 INTMSK、SRCPND、INTPND

五、将中断处理函数的函数名加载到内存地址当中,以便CPU自动执行中断处理函数

中断处理函数注意点:

1、必须要有 __irq 关键字

2、函数不能带有参数

3、必须用 static 关键字声明函数

4、不要进行过于复杂的运算和打印输出

5、不能有返回值

CPU会自动执行中断处理函数,不需要由外部进行调用

为了方便实现一个模块的管理,将按键查询和按键中断操作统一写在一个源程序中,用预定义进行区分

KEY.C 代码如下

Code:

/* Copyright (C), 2008-2010, wanczy Tech. Co., Ltd.

File name : key.c
Author : cy
version : V1.0
Date : 2010-6-23
Description : key module function implement

History :
1 Date 2010-6-23
Author cy
Modification
*/

#include "2440addr.h"
#include "uart.h"
#include "key.h"
#include "led.h"

/********************* 以下是按键查询代码 ************************/

#ifdef KEYPOLL

/*
Function name : key_init
Description : key init
Input parameter : none
Return : none

Others :

*/

void key_init(void)
{
volatile unsigned int val;
val = rGPFCON; /* SW1,SW2 */
val &= ~((3)|(3<<4));
rGPFCON = val;

val = rGPGCON; /* SW3,SW4 */
val &= ~((3<<6)|(3<<22));
rGPFCON = val;

}

/*
Function name : key_scan
Description : return a key value to Main

Input parameter : none
Return : the int value
Others :

*/

int key_scan(void)
{
int key;
unsigned int val;
val = (~rGPFDAT)&((1)|(1<<2));

switch(val)
{
case 1:
{
key = SW1;
break;
}
case (1<<2):
{
key = SW2;
break;
}
default:
{
key = NOKEY;
break;
}
}

val = (~rGPGDAT)&((1<<11)|(1<<3));
switch(val)
{
case (1<<3):
{
key = SW3;
break;
}
case (1<<11):
{
key = SW4;
break;
}

}
return key;
}

int key_old = NOKEY,key_new= NOKEY;

/*
Function name : key_getvalue
Description : key
Input parameter : none
Return : the int value

Others :

*/

int get_keyvalue(void)
{
int key1,key2;

key1 = key_scan(); /*recieve the key value when scan the key*/
Delay(40); /* 进行去抖动操作 */
key2 = key_scan();

if(key1!=key2)
{
return NOKEY;
}

key_new = key2;

if(key_old!=key_new)
{
key_old = key_new; /*disable the key repeat*/
return key_new;
}
return NOKEY;
}

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

/*==================== 以下是按键中断处理函数 ========================*/

#elif defined KEYIRQ //If not define KEYPOLL, define KEYIRQ

int keyvalue=NOKEY,keyflag=0;

static void __irq EINT0(void) //按键1中断函数

{
rSRCPND |= BIT_EINT0;
rINTPND |= BIT_EINT0;

keyvalue = SW1;
keyflag = 1;

}

static void __irq EINT2(void) //按键2中断函数

{
rSRCPND |= BIT_EINT2;
rINTPND |= BIT_EINT2;

keyvalue = SW2;
keyflag = 1;

}

static void __irq EINT11_19(void) //按键3,4中断处理函数

{
//进行手动置1操作

rSRCPND |= BIT_EINT8_23;
rINTPND |= BIT_EINT8_23;

//因为按键3和4共用一个中断源,所以要对响应的中断进行判断

if(rEINTPEND==(1<<11))
{
rEINTPEND |= (1<<11);
keyvalue = SW3;
keyflag = 1;
}
else if(rEINTPEND==(1<<19))
{
rEINTPEND |=(1<<19);
keyvalue = SW4;
keyflag = 1;
}

}

/*============================================================*/

void irq_init(void)
{

rGPFCON= ((rGPFCON & ~((3<<0)|(3<<4)))|(2<<0)|(2<<4)); //EINT[0], EINT[2]

rGPGCON= ((rGPGCON & ~((3<<6)|(3<<22)))|(2<<22)|(2<<6)); //EINT[11], EINT[19]

rEXTINT0= ((rEXTINT0 & ~((7<<0)|(7<<8)))|(2<<0)(2<<8));// Falling edge triggered

rEXTINT1= ((rEXTINT1 & ~(7<<12))|(2<<12)); //Falling edge triggered

rEXTINT2= ((rEXTINT2 & ~(7<<12))|(2<<12)); // Falling edge triggered

rEINTMASK = (rEINTMASK & ~((1<<11)|(1<<19))); //EINT11, EINT19 Disable the MASK

rEINTPEND |= (1<<11)|(1<<19); //EINT11, EINT19 occur interrupt

rINTMSK &= ~((BIT_EINT8_23)|(BIT_EINT2)|(BIT_EINT0)); //Disable MASK

//SRCPND,INTPND进行置1操作

rSRCPND |= (BIT_EINT8_23)|(BIT_EINT2)|(BIT_EINT0);
rINTPND |= (BIT_EINT8_23)|(BIT_EINT2)|(BIT_EINT0);

//将中断处理函数名加载到内存中断地址中

pISR_EINT0= (unsigned )EINT0;
pISR_EINT2= (unsigned )EINT2;
pISR_EINT8_23= (unsigned )EINT11_19;
}

/*
Function name : get_keyvalue

Description : key
Input parameter : none
Return : the int value
Others :

*/

int get_keyvalue(void) //返回获取的键值

{
if(keyflag==0)
return NOKEY;
else
{
keyflag=0;
return keyvalue;
}
}

#endif

KEY.H 代码如下

Code:

#ifndef _KEY_H
#define _KEY_H

#define SW1 1
#define SW2 2
#define SW3 3
#define SW4 4
#define NOKEY 0

#define KEYIRQ
//define KEYPOLL

extern void key_init(void);
extern int key_scan(void);
extern void irq_init(void);
extern int get_keyvalue(void);

#endif
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: