简单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可以了解一下。
如果你觉得此篇文章对你有用,请点个赞再走吧。

浙公网安备 33010602011771号