简单30行代码实现按键的长按、短按和双击判断

  最近项目有按键,是要实现按键的复用。看看网上的一些例程,使用场景上有一些差别,也比较繁杂。因为目前对这点的要求也不是很高,我就在想自己能不能写个简单点的。

unsigned char Scan_Key(unsigned char const volatile *ptr,char bitposition)
{
    unsigned char mask,Key_Value=0;
    unsigned long count=0;

    mask=0x01<<bitposition;
    while((*ptr & mask)==0)               //指针变量对应的值中第n bit如果为0(说明按键被按下)
    {
        count++;
        if(count>100000)                  //count大于100000视为长按
        {
            Key_Value+=0x10;              //高4位记长按次数
            count=0;
            break;                        //直接break whlie,不等待按键释放
        } 
    }
    if(((*ptr & mask)!=0)&&(count>2000))  //如果第n bit为1(说明按键被释放)且count>2000视为短按
    {
          Key_Value+=0x01;                //低四位记短按次数
          count=0;    
          for(unsigned long i=25000;i>0;i--)  //按键被释放后,继续监测一段时间,看是否再被按下
            if((*ptr & mask)==0)              
            {
              Key_Value+=Scan_Key(ptr,bitposition);     //函数递归,根据按键长短再判断长按短按
              break;                          
            }
    }
    return Key_Value;
}

  此函数不依靠main函数的while循环和定时器,可以运行在中断中,一次中断实现双击。功能在理论上可以实现n长击、n短击,但行数上只有不到30行,大括号占了挺大比例啊,个人书写习惯。如果明确按键在哪只引脚上,还可以自行调整一下,代码可以再少些。
  使用的话,可以这么用:

unsigned char Key_Value;
unsigned char const volatile *ptr;
ptr = &PA_IDR;
Key_Value = Scan_Key(ptr,2);
swich(Key_Value)
{
case 1:xxxx;break;
case 2:xxxx;break;
case 16:xxxx;break;
default:xxxx;break;
}

  首先,这函数我是用在STM8S平台上的,所以弄了两个参数,一个寄存器的指针,一个按键所在位。这里主要是考虑PA~PE所有端口组的所有引脚都可以直接调用,不必再多考虑其他。
  程序运行的CPU为2MHz,效果不错,如果想调整各时间,可以修改if(count>100000)中的count调整长按判断时间,修改if(((*ptr & mask)!=0)&&(count>2000))中的count调整短按判断时间,修改for(unsigned long i=25000;i>0;i--)中的i调整连击等待时间。
  最后,其他地方也没什么特别值得说明了,两个break可以了解一下。

  如果你觉得此篇文章对你有用,请点个赞再走吧。

posted @   皮格马利安  阅读(136)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示