本帖最后由 wyq165 于 2014-10-31 19:29 编辑
typedef struct
{
uchar LongFlag ;
Uint keydat ;
}KEY;
Uint keysame = 0;
Uchar keyCnt0 = 0,keyCnt = 0;
bit b_longfalg = 0;
KEY KeyCanf() //20MS扫描一次 或者其他时间
{
KEY mykey;
Uchar i;
Uint keyNum = 0;
code Uchar Make[3]={0xfe,0xfd,0xfb};
P0 = 0xf8; //p0-p2为输出 P3-P7为输入
if(P0 != 0xf8){
for(i = 0;i < 3;i++)
{
P0 = Make;
keyNum |= ((~(P0 & 0xF8)) >> 3) << (5 * i);
}
if(++keyCnt0 > 4){ //这里是按下和松开的防抖 可以自己适当改值 ,改变灵敏度
if(keysame != keyNum)
{
keyCnt0 -=4;
}else{
keyCnt0 = 4;
keyCnt++;
mykey.keydat = keyNum;
if(keyCnt>=80) b_longfalg = 1; //这里bit为蜂鸣响标示。 是为了响应长按而松手的时候 ,比如一直按,直到声音响(长按)。
}
keysame =keyNum;
}
mykey.LongFlag = 0xff;
}else
{
if((keyCnt>2)&&(keyCnt <80)) //小于5秒为端按 或者自己定合适的时间
{
mykey.LongFlag = 0x00;
}else if(keyCnt>=80) //长按 维持5S以上 或者自己定合适的参数。
{
mykey.LongFlag = 0x01;
}else //无按键
{
mykey.LongFlag = 0xff;
}
keyCnt = 0;
keyCnt0 = 0;
b_longfalg = 0;
}
return mykey;
}
调用方式:
void main()
{
KEY t_key;
while(1)
{
if(timer_isr_delay) //定时器中断内置的位 20ms或10ms 。。。视具体情况
{
timer_isr_delay
t_key = KeyCanf() ;
if(t_key.LongFlag != 0xff) //有按键
{
if(t_key. LongFlag == 0x00) //短按
{
switch( keydat )
{
case XX: 对应单个键或者组合键都可以。值不一样
对应按键处理
break;
}
}
else 长按
{
同上
}
}
}
}
}
这是我的16X16矩阵按键检测的实现(单按键/几个独立按键也可以用此法),可以实现长按,短按,组合按,自己琢磨的。一直在用着,也不知道好不好,也一并发给你看看吧,希望能帮到你。
|