基于STM32F103C8T6(HAL库)和CubeMX使用定时器TIM中断扫描按键,实现按键的长按、短按以及双击

在按键的使用过程中,有许多的按键扩展方式,比如区别按键的长按短按以及双击,这里将实现这些功能

硬件连接、cubemx配置、LED封装函数,请看我的上一篇文章,这里只介绍按键的封装函数

实现按键长短按

中断回调函数void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

volatile uint8_t  j = 0;
volatile uint8_t  key_short = 0; // 短按标志
volatile uint8_t key_long = 0;  // 长按标志
uint16_t key_t = 0;    // 计时器(单位:10ms,TIM3中断周期为10ms)
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
    if (htim->Instance == TIM3) {
      uint8_t  k = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0);
        switch (j) {
            case 0: // 初始状态,等待按键按下
                if (k == 0) { // 检测到按下
                    j = 1;    // 进入消抖确认状态
                    key_t = 0;
                }
                break;
            case 1: // 消抖确认按下(10ms)
                if (k == 0) {  // 确认稳定按下
                    j = 2;
                    key_t = 0;
                } 
                else {      // 抖动,回到初始
                     j = 0;
               }
                break;
            case 2: // 检测按持续时间
                if (k == 1) { // 按键松开
                    if (key_t <= 100) { // 短按(≤1秒)
                        key_short = 1;
                    } else {            // 长按(>1秒)
                        key_long = 1;
                    }
                    j = 0; // 复位状态机
                } else {   // 持续按下
                    key_t++;
                }
                break;
        }
    }
}

主函数main.c

  HAL_TIM_Base_Start_IT(&htim3);

开启定时器

  while (1)
  {
      if(key_long==1)//按键长按LED灯熄灭
      {
         led_p(0);
         key_long=0;//将标志位清零
      }
      if(key_short==1)//按键短按LED灯点亮
      {
         led_p(1);
         key_short=0;//将标志位清零
      }
  }

这样就实现了长按和短按了

实现按键双击

中断回调函数void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

//按键单击双击(1S内没有按下第二次默认为单击)
volatile uint8_t j = 0;
volatile uint8_t key_d = 0; // 单击标志
volatile uint8_t key_s = 0; // 双击标志
uint16_t key_t=0; // 计时器(单位:10ms)
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim->Instance == TIM3) //TIM3中断周期为10ms
    {
      uint8_t  k = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0);
        switch(j)
        {
            case 0: // 初始状态,等待按键按下
                if(k == 0) { // 检测到按下
                    j = 1;   // 进入消抖确认状态
                    key_t = 0;
                }
                break;
            case 1: // 消抖确认按下
                if(k == 0) { // 仍然按下
                    j = 2;  // 进入等待松开状态
                    key_t = 0;
                } else {     // 抖动,回到初始
                    j = 0;
                }
                break;
            case 2: // 等待第一次松开
                if(k == 1) { // 已松开
                    j = 3;   // 进入等待双击状态
                    key_t = 0; // 重置双击计时
                }
                break;
            case 3: // 等待第二次按下(双击检测窗口)
                if(k == 0) { // 第二次按下
                    j = 4;   // 进入第二次消抖
                    key_t = 0;
                } 
                else {
                    key_t++;
                    if(key_t >= 100) { // 1秒超时
                        key_d = 1;     // 触发单击
                        j = 0;        // 复位状态机
                    }
                }
                break;
            case 4: // 确认第二次按下
                if(k == 0) { // 仍然按下
                    j = 5;   // 进入等待第二次松开
                    key_t = 0;
                } else {     // 抖动,回到双击检测
                    j = 3;
                }
                break;
            case 5: // 等待第二次松开
                if(k == 1) { // 松开完成双击
                    key_s = 1; // 触发双击标志
                    j = 0;      // 复位状态机
                }
                break;
        }
    }
}

主函数main.c

HAL_TIM_Base_Start_IT(&htim3);

开启定时器

  while (1)
  {
      if(key_d==1)//按键单击LED灯点亮
      {
         led_p(1);
         key_d=0;//将标志位清零
      }
      if(key_s==1)//按键双击LED灯熄灭
      {
         led_p(0);
         key_s=0;//将标志位清零
      }
  }

这样就实现了单击和双击了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值