实现按键的短按与长按的不同功能
问题分析
对于按键短按,通常是松开后实现其功能,而不会出现按下就进行后续的操作;而对于按键长按,则不太一样,按键长按可能分为两种情况,一是长按n秒后实现后续功能,比如按键按下1s后开灯,第二种情况是长按超过n秒以上实现功能,例如按键按下超过1s则不断增加某一个参数的数值;
对于按键检测,通常有两种方式,一种是使用循环进行检测,另一种是使用中断进行检测,对于短按按键,两种方式都可以较好地实现,但是对于长按按键,则只能在中断里进行检测,下面上述几种情况进行具体分析。
按键的检测
引脚定义如下,对应按键为S7.
sbit col1=P4^4;
sbit row1=P3^0;
循环检测
循环检测就给一个行和一个列分别赋值相反的值即可,然后检测是否被拉低,并进行消抖,代码如下,通常来讲,在比赛中都是按键松开后实现功能,因此这里不必纠结到底应该在什么时候实现功能,代码如下。通过判断函数是否返回1来判断S7是否被按下。
bit S7()
{
col1=0;row1=1;
if(row1==0)
{
Delay15ms();
while(row1==0);
return 1;
}
return 0;
}
中断检测
中断检测较为方便,通常我们将定时器设为1ms的定时,然后在中断里检测按键是否被按下,如果被按下,则开始计数,如果在15次计数后依旧处于按下的状态,则说明此次按键是有效的,在这里,有两种实现方式,第一种是按键按下超过15ms就进行下一步操作,不等待松开,这种方式通常来讲会存在bug,因为会导致程序不断重复执行后续的代码,因此一般不用这种方式。另一种是等待按键松开后再进行下一步操作,代码如下,这里定时器的配置省略;
void Timer0()interrupt 1
{
static unsigned int cnt=0,flag=0;
col1=0;row1=1;
if(row1==0)
{
cnt++;
}
else
{
if(cnt>15)
{
/*****进行后续操作*****/
}
}
}
对于按键的长按,与短按检测相差不大,只不过是比较的数值会增加而已,对于同一个按键的短按与长按,分开进行判断即可,这里假设检测长按时间为1s,代码分别如下;
长按后松开执行
void Timer0()interrupt 1
{
static unsigned int cnt=0,flag=0;
col1=0;row1=1;
if(row1==0)
{
cnt++;
}
else
{
// 长按松开检测 注意 长按检测要放在短按检测前
if(cnt>1000)
{
/*进行后续操作*/
}
// 短按检测
else if(cnt>15)
{
/****进行后续操作****/
}
// 注意 此时按键处于断开状态
// 因此检测完按键后要将cnt清零
cnt=0;
}
}
长按后即刻执行
void Timer0()interrupt 1
{
static unsigned int cnt=0,flag=0;
col1=0;row1=1;
if(row1==0)
{
cnt++;
// 长按检测
if(cnt>1000)
{
// 如果题目要求的是按键按下超过1s就执行动作 不需要按键松开
// 例如按下超过1s则数字持续增加 此时就直接在此处进行增加的操作即可
/*******进行后续的操作*******/
}
}
else
{
// 短按检测
if(cnt>15)
{
/****进行后续操作****/
}
// 注意 此时按键处于断开状态
// 因此检测完按键后要将cnt清零
cnt=0;
}
}