扫描键盘
已有 855 次阅读2010-1-8 05:27
|系统分类:单片机|
扫描键盘
#define TK 8 //主程序执行时间8ms //8
#define timer20ms (30/TK) //延时时间20ms //(30/TK)
#define timer3S (800/TK) //延时时间3S //(1200/TK)
#define timer100ms (500/TK) //延时时间100ms //(1000/TK)
KEY KeyDat; //定义数据结构
/***************************
【函数】:HC166_read(void)
【功能】:HC166驱动与硬件相关
【参数】:无
***************************/
unsigned char HC166_read(void)//HC166_read
{
unsigned char i,set,k;
Bits1_PutBit(2, FALSE);//L cp底电平
Bits1_PutBit(1, FALSE);//L PCLK时钟低电平
Bits1_PutBit(1, TRUE); //H PCLK//时钟高电平,上升沿有效
Bits1_PutBit(2, TRUE); //H cp高电平
for(i = 0, set = 0; i < 8;i ++)//依次读取锁存的8位数据
{
set <<= 1;
if (!Bit1_GetVal())set ++;
Bits1_PutBit(1, FALSE);//L PCLK时钟低电平
Bits1_PutBit(1, TRUE);//H PCLK//时钟高电平,上升沿有效
}
switch(set) //读取扫描值
{
case 0x00: k=0x00; break; //
case K_Run: k=0x01; break; //GetRun
case K_Stop: k=0x02; break; //GetStop
case K_Down: k=0x03; break; //GetDown
case K_Jog: k=0x04; break; //GetJog
case K_Shif: k=0x05; break; //GetShif
case K_Up: k=0x06; break; //GetUp
case K_Enter: k=0x07; break; //GetEnter
case K_Mode: k=0x08; break; //GetMode
case K_Enter+K_Up: k=0x09; break; //组合键K_Enter+K_Up
case K_Enter+K_Down: k=0x10; break; //组合键K_Enter+K_Down
default: k=0x00; break; //点亮LED2
}
return k;
}
/***************************
【函数】:GetKey(void)
【功能】:判断是否有按键
【参数】:无
***************************/
void GetKey(void)
{
KeyDat.KeyTemp=HC166_read();
if(KeyDat.KeyTemp!=0) //有按键
{
KeyDat.KeyDog=timer20ms;
KeyDat.KeyPower++;
}
}
/***************************
【函数】:KeyDog(void)
【功能】:按键延时
【参数】:无
***************************/
void Key_Dog(void)
{
if(0==--KeyDat.KeyDog) //按键松开
{
KeyDat.KeyData=HC166_read();//读键盘
if(KeyDat.KeyData!=0)
{
KeyDat.KeyPower++; //进入KeyOffShort(void)
KeyDat.KeyDog=timer3S; //计数器装载3S
}
else
{
KeyDat.KeyPower=0;
KeyDat.KeyData=0; //返回
}
}
}
/***************************
【函数】:KeyOffShort(void)
【功能】:判断按键是否松开
【参数】:无
***************************/
void KeyOffShort(void)
{
if(HC166_read()==0) //判断按键松开
{
KeyDat.KeyPower=0;
KeyDat.KeyData|=HaveKey;//定义短击标记
}
else
{
if(0==--KeyDat.KeyDog) //3秒延时到否
{
KeyDat.KeyDog=timer100ms;//计数器装载100ms
KeyDat.KeyPower++; //进入KeyOffLong(void)
}
}
}
/***************************
【函数】:KeyOffLong(void)
【功能】:判断按键长击
【参数】:无
***************************/
void KeyOffLong(void)
{
if(HC166_read()!=0)//判断长击按键弹起
{
if(0==--KeyDat.KeyDog)//3秒延时到
{
if(KeyDat.KeyTemp==HC166_read())//校验数据(判断组合键用)
{
KeyDat.KeyData|=DubClick;//DubClick|HaveKey;//长击标记
KeyDat.KeyDog=timer20ms;
}
else
{
KeyDat.KeyData=0; //数据归0
KeyDat.KeyPower=0; //长击按键弹起后返回
}
}
}
else //长击按键弹起
{
KeyDat.KeyData=0; //数据归0
KeyDat.KeyPower=0; //长按键弹起后返回
}
}
/***************************
【函数】:void(*SubKey[])()
【功能】:函数指针定义
【参数】:无
***************************/
void(*SubKey[4])()=
{
GetKey,Key_Dog,KeyOffShort,KeyOffLong
};
/***************************
【函数】:void KeyBoard(void)
【功能】:主循环或者定时中断调用
【参数】:无
***************************/
void KeyBoard(void)//扫描键盘
{
(*SubKey[KeyDat.KeyPower])();
}
/***************************
【函数】:unsigned char JB_KeyData(void)()
【功能】:用户功能函数调用
【参数】:无
***************************/
unsigned char JB_KeyData(void)
{
unsigned char i=0;
if(KeyDat.KeyData>DubClick)//DubClick=0x40
{
i=KeyDat.KeyData;
KeyDat.KeyData=0;
}
return i;
}