当前位置:   article > 正文

蓝桥杯嵌入式G431(hal库)——定时器实现按键长按、短按、双击_嵌入式怎么实现按键的连续按下

嵌入式怎么实现按键的连续按下

前言:

        本文使用cubemx软件,利用定时器10ms中断实现按键的长按、短按、双击。

        定时器通常是通过一个晶体振荡器和一个计数器实现的。晶体振荡器可以产生稳定的时间基准,计数器可以根据振荡器提供的稳定时钟信号进行计数。当计数达到预设的值时,计数器就会触发一个中断信号。通过调整计数器的预设值和时钟信号的频率,我们就可以实现不同时间间隔的定时器。

        例如,我们的频率为80MHz,我们可以将分频系数设置为80-1,重装载值设置为10000-1,则中断时间为80000000/80/10000=100HZ,1/100=0.01秒,即10ms。

        定时器10ms进入一次中断,回调函数中读取引脚电平状态,由于按键抖动不会超过10ms,通过多次引脚电平保持时长进行判断,可实现短按、长按、双击。

CUBEMX配置如下:

        时钟树配置:

        定时器配置(蓝桥杯选手建议使用TIM6):

        记得开启NVIC:

        引脚配置为输入状态即可。

 代码如下:

        开启定时器中断代码如下:

    HAL_TIM_Base_Start_IT(&htim6);

        中断回调函数如下:

  1. struct keystruct {
  2.     uint8_t keyLevel;
  3.     uint8_t keyShort;
  4.     uint8_t keyLong;
  5.     uint8_t KeyDouble;
  6.     uint8_t keyTime1;
  7.     uint8_t keyTime2;
  8.     uint8_t keyChoose;
  9. }key[4];
  10.  void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  11. {
  12.     key[0].keyLevel=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
  13.     key[1].keyLevel=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
  14.     key[2].keyLevel=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
  15.     key[3].keyLevel=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
  16.     for(int i=0;i<4;i++)
  17.     {
  18.         switch(key[i].keyChoose)
  19.         {
  20.             case 0:
  21.                 if(key[i].keyLevel==0)            
  22.                     key[i].keyChoose=1;                //按下
  23.                 break;
  24.             case 1:                                                    
  25.                 if(key[i].keyLevel==0)            
  26.                     key[i].keyChoose=2;                //消抖            
  27.                 else
  28.                     key[i].keyChoose=0;                    //去抖
  29.                 break;
  30.             case 2:
  31.                 if(key[i].keyLevel==0)              //单击计时
  32.                     key[i].keyTime1++;                     
  33.                 else 
  34.                     key[i].keyChoose=3;           //已松手 
  35.                 break;
  36.             case 3:
  37.                     if(key[i].keyLevel==1)    
  38.                     {
  39.                         key[i].keyTime2++;                //等待双击开始计时
  40.                         if(key[i].keyTime2>30)        // 等待时间过长,长按短按判断
  41.                         {
  42.                             if(key[i].keyTime1<70)
  43.                                     key[i].keyShort=1;            //是短按
  44.                             else
  45.                                     key[i].keyLong=1;                    //长按
  46.                             key[i].keyChoose=0;                    //清除标志
  47.                             key[i].keyTime1=0;
  48.                             key[i].keyTime2=0;
  49.                         }
  50.                     }
  51.                     else
  52.                         key[i].keyChoose=4;     //双击开始
  53.                 break;
  54.             case 4:    
  55.                 if(key[i].keyLevel==0)            //不是消抖
  56.                     key[i].keyChoose=5;        
  57.                 else                                                //是抖动
  58.                 {
  59.                     if(key[i].keyTime1<70)
  60.                             key[i].keyShort=1;            //是短按
  61.                     else
  62.                             key[i].keyLong=1;                    //长按
  63.                     key[i].keyChoose=0;
  64.                     key[i].keyTime1=0;
  65.                     key[i].keyTime2=0;    
  66.                 }                    
  67.                 break;
  68.             case 5:
  69.                     if(key[i].keyLevel==1)            //双击松手
  70.                     {
  71.                         key[i].KeyDouble=1;
  72.                         key[i].keyChoose=0;
  73.                         key[i].keyTime1=0;
  74.                         key[i].keyTime2=0;    
  75.                     }
  76.                 break;
  77.         }
  78.     }
  79. }

        屏幕显示代码如下:

  1. void keyProc(void)
  2. {
  3.     char chPorc[21];
  4.     for(int i=0;i<4;i++)
  5.     {
  6.         if(key[i].keyShort==1)
  7.         {
  8.             key[i].keyShort=0;
  9.             sprintf(chPorc,(const char *)"KEY SHORT = %d    ",i+1);
  10.             LCD_DisplayStringLine(Line2,(u8 *)chPorc);
  11.         }
  12.         if(key[i].keyLong==1)
  13.         {
  14.             key[i].keyLong=0;
  15.             sprintf(chPorc,(const char *)"KEY  LONG = %d    ",i+1);
  16.             LCD_DisplayStringLine(Line2,(u8 *)chPorc);
  17.         }
  18.         if(key[i].KeyDouble==1)
  19.         {
  20.             key[i].KeyDouble=0;
  21.             sprintf(chPorc,(const char *)"KEY DOUBLE = %d    ",i+1);
  22.             LCD_DisplayStringLine(Line2,(u8 *)chPorc);
  23.         }
  24.         
  25.     }
  26. }

最后

        mian函数中调用一下即可

链接

        链接:https://pan.baidu.com/s/1-tUgoAmMSVSJ0tivBjPNJQ?pwd=la74 
        提取码:la74

        

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/912996
推荐阅读
相关标签
  

闽ICP备14008679号