钱程 赵莎莎
摘 要:文章针对目前单片机矩阵键盘模块的低实时性问题,设计了一种基于TTL去抖算法的单片机矩阵键盘算法。利用TTL去抖算法的间隔时间采样机制以及双循环扫描法的逐行逐列扫描机制,保证矩阵键盘模块响应按键的实时性以及识别按键的准确性。实验结果表明,该矩阵键盘算法识别按键准,响应时间低,能够识别组合键,通用性强。
关键词:矩阵键盘;实时性;去抖;TTL
在嵌入式系统中,矩阵键盘是最常见的输入设备。然而,机械按键在按下和松开时,会产生机械抖动,干扰输入信号。为了避免这种干扰,在扫描矩阵键盘的过程中必须进行去抖[1-3]。
一般的办法是加入去抖延时[4-7],这样虽然能达到去抖的目的,但在延时等待的时候,CPU不能执行其他操作,因此实时性不高。而本文设计的基于生存时间值(Time To Live,TTL)的去抖算法,可以很好地解决上述问题。
本文将双循环扫描法和TTL去抖算法结合起来,以寻求最优算法。
1 TTL去抖算法
1.1 TTL算法
原始的TTL算法,是用在IPv4数据包头部的一个数据段,用于避免数据包在网络上被无限转发[8-9]。
TTL的含义是生存时间值,数据包每经过一个路由器,TTL的值就减1[10]。
如果TTL大于0,说明该数据包有效,应该转发。
反之,如果TTL等于0,说明该数据包已过期,应该丢弃[11]。
1.2 TTL算法的扩展
扩展的TTL算法流程如图1所示,用来判断一个受干扰的信号是否有效。
(1)TTL是不断递减的计数器,每间隔单位时间,TTL就减1,直至减为0。
(2)如果检测到事件信号,TTL就加2。
(3)如果TTL的值大于某个阈值,说明事件已发生,应该处理;反之,如果TTL的值小于某个阈值,说明事件不一定发生,应该忽略。
1.3 TTL去抖算法
扩展的TTL算法,可以用于机械按键的软件去抖,流程如图2所示。
(1)TTL是不斷递减的变量,每间隔单位时间,TTL就减1,直至减为0。
(2)如果检测到按键被按下,该按键的TTL就加2。
(3)如果TTL的值大于某个阈值,说明按键真的被按下了,应该处理;反之,如果TTL的值小于某个阈值,说明按键不一定被按下,应该忽略。
2 改进的矩阵键盘算法
2.1 矩阵键盘模块的原理
本文所采用的开发平台为TX-1C 51开发板。矩阵键盘的原理如图3所示。
2.2 扫描法的选择
2.2.1 线反转法
这种方法是先让4根列线输出0000B,读取4根行线的数据A;再行列反转,即让4根行线输出0000B,读取4根列线的数据B;最后由AB组合成一个8位的二进制数据即为键值[12-13]。
2.2.2 逐行扫描法
这种方法是先让一根行线输出0,其余行线输出1,读取列线的数据,即为该行的键值。逐行扫描,4根行线各自输出一次0,来读取4行的键值[14-16]。
2.2.3 双循环扫描法
顾名思义,这种方法是指在矩阵键盘中,列和行都各自循环扫描[16]。与逐行扫描法的区别在于,逐行扫描法是一次性读取4根列线的值,而双循环扫描法是分别读取4根列线的值。
2.2.4 扫描法的选择
组合键有3种类型,示意如图4所示。
(1)跨行组合键,即同时按住多个按键,且每一行只按下了一个按键。
(2)同行组合键,即同时按住多个按键,且有两个按键恰好在同一行。
(3)三角键,即同时按住多个按键,且有3个按键恰好占了两行两列。
3种扫描法的比较如表1所示。可以看出,线反转法速度最快,而双循环扫描法最适合用组合键。本文选择双循环扫描法。
2.3 软件编程
2.3.1 定义全局变量
(1)uchar key_TTL[16];
对应16个按键的TTL(用于去抖)
(2)uint keys_val=0;
16位组合键的键值(用于按键功能)
(3)uchar max_TTL=3;
TTL的阈值(判断按键信号是否有效)
(4)uint last_keys_val=0;
上一时刻的键值(判断键值变动)
2.3.2 矩阵键盘核心函数
void key_spy(void)
{
uint temp=0;
//双循环扫描法 + 译码
uchar k,l;
for(l=0;l<4;l++)
{
P3=~(0x01< for(k=0;k<4;k++) { if((P3&(0x10< key_TTL[k+l*4]+=2; } } //TTL去抖 for(k=0;k<16;k++) { if(key_TTL[k]>0)key_TTL[k]--; if(key_TTL[k]>=max_TTL){ //把这个if里的>=改为=,就能自动连点 key_TTL[k]--; temp=temp|(1<
}
}
keys_val=temp;
//按键功能
if(keys_val!=last_keys_val){
if(keys_val==((1<<0))){
//TODO:按下了0号键
}
else if(keys_val==((1<<3)|(1<<4))){
//TODO:同时按下了3号、4号键
}
//TODO:加入更多else if,
// 以扩充键盘功能。
}
last_keys_val=keys_val;
}
2.3.3 核心程序的使用方法
在嵌入式系统的主循环或者定时器中断里,加入key_spy(void);这条语句,并在key_spy(void)的按键功能区域,编写按键的处理程序。
2.3.4 改进的矩阵键盘算法的例程
本例程中,矩阵键盘的功能是:通过按特定的组合键,来改变全局变量k1和k2的值。
矩阵键盘和液晶屏的代码省略。
主函数代码如下:
void main()
{
while(1)
{
k3++;if(k3==100)k3=0;
//让k3不断增加
display3n(k1,k2,k3);
//数码管实时显示k1 k2 k3的值
key_spy();
//主循环里加入键盘程序
}
}
图5为例程在TX-1C 51开发板上运行的照片。
6位数码管,左边4位用来输出两个变量k1和k2的值, 右面两位用来输出变量k3的值。
在实际运行中,数码管右边两位的数字在不停变化。从按下按键到松开按键,都不会使这两位数字的变化出现停顿,说明改进的矩阵键盘算法占用CPU资源小。
在按下按键的时候,程序能迅速地相应按键事件,立刻改变k1和k2的值,具有很高的实时性和准确性。
3 评价和推广
3.1 评价
TTL去抖算法是一种间隔时间采样的方法。与传统的延时去抖相比,TTL去抖算法可以很好地利用延时等待的时间,来处理别的任务,从而提高整个系统的实时性。
TTL去抖算法可以配合线反转法、双循环扫描法使用。线反转法扫描得更快,但是不支持组合键;而双循环扫描法扫描得稍慢,支持组合键。这两种方法与传统的矩阵键盘检测方法,在扫描时间上的比较如表2所示。
传统的矩阵键盘检测方法,往往需要等待按键松开,这样按住按键不松,主程序就陷入死循环。
线反转法和双循环掃描法,按不同按键,所需的扫描时间会有细微差别,这是由于按键的检测顺序所导致的。
线反转法和双循环扫描法的实际用时差别不大。测试平台用的是11.059 2 MHz的51单片机。在频率更高的嵌入式系统中,两种算法的实际用时会更短,差别会更小。
3.2 推广
3.2.1 TTL去抖算法用于检测斑马线
TTL去抖算法,可以用于恩智浦杯智能汽车竞赛中,选用线性CCD作为传感器的光电组,用来给二值化后的线性CCD图像检测斑马线,也就是检测起跑线。
二值化后的线性CCD图像是一行像素,一段连续的相同的像素,称为一片区域;两片区域的连接处,称为一个跳变。
(1)TTLA和TTLB是两个不断递减的计数器,每扫描一个像素,TTLA就减1,直至减为0;每扫描一个区域,TTLB就减1,直至减为0。
(2)每扫描到一个跳变,先判断TTLA是否为0,再给TTLA赋初值。
(3)如果检测到跳变的时候,TTLA不为零,那么上一个区域可能属于斑马线,令TTLB加2;反之,如果检测到跳变的时候,TTLA为零,那么上一个区域不属于斑马线。
(4)如果TTLB的值大于某个阈值,说明之前的TTLB个区域确实是斑马线,应该处理;反之,如果TTLB的值小于某个阈值,说明之前的TTLB个区域的不一定是斑马线,应该忽略。
3.2.2 改进的矩阵键盘算法的推广
单片机现场赛,是要求参赛选手在规定时间内按要求编写单片机软件的比赛,需要在最短的时间写好底层驱动,才有时间编写规定的功能。改进的矩阵键盘算法把获取键值、译码、去抖和按键功能几个步骤[15]都精简到一个子函数里,代码短,结构清晰,易于开发,非常适合单片机现场赛。
平衡车,是对实时性要求极高的嵌入式系统。如果因为按键去抖而出现等待延时,那么将极有可能导致平衡车失衡,造成安全隐患。基于TTL去抖算法和线反转法的矩阵键盘算法,将非常适合平衡车。
TTL去抖算法和双循环扫描法组成的矩阵键盘算法,由于支持组合键,且实时性高,可以用来制作按键多的游戏机,还可以用来做游戏键盘。
4 结语
为实现矩阵键盘模块的快速响应以及精准检测,设计了基于TTL的去抖算法的矩阵键盘算法,扫描部分采用双循环扫描法来支持多键齐按的功能。通过实验验证可知:矩阵键盘算法实时性高,识别按键准。
与部分矩阵键盘算法相比,此算法不依赖中断、多线程,因此更适用于前后台系统。代码精简,易于开发单按键、组合键的键盘功能,因此适用于很多场景。
[参考文献]
[1]吉喆.单片机矩阵键盘去抖程序的设计[J].计算机光盘软件与应用,2012(7):167.
[2]崔朋.矩阵键盘在单片机工程中的应用[J].黑龙江科技信息,2016(11):43.
[3]郑采君.基于CPLD的矩阵键盘扫描模块设计[J].电子设计工程,2010(10):169-175.
[4]武志鹏,焦红卫.一种基于矩阵键盘扫描原理的程序设计[J].工业控制计算机,2018(7):141-142.
[5]张成法,马凤娟.基于AT89C52的矩阵键盘编程[J].河北农机,2016(11):46-47.
[6]刘军.4×4矩阵键盘控制LED原理及软硬件设计、仿真调试[J].哈尔滨铁道科技,2015(4):7-11.
[7]李其珂,付红桥.基于嵌入式Linux的矩阵键盘驱动研究与实现[J].重庆理工大学学报(自然科学版),2012(12):88-92.
[8]王建平,左现刚,胡孟杰,等.固定节点3D网格部署的水下传感器网络分簇路由算法[J].火力与指挥控制,2017(5):84-89.
[9]杨建强,宁彬.基于IPv6协议的操作系统指纹识别[J].湖北文理学院学报,2013(5):13-17.
[10]袁福祥,刘粉林,芦斌,等.基于历史数据的异常域名检测算法[J].通信学报,2016(10):172-180.
[11]危婷,冷峰,张跃冬,等.DNS服务器缓存失效过程的研究[J].电信科学,2013(9):94-97.
[12]曾晓春.线反转法矩阵键盘程序设计[J].科技创新与应用,2013(23):14.
[13]段崇秀.单片机中的矩阵键盘编程[J].硅谷,2012(5):172.
[14]周正贵.基于单片机技术的按键扫描电路分析[J].信息与电脑(理论版),2018(13):29-30.
[15]刘宸,黄世瑜.对电平计时的矩阵键盘识别方法研究[J].通信电源技术,2018(2):5-6,10.
[16]黄丽英,章敏.浅析基于AT89C51矩阵键盘检测的编程技巧[J].科技创业家,2013(2):160-161.