|
有BUG的硬件按键,本以为程序扫描能解决,但还是有问题?
(原文件名:QQ截图20111123095528.png)
这个硬件电路有问题,但是板子已经设计好了,因为考虑到按键不会同时按下,每次只能单个按键按下,我就通过软件来实现,可是问题存在,程序如下,问题是,S1,S2,S3,S4能实现短按长按功能,但是S4,S5,S6,S7,S8,S9,S10,长按功能实现不了,而且有时短按时灵时不灵
#define KEY_LONGDOWN_TIME 330 // 330*6ms=1.98s
#define KEY_SHORTDOWN_TIME 6 // 6*6ms=36ms
#define KEY_LONGDOWN_STATE 2
#define KEY_SHORTDOWN_STATE 1
#define KEY_NODOWN_STATE 0
//S1 = 0b01 1111 1111
//S2 = 0b10 1111 1111
//S3 = 0b11 0111 1111
//S4 = 0b11 1111 1110
//S5 = 0b11 1111 1101
//S6 = 0b11 1110 1111
//S7 = 0b11 1111 1011
//S8 = 0b11 1101 1111
//S9 = 0b11 1111 0111
//S10 = 0b11 1011 1111
typedef enum KEY {
KEY_NULL = (u16)0x03FF,
KEY_VALUE_1 = (u16)0x01B7,
KEY_VALUE_2 = (u16)0x02DB,
KEY_VALUE_3 = (u16)0x036D,
KEY_VALUE_4 = (u16)0x03FE,
KEY_VALUE_5 = (u16)0x03FD,
KEY_VALUE_6 = (u16)0x03EF,
KEY_VALUE_7 = (u16)0x03FB,
KEY_VALUE_8 = (u16)0x03DF,
KEY_VALUE_9 = (u16)0x03F7,
KEY_VALUE_10 = (u16)0x03BF,
KEY_POS_SPEED = (u16)0x0401
} KEY_VALUE;
void Key_Scan(void)
{
if(gStruKey.KeyStatus == TRUE)
return;
gStruKey.BackKey = (gStruKey.BackKey<<3)|((PINB&0xE0)>>5);
switch(gStruKey.ScanCnt)
{
case 0:
cbi(PORTD,PD0);
sbi(PORTD,PD1);
gStruKey.ScanCnt = 1;
return;
case 1:
sbi(PORTD,PD0);
cbi(PORTD,PD1);
gStruKey.ScanCnt = 2;
return;
case 2:
sbi(PORTD,PD0);
sbi(PORTD,PD1);
gStruKey.ScanCnt = 0;
break;
default:
break;
}
gStruKey.BackKey <<= 1;
gStruKey.BackKey |= (PIND&0x04)>>2;
gStruKey.BackKey &= KEY_NULL;
gStruKey.KeyTempWord[2] = gStruKey.KeyTempWord[1];
gStruKey.KeyTempWord[1] = gStruKey.KeyTempWord[0];
gStruKey.KeyTempWord[0] = gStruKey.BackKey;
if((gStruKey.KeyTempWord[2] == gStruKey.KeyTempWord[1])
&&(gStruKey.KeyTempWord[2] == gStruKey.KeyTempWord[0])
&&(gStruKey.BackKey != KEY_NULL))
{
if(gStruKey.CurrentKey == gStruKey.BackKey)
{
gStruKey.KeyPrsTime++;
if(gStruKey.KeyPrsTime >= KEY_LONGDOWN_TIME) // 长按
{
gStruKey.KeyStatus = TRUE;
gStruKey.IsRealse = TRUE;
gStruKey.KeyPrsState = KEY_LONGDOWN_STATE;
gStruKey.KeyPrsTime = 0;
}
}
else
{
gStruKey.KeyPrsTime = 0;
gStruKey.CurrentKey = gStruKey.BackKey;
}
}
else
{
if((gStruKey.IsRealse==FALSE)&&(gStruKey.KeyPrsTime>=KEY_SHORTDOWN_TIME)) // 短按
{
gStruKey.KeyStatus = TRUE;
gStruKey.IsRealse = TRUE;
gStruKey.KeyPrsState = KEY_SHORTDOWN_STATE;
}
else
{
gStruKey.KeyStatus = FALSE;
gStruKey.IsRealse = FALSE;
gStruKey.KeyPrsState = KEY_NODOWN_STATE;
}
gStruKey.KeyPrsTime = 0;
}
}
Key_Scan()放在2MS的定时中断0里面 |
|