【分享】按键程序,大道至简,按键扫描 + 累计主循环次数去抖动/不占用定时器
【分享】按键程序,大道至简按键扫描 + 累计主循环次数去抖动/不占用定时器
我分享这个代码有下面几个意思:
1. 向坛友介绍三行按键代码。
2. 累计主循环次数可当作软定时器使用。
3. 向坛友介绍状态机编程概念。该代码是状态机编程的最佳范例。
#define Port_KeyP2
#define KEY_NUMBER 1000
u8 Keyscan(void)
{
u8 ReadKey;
u8 i = 0;
static u8 Key_Trge = 0;
static u8 ContKey = 0;
static u16 LoopCnt_Key = 0;
if(++LoopCnt_Key >= KEY_NUMBER)
{
// P54 = ~P54; //用于测量读按键的时间间隔
LoopCnt_Key = 0;
ReadKey = Port_Key ^ 0xff;
if(Key_Trge && ReadKey)
{
i = ReadKey;
}
Key_Trge = ReadKey & (ReadKey ^ ContKey);
ContKey = ReadKey;
}
return i;
}
假定主循环时间在 【50mS ~ 10mS】
那就查询,主循环中查询到连续2次读按键是按下的状态
就认为有该按键事件 !
处理完该按键事件后,要判断该按键是否已被释放
===根据实际微调下
在主循环里累计计数值扫描啊,,扫描周期怎么固定呢? 不知道这种方式是否可靠,因为在主程序中的扫描周期可能会不一定的。 经历15年N多项目验证,工作稳定可靠!
读按键的时间间隔30----50ms。-----》修改LoopCnt_Key值。 该代码是在2008年,根据网上的三行按键代码修改而成的。是用在STC89C52上,片内资源太少。
后来虽然MCU的片内资源增加,但该代码工作稳定,移植方便,就一直使用至今。 再补充一点:该代码也移植到ARM核的M0,M0+,M3,M4上面,同样工作稳定可靠。 如果要增加组合键功能,这个还好说点。双击 三击操作如果这个延时检测的时间不确定,会不会造成按键判断失误。这样用户体验效果很差的 单独一个按键的话,我们这里就直接做成长按按键触发功能。
直接就再主函数中轮训按键的IO电平,满足多少次高电平后认为按键按下,测量触发时间。然后给客户说至少要长按多少秒,一般按测量时间的两倍。。
不过我们这里一般按键的功能都是校准什么模块,复位什么模块,就简单的做成长按触发。
我们也有以交互为主的按键,通过按键控制显示屏上的光标等等。所以要用到组合键,双击,长按等等更复杂的操作。如果扫描周期不固定,就不太好做功能性的判断。客户的使用体验就会大打折扣。
所以,这样的用法可以实现么? 这种利用累计循环次数的方法,又称为软定时器。误差在2%---3%左右,一般不超过5%。
我除了用来扫描按键,还用来数码管的动态显示。