简单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可以了解一下。
如果你觉得此篇文章对你有用,请点个赞再走吧。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库