STM32单片机定时器做按键消抖
原因:直接用软件延时做消抖会暂用整个资源,导致程序全部卡死等待延时,如下面程序:
if(key_up&&(KEY0==0||KEY1==0||WK_UP==1))
{
delay_ms(10);//去抖动
key_up=0;
if(KEY0==0)return KEY0_PRES;
else if(KEY1==0)return KEY1_PRES;
else if(WK_UP==1)return WKUP_PRES;
}else if(KEY0==1&&KEY1==1&&WK_UP==0)key_up=1;
return 0;// 无按键按下
所以建议使用定时扫描按键状态来判断状态去做消抖,提高程序利用率,如下面程序:
uint8_t KeyStatus[17][4]; //按键状态缓存区
uint8_t KeyTrigger[17]; //按键出发
uint16_t KeyReadTimer=0; //按键循环读取时间
extern uint16_t KEY_time; //定时器变量,5ms加1
void KEY_loop(void)
{
uint8_t i=0;
if(KEY_time >= (KeyReadTimer+2))
{
if(KEY_time>=60000) KEY_time=0;
KeyReadTimer=KEY_time;
for(i=0;i<sizeof(KeyTrigger);i++) //5ms左移一次
{
KeyStatus[i][0] = KeyStatus[i][1];
KeyStatus[i][1] = KeyStatus[i][2];
KeyStatus[i][2] = KeyStatus[i][3];
}
KeyStatus[0][3] = KEY1; //读取按键状态, #define KEY1 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_0)
KeyStatus[1][3] = KEY2;
KeyStatus[2][3] = KEY3;
KeyStatus[3][3] = KEY4;
KeyStatus[4][3] = KEY5;
KeyStatus[5][3] = KEY6;
KeyStatus[6][3] = KEY7;
KeyStatus[7][3] = KEY8;
KeyStatus[8][3] = KEY9;
KeyStatus[9][3] = KEY10;
KeyStatus[10][3] = KEY11;
KeyStatus[11][3] = KEY12;
KeyStatus[12][3] = KEY13;
KeyStatus[13][3] = KEY14;
KeyStatus[14][3] = KEY21;
KeyStatus[15][3] = KEY22;
KeyStatus[16][3] = KEY23;
for(i=0;i<sizeof(KeyTrigger);i++) //左移4次相当于延时20ms后做判断
{
if(KeyStatus[i][0]==0 && KeyStatus[i][1]==0 && KeyStatus[i][2]==0 && KeyStatus[i][3]==0)
{
KeyTrigger[i] = 1;
}
else if(KeyStatus[i][0]==1 && KeyStatus[i][1]==1 && KeyStatus[i][2]==1 && KeyStatus[i][3]==1)
{
KeyTrigger[i] = 0;
}
}
还可以通过改变判断 < if(KeyStatus[i][0]==0 && KeyStatus[i][1]==0 && KeyStatus[i][2]==0 && KeyStatus[i][3]==0) > 来做上升沿或下降沿触发。