蓝桥杯单片机之通过实现同一个按键的短按与长按功能
实现按键的短按与长按的不同功能
问题分析
对于按键短按,通常是松开后实现其功能,而不会出现按下就进行后续的操作;而对于按键长按,则不太一样,按键长按可能分为两种情况,一是长按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;}
}