/*********************************************************************
*文件名称: Key.c
*文件标识:
*摘 要: 键盘扫描程序
*当前版本: V1.0
*作 者: eBoy
*完成日期: 2009.12.20
*********************************************************************/
#define Key_GLOBALS
#include "GLOBAL.h"
/***************************************************/
///////////////////键盘中断服务程序//////////////////
/***************************************************/
void Key_ISR(void * context,alt_u32 id)
{
uchar Key_Val,Scan_Code,Key_Temp;
uchar HCODE,LCODE;
//Key ===>| H4 | H3 | H2 | H1 | L4 | L3 | L2 | L1 |
//行和列都只有4位.
///////////////////////////////////////////////////////////
Key_Val =0xFF;
Scan_Code =0xFF;
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(KEY_H_BASE,0x00);//关KEY_H的中断.
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(KEY_H_BASE,0x00);//清中断捕获寄存器.
RD_KeyH_EN; //行使能为读.
WR_KeyL_EN; //列使能为写.
WR_KeyL(0x0); //列信号全为低电平.
Key_Temp=RD_KeyH; //读入行值.
if((Key_Temp & 0x0F)!=0x0F) //有键按下---(没键按下时,行有上拉电阻,则为高电平).
{
Delay_US(50); //延时,去抖动.
///////////////////////////////////////////////////////////
if((Key_Temp & 0x0F)!=0x0F) //去抖动后,按键还没提起.
{
Key_Temp<<=4;
HCODE=(~(Key_Temp & 0xF0)) & 0xF0; //行值.放在高4位.
//找列值.
WR_KeyL(0xE); //第1列置低电平.
Key_Temp=RD_KeyH;
if((Key_Temp & 0x0F)!=0x0F){LCODE=0x01;}
WR_KeyL(0xD); //第2列置低电平.
Key_Temp=RD_KeyH;
if((Key_Temp & 0x0F)!=0x0F){LCODE=0x02;}
WR_KeyL(0xB); //第3列置低电平.
Key_Temp=RD_KeyH;
if((Key_Temp & 0x0F)!=0x0F){LCODE=0x04;}
WR_KeyL(0x7); //第4列置低电平.
Key_Temp=RD_KeyH;
if((Key_Temp & 0x0F)!=0x0F){LCODE=0x08;}
//扫描值---行值在高4位,列值在低4位.
Scan_Code=HCODE+LCODE;
////////////////////////////
switch(Scan_Code)
{
case 0x11:Key_Val= 1; break; //"K01"键按下.--->表示数字键"1"
case 0x12:Key_Val= 2; break; //"K02"键按下.--->表示数字键"2"
case 0x14:Key_Val= 3; break; //"K03"键按下.--->表示数字键"3"
case 0x18:Key_Val=DIR_Up; break; //"K04"键按下.--->表示方向键"↑"---向上
case 0x21:Key_Val= 4; break; //"K05"键按下.--->表示数字键"4"
case 0x22:Key_Val= 5; break; //"K06"键按下.--->表示数字键"5"
case 0x24:Key_Val= 6; break; //"K07"键按下.--->表示数字键"6"
case 0x28:Key_Val=DIR_Left; break; //"K08"键按下.--->表示方向键"←"---向左
case 0x41:Key_Val= 7; break; //"K09"键按下.--->表示数字键"7"
case 0x42:Key_Val= 8; break; //"K10"键按下.--->表示数字键"8"
case 0x44:Key_Val= 9; break; //"K11"键按下.--->表示数字键"9"
case 0x48:Key_Val=DIR_Right; break; //"K12"键按下.--->表示方向键"→"---向右
case 0x81:Key_Val= 0; break; //"K13"键按下.--->表示数字键"0"
case 0x82:Key_Val=CTR_Cancel; break; //"K14"键按下.--->表示控制键"取消"
case 0x84:Key_Val=CTR_OK; break; //"K15"键按下.--->表示控制键"确定"
case 0x88:Key_Val=DIR_Down; break; //"K16"键按下.--->表示方向键"↓"---向下
default: Key_Val=0xFF; break;
}
////////////////////////////
if(Key_Val!=0xFF)
{
Key_Val_Buffer=Key_Val; //返回键值.
Key_Down=1; //有键按下标致置位.
//printf("Key_Val=%d\n",Key_Val_Buffer);
}
////////////////////////////
}
else{
Key_Down=0; //有键按下标致清零.
}
/////////////////////////////////////////
}
///////////////////////////////////////////////////////////
else
{
Key_Down=0; //有键按下标致清零.
}
///////////////////////////////////////////////////////////
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(KEY_H_BASE,0xFF); //开KEY_H的中断.
}
/***************************************************/
/////////////////////键盘初始化//////////////////////
/***************************************************/
void Key_init(void)
{
RD_KeyH_EN; //行初始化为输入.
WR_KeyL_EN; //列初始化为输出.
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(KEY_H_BASE, 0xFF); //开KEY_H的中断.
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(KEY_H_BASE, 0x00); //清KEY_H边沿捕获寄存器.
alt_irq_register(KEY_H_IRQ, NULL, Key_ISR); //注册中断服务子程序.
}
/***********************完毕*************************/
/***************************************************/