|
发表于 2009-12-18 11:21:55
|
显示全部楼层
自从学习了马老师按键的状态机,我才知道什么是实用的按键程序。下面是本人用于项目的按键扫描。
其中包括一个按键是单发的,二个是连_发的,连_发的时间SPEED_INC_DEC设定,而按键去抖时间由KEY_DELAY确定(实际即是在主程序的循环次数,根据实际设定)
/*4 key state in key FSM mode*/
enum
{
KEY_STATE_0=0, //wait trigger
KEY_STATE_1, //key press wait to comfirm
KEY_STATE_2, //delay count_1
KEY_STATE_3 //delay count_2
};
//key dely 1s,Sequence key trigger time delay 500ms
#define SPEED_INC_DEC 200
#define KEY_DELAY 500
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : KEYS_Init
* Description : Init GPIOs for joystick/button management
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void KEYS_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* EnableGPIOBclock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_StructInit(&GPIO_InitStructure);
/*Key GPIOs configuration*/
/*Input pull up-mode can save Res*/
GPIO_InitStructure.GPIO_Pin = KEY_ON_BIT|KEY_PLUS_BIT|KEY_MINUS_BIT;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(KEY_PORT, &GPIO_InitStructure);
}
/*******************************************************************************
* Function Name : KEYS_Read
* Description : Reads key from demoboard.FSM detect the key pad
* Input : None
* Output : None
* Return : Return key_value
*******************************************************************************/
u8 KEYS_Read (void)
{
static u8 key_state= KEY_STATE_0;
static u32 bKey_Port_current;
static u32 bKey_Port_previous=KEY_MASK;
u8 key_return=NOTHING;
bKey_Port_current= KEY_MASK&GPIO_ReadInputData(KEY_PORT);
switch(key_state)
{
case KEY_STATE_0:
//key press waite comfirm
if((bKey_Port_current!=KEY_MASK)/*&&(bKey_Port_current==bKey_Port_previous)*/) key_state=KEY_STATE_1;
break;
case KEY_STATE_1:
//real key press,turn to delay_cout1
if(bKey_Port_previous==bKey_Port_current)
{ //ONOFF not use sequence trigger mode
if(!(bKey_Port_current&KEY_ON_BIT)) {key_return=ONOFF;DelayTimer(200);}
key_state=KEY_STATE_2;
StartTimer(TIMERKEY,KEY_DELAY);
}
else key_state=KEY_STATE_0;
break;
case KEY_STATE_2:
//real key press,and no delay for 1s
if(bKey_Port_current==KEY_MASK)
{ //PLUS,MINUS key 1/1,ONOFF key 1/0,iput(1:0 off:ON)/output
if(!(bKey_Port_previous&KEY_PLUS_BIT)) key_return=PLUS;
else if(!(bKey_Port_previous&KEY_MINUS_BIT)) key_return=MINUS;
key_state=KEY_STATE_0;
}
else if(ReadTimer(TIMERKEY)==OK)
{ //PLUS,MINUS key 0/2,ONOFF key 0/0
if(!(bKey_Port_current&KEY_ON_BIT)) break;
if(!(bKey_Port_current&KEY_PLUS_BIT)) key_return=PLUS;
else if(!(bKey_Port_current&KEY_MINUS_BIT)) key_return=MINUS;
key_state=KEY_STATE_3;
StartTimer(TIMERKEY,SPEED_INC_DEC);
}
break;
case KEY_STATE_3:
//PLUS,MINUS 0/2
if((bKey_Port_previous==bKey_Port_current)&&(ReadTimer(TIMERKEY)==OK))
{
if(!(bKey_Port_current&KEY_PLUS_BIT)) key_return=PLUS;
else if(!(bKey_Port_current&KEY_MINUS_BIT)) key_return=MINUS;
StartTimer(TIMERKEY,SPEED_INC_DEC);
}
else if(bKey_Port_previous!=bKey_Port_current) //if(bKey_Port_previous!=bKey_Port_current) must used
{
key_state=KEY_STATE_0;
StopTimer(TIMERKEY);
}
break;
}
bKey_Port_previous=bKey_Port_current;
return key_return;
} |
|