数码相框项目模块【三】 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
按键查询操作
一、首先在电路图中找到按键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
相关文章推荐
- 数码相框项目模块【一】 跑马灯
- 数码相框项目模块【二】 UART
- 数码相框项目之触摸屏模块
- 数码相框项目
- linux应用项目(一)数码相框(2)数码相框之字符编码与字符的点阵显示
- 韦东山第三期视频数码相框中的电子书项目的ShowOnePage函数解析
- 数码相框各模块时钟流详解
- 文件浏览器_数码相框项目总结 (上)
- linux应用项目(一)数码相框数码相框之电子书
- linux应用项目(一)数码相框(2)数码相框之freetype实现矢量字体的显示
- linux应用项目(一)数码相框(3)数码相框之电子书
- linux应用项目(一)数码相框(1)数码相框之系统框架
- 数码相框项目之LCD模块
- 构建Maven多模块项目+SSM框架整合+Thymeleaf(二)
- 项目开发:SSH 之“department”模块从零开发
- maven创建多模块项目fREemark+springMVC+mybatis+mybatis 自动生成
- 动态规划及其在Apollo项目Planning模块的应用
- eclipse创建maven多模块项目(单个类似)
- [maven] 搭建多模块企业级项目
- Android项目模块化介绍——用注解使各个模块间不再依赖