记录STM32实现多功能按键

由于网上购买的最小系统板子按键有限,自己加了一个按键在PA0上,单个按键需要实现多种功能,自己写了一个简单代码进行简单的单击、双击、三连击、长按等功能,以此简单记录。

编程思路:

如果只用标志位记录按键按下次数以此判断的话,无法准确做到在一定时间内判断是单击还是双击。在此我使用一个定时器进行记录按下按键在周期内是否有效。如果按键按下,开始进行计数,时间到后开始判断触发次数。

所以每当我按下按键,我就开启定时器3进行计时

按键的配置代码和中断如下:

void KEY_Init(void)
{    
    GPIO_InitTypeDef KEY_PIN;
    EXTI_InitTypeDef KEY_exti;    
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);        //RCC
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);      
    
    KEY_PIN.GPIO_Mode = GPIO_Mode_IPD;  //上拉输入    GPIO
    KEY_PIN.GPIO_Pin = GPIO_Pin_0;   //选中0引脚
    KEY_PIN.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_Init(GPIOA,&KEY_PIN);  //初始化GPIO配置
    
    KEY_exti.EXTI_Line = EXTI_Line0;  //选中线0
    KEY_exti.EXTI_Mode = EXTI_Mode_Interrupt;  //中断模式
    KEY_exti.EXTI_Trigger = EXTI_Trigger_Rising;  //下降沿触发 
    KEY_exti.EXTI_LineCmd =  ENABLE;  //使能中断请求
    EXTI_Init(&KEY_exti);  //初始化结构体
    
    NVIC_EnableIRQ(EXTI0_IRQn);  //开启exti0中断编号进行工作,默认自然优先级
} 
u8 KEY_CONR; //记得全局声明这个变量
void EXTI0_IRQHandler(void)
{
    delay_ms(100);
    //清除中断标志位
    EXTI_ClearITPendingBit(EXTI_Line0);
    TIM_Cmd( TIM3,ENABLE);//按下按键开始计时,时间到进入定时器中断
     KEY_CONR++;//按下按键累计次数
}

我这里使用的是通用定时器3进行一个基本定时,代码如下:

void TIM3_Init(u16 per,u16 psc)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure={0};
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能TIM3时钟
   //初始化TIM3
    TIM_TimeBaseInitStructure.TIM_Period=5000-1;   //自动装载值5000
    TIM_TimeBaseInitStructure.TIM_Prescaler=7200-1; //分频系数7200
    TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //设置向上计数模式
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;    //不分频
    TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
   
    TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除标志 

    TIM_ITConfig(TIM3,TIM_IT_Update, ENABLE);   //使能定时器溢出更新中断
    
    NVIC_EnableIRQ(TIM3_IRQn);   //使能TIM3_IRQn中断编号进行工作,默认自然优先级编号

    //TIM_Cmd(TIM3,ENABLE); //使能定时器    
}

定时器3的中断服务函数进行标志位判定,代码如下:

void TIM3_IRQHandler(void)
{
            TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除标志 
        if(KEY0==0&&KEY_CONR==2)//按下按键松手,并且超过1秒只触发两次按键中断
          {
              KEY_CONR=0;//清空标志,下次还能触发
              TIM_Cmd( TIM3,DISABLE);//判断单双击
              printf("触发双击!\r\n"); 
                LED0=0;              
          }
          else if(KEY0==0&&KEY_CONR==1)//按下按键松手,并且超过1秒只触发一次按键中断
          {
                KEY_CONR=0;//清空标志,下次还能触发
                TIM_Cmd( TIM3,DISABLE);
                printf("触发单击\r\n");
                LED0=1;
          }else if(KEY_CONR>=3)//三连击,我这里不需要
          {
                KEY_CONR=0;//清空标志,下次还能触发
                TIM_Cmd( TIM3,DISABLE);
                printf("此次按键功能不存在\r\n");
          }else if(KEY0==1&&KEY_CONR==1)//按下按键没有松手,并且超过1秒只触发一次按键中断,这里存在小BUG,必须要按够1秒不松手才算触发
          {
                KEY_CONR=0;//清空标志,下次还能触发
                TIM_Cmd( TIM3,DISABLE);
                printf("触发长按\r\n");
          }



}

注:因为板子只有一个按键,还有剩余的定时器可以使用,如果定时器不够的话,不建议这么去占用宝贵的定时器。

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小刘刘的奇妙冒险

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值