基于HAL库,STM32 实现按键唤醒+中断实现连按两次和三次

时间:2021-08-02 14:35:34

在很多时候,我们都会碰到要实现按键连按功能,笔者起初刚实现这功能,挺纠结的,为什么呢?我项目的要求是按键唤醒,因此要使用外部中断,同事要实现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;
    }
}

2、实现2击和3击按键:,代码如下:
void PressKey(void)
{
    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;  
    }
}
到此为止,按键部分实现就完成了,具体做法就得看自己了,若有疑问,欢迎留言,一起讨论!