在很多时候,我们都会碰到要实现按键连按功能,笔者起初刚实现这功能,挺纠结的,为什么呢?我项目的要求是按键唤醒,因此要使用外部中断,同事要实现2次连按
和3次连按两种功能,但是在网上也没找到相关资料,大部分都是按键状态机,无法满足我要求,好了,闲话不多说,下面直接讲代码实现。
1、中断扫描按键,PA8是我其他功能外部中断,PA0是按键唤醒和按键扫描,注意代码红色部分,起初觉得因为HAL库中断有清中断功能,就没加清中断,但是偶然性
会中断多次 ,因此必须加上:
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
switch(GPIO_Pin)
{
case GPIO_PIN_8:
{
EXTIFlag = 1;
break;
}
case GPIO_PIN_0:
{
delay_us(500000); //250000 <==>10ms
if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == 1)
{
FlagCount++;
if(FlagCount>2)
FlagCount=3;
}
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
break;
}
default:
break;
}
}
{
switch(FlagCount)
{
case 1:
{
if(cs3511.BegainTime == 0)
cs3511.BegainTime = HAL_GetTick();
cs3511.MatchTime= HAL_GetTick() - cs3511.BegainTime;
if(cs3511.MatchTime > 500 && HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == 0) //超时0.5s
{
cs3511.BegainTime = 0;
FlagCount = 0;
}
break;
}
case 2:
{
if(cs3511.SecondTime == 0)
cs3511.SecondTime = HAL_GetTick();
cs3511.MatchTime= HAL_GetTick() - cs3511.SecondTime;
if(cs3511.MatchTime > 400) //超时0.4s
{
cs3511.BegainTime = 0;
cs3511.SecondTime = 0;
Stage=DOUBLECLICKFLAG;
//FlagCount = 0;
}
else if(cs3511.MatchTime > 1500) //超时1.5s按键功能失效
{
Stage=NOCLICKFLAG;
FlagCount = 0;
}
break;
}
case 3:
{
if(cs3511.ThirdTime == 0)
cs3511.ThirdTime = HAL_GetTick();
cs3511.MatchTime= HAL_GetTick() - cs3511.ThirdTime;
if(cs3511.MatchTime > 1500) //超时1.5s,按键失效
{
cs3511.ThirdTime = 0;
Stage=NOCLICKFLAG;
FlagCount = 0;
}
Stage = THIRDCLICKFLAG;
cs3511.BegainTime = 0;
cs3511.SecondTime = 0;
break;
}
default:
break;
}
}