本帖最后由 warship 于 2018-9-18 14:09 编辑
//////////////////////////////////////////////////////////////////////////////////
本键盘扫描模块的特点:
一、
使用灵活:一体实现按键的普通、单击、双击、长按、保持以及组合等功能,无须事前为每个按键每种键值逐一进行宏定义,也无须逐一编写各事件的条件判断,
只须为需要的按键事件编写相应的响应代码即可,同时留有特殊键组合等的扩展接口;
可以选择每一按键事件的处理实时性,从而能够使强实时性的紧急按键优先得到处理,可自由选择中断处理及查询处理或二者混合的处理方式,
灵活适配使应用项目能够兼备按键的强实时性要求以及超长(主循环执行一遍的时间长达1秒以上的)程序的适应性。
二、
注重通用:模块设计时注重通用性,按键事件(键值)依简单易懂的标准事件格式编写;除能满足几乎所有按键应用需求外,在按键数量上,
从少到2-4个按键直到最大32个按键(包括端口直联、行列式矩阵、矩阵加直联混合)都可适用。(注:新写了一个4*4矩阵加4键直联混合共20个键的例子参见153楼)
三、
稳定可靠:后台智能抖动消除、按键干扰杂波滤除措施有力,获取按键稳定可靠,不会产生重复按键,即使在CPU非常繁忙时也不会漏失按键。
四、
移植简便:所有可调整参数(数量不多)均以宏定义列出,除与硬件相关(按键个数及连接端口)的部分须根据具体系统修改外,其它均无须变化,很容易移植。
程序可读性强,注释详尽丰富,其中包括函数调用关系及详细运用修改说明,如有未尽事宜,可提出探讨,本人尽量解答修改。
五、
高效节能:消抖无须延时等待,同时采取自适应变频扫键、键盘闲置检测、消抖读键双进程周期差异等多项智能措施尽量减少占用CPU的计算资源。
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//测试平台:ALIENTEK战舰STM32开发板
//按键驱动代码
//正点原子@ALIENTEK
//引用请注明出处:
http://www.openedv.com/forum.php?mod=viewthread&tid=277263,有问题可在本帖中提出讨论,谢谢。
//在网友@学习stm32f4 的建议下,部分源码上传到了
https://github.com/ShuifaHe/STM32.git,新司机上路,请多关照。如果觉得对您有用的话,
请按 “星” 号点一下赞。
//修改日期:2018/9/1
//版本:V2.2,本帖研讨过程详见2楼,鸣谢相关坛友,感谢@正点原子 的支持肯定。
//Made by warship
//////////////////////////////////////////////////////////////////////////////////
下面给出经由原子试验3改造测试通过的程序范例:
回复后可获取解压密码,谢谢支持。游客,如果您要查看本帖隐藏内容请
回复
这个无须调用函数,就是原子的宏定义
#define GET_K0() (!KEY0)
#define GET_K1() (!KEY1)
#define GET_K2() (!KEY2)
#define GET_KWK() (WK_UP) //注意WK_UP按键硬件上是高电平有效
/******************** 用户应用程序按键判断接口函数 *********************************/
//在主循环中调用,返回稳定的键值,用户程序直接处理规定的键值即可。
//想添加什么样的键(类型或组合)就在本函数增加(下列代码仅为示例,包括注释掉的代码也是可用的)。
//可适应的按键类型如下:
//普通:按下即有效,不用等按键释放
//短按:按下再松开后有效,可设置短按时间长度
//长按:按下超过规定的时间,超过后可连续输出,也可设置间隔一定时间输出一次键值
//组合:双键组合(其实多键组合也可同理实现)
/**********************************************************************************/
u8 Get_Key(void)
{
u8 keyp=0;
static u16 OldKeyTime=0;
static u16 OldKeyTrg=0;
static u16 OldKeyCont=0;
KeyRead(); //调用三行读键程序
//以下是按键判断,用户可根据需要随意添加
if((Cont==(KEY0_ON+WKUP_ON)) && KEY0_PRESSED) //KEY0+WKUP组合按键(先按下WKUP再按下KEY0)
keyp=WKUP_PLUSKEY0_PRES;
// else if(Cont==KEY1_ON && KeyTime>=100) //长按键KEY1超过2秒
// keyp=LONG_KEY1_PRES;
else if(Cont==KEY1_ON && KeyTime>=100 && (KeyTime%20==0)) //KEY1超过2秒的长按键,每400ms返回一次键值(可用于常见的快速调整键)
keyp=LONG_KEY1_PRES;
else if((OldKeyCont==KEY0_ON) && KEY_RELEASED && (OldKeyTime<40)) keyp=KEY0_PRES; //短按(时间可设也可不设),松开有效
else if((OldKeyCont==KEY1_ON) && KEY_RELEASED && (OldKeyTime<40)) keyp=KEY1_PRES;
else if((OldKeyCont==KEY2_ON) && KEY_RELEASED && (OldKeyTime<40)) keyp=KEY2_PRES;
else if((OldKeyCont==WKUP_ON) && KEY_RELEASED && (OldKeyTime<40)) keyp=WKUP_PRES;
// else if(KEY0_PRESSED) keyp=KEY0_PRES; //按下即有效
// else if(KEY1_PRESSED) keyp=KEY1_PRES;
// else if(KEY2_PRESSED) keyp=KEY2_PRES;
// else if(WKUP_PRESSED) keyp=WKUP_PRES;
OldKeyTime=KeyTime; //保存上一次读的触发值、按键值及按键时间
OldKeyTrg=Trg;
OldKeyCont=Cont;
return keyp;
}
感谢楼主不断地更新、补充,不知楼主能否利用该按键实现思想将原子的按键实验改写一下,以便大家对比研究探讨。
一周热门 更多>