APP下载

基于统计溢出的矩阵键盘程序设计

2023-06-09张星张睿智郝琛姚美菱

电子制作 2023年8期
关键词:键值按键键盘

张星,张睿智,郝琛,姚美菱

(石家庄邮电职业技术学院 智能工程系,河北石家庄,050021)

0 引言

矩阵键盘模块是工业电子产品常用的输入设备,比如需要输入简单数字字符的快递柜、存包柜等,如图1所示,常见的矩阵键盘样式有4×3(12 键)和4×4(16 键)的,键盘材质有薄膜键盘型、直插按键型、ABS 外壳键盘型等。

图1 多种材质样式的矩阵键盘

矩阵键盘由于按键机械特性及电路构成结构等原因,在按键按下及松开瞬间触点电压跳变会引起现按键自身及按键之间的电压抖动,造成按键误判错误输入。按键输入过程包括去除抖动和按键识别,去除抖动可以通过程序设计和硬件设计两种方法实现。作者在设计快递柜产品使用无硬件去抖的矩阵键盘时发现,采用顺序扫描的按键识别方法,一定概率会出现按键误判错误输入,影响了使用者体验,经实验发现不同材质样式的矩阵键盘出现错误的概率也不同,塑料矩阵键盘按键时震动较大,出现误判错误的概率高一些。

如图2所示,智能快递柜中使用矩阵键盘,用户在通过按键输入操作完成取件。通过矩阵键盘输入的数字及字符在ST7920 液晶屏(12864 字库型)上显示,因快递柜主控板使用的STM32 单片机主频高,片上资源丰富,快递柜系统任务占用不高,可以通过提高矩阵键盘占用单片机运行资源的方法减少按键误判的概率,提高键盘输入流畅度,改善用户使用体验。

图2 矩阵键盘在智能快递柜中的使用

1 矩阵键盘按键识别及抖动去除

4 行4 列式矩阵键盘的电路仿真原理如图3所示,按键组成行列矩阵形式,水平方向的行线和垂直方向的列线,在两条线交叉的地方没有直接相连,通过1个机械按键控制交叉触点的连接或断开,4 行4 列式矩阵键盘能够组合成16个按键输入。

图3 4×4矩阵键盘原理图

矩阵键盘的行线和列线分别连接STM32 单片机的4个GPIO口,共计8 条线,如果是按键直连单片机GPIO口,16 键键盘需要占用16个GPIO口,将多占用1 倍IO 资源。显然,使用矩阵键盘的优势是减少GPIO口的占用,但随之而来的是造成按键识别难度增加,按键间的相互干扰增大,需要设计出相对复杂的识别及去抖程序。

(1)行列顺序扫描按键识别法

行列顺序扫描按键识别法的基本思路是,行线依次置零,按照列线顺序读取,当列线读到零,置零的行和读到零的列交叉的位置就是被按下的按键。

首先将所有行列对应的GPIO口设置为高电平,随后将第1 行对应GPIO口设置为低电平,依次读取1 到4 列对应GPIO口数据,如果列线GPIO口的数据等于零(相当于低电平),表示第1 行当前列有按键按下,所有行列对应的GPIO口设置为高电平,程序跳出循环返回。如果没有读到数据零,则将2 行对应GPIO 引脚设置为低电平,依次读取1 到4 列对应GPIO口数据,如果列线GPIO口的数据等于零,表示第2 行当前列有按键按下,所有行列对应的GPIO口设置为高电平,程序跳出循环返回。按照上面规则遍历所有行线的所有列线找出可能的按键位置,将键值返回给主程序,主程序根据键值执行相应的处理操作。

使用矩阵键盘时,在按键按下及松开瞬间触点电压跳变会引起现按键自身及按键之间的电压抖动,造成按键误判引起输入错误,所以需要在按键识别程序中加入去抖处理,如图4所示,可以采用延时二次判断的方法消除按键抖动影响,在第1 次按照行列顺序扫描法检测到有按键按下后,采用程序定时延时,让单片机空闲10ms 后,再次扫描键盘判断键盘状态。若2 次判断都是同一按键,则确定并返回该按键值,否则清除按键判定状态,重新进行按键判定。

图4 行列扫描软件去抖流程图

使用软件定时延时会浪费单片机时间资源,如果单片机中断资源丰富,可以给矩阵键盘输入GPIO口设置中断,减少延时造成的单片机时间占用;或者让单片机运行实时系统,将按键扫描设计为系统任务也可减少单片机时间浪费。

(2)问题及改进

在快递柜中使用塑料矩阵键盘实验时,会出现小概率的错误输入,分析原因发现,塑料键盘按键时震动较大,会引起相近触点的较长时间的电压变化,造成按键误判。比如“A”键按下时,引起“6”“9”按键触点电压变化,按照顺序判决规则,“6”“9”键判定次序在“A”键之间,假设“6”“9”键电压变化持续时间超过去除抖动的延时时长,这时就产生误判。如果增加软件延时时间,能减少误判概率,但会造成输入迟滞、影响用户体验。

改进思路是,“6”“9”键的电压变化由于按键“A”按下引起的,其电压变化量和持续时间必然比按键“A”低,在一定时间内进行多次判定,并对多次按键判定值统计,计数最高且溢出门限的键值作为最终按键判定,这种方法找出真正的按键“A”概率最高,误判最少。单片机主频高,IO 输出速度快,单次按键判定的时间可以做到很小,从而既提高了识别准确度,又减少了输入响应时间。

2 程序设计

基于统计溢出方法,根据STM32 单片机中断、定时器资源优化矩阵键盘识别去除抖动程序。

■2.1 程序流程

基于统计溢出的矩阵键盘按键识别程序流程如图5所示,系统上电后,对STM32 单片机定时器、键盘GPIO、液晶屏GPIO 等设备进行初始化设置后进入主循环,定时器产生中断后,检测矩阵键盘状态,统计按键值,主循环按键判断程序根据按键统计值,做出按键判定,通过ST7920 液晶屏显示键值并执行相应的操作。

图5 基于统计溢出的矩阵键盘按键识别流程图

■2.2 程序实现

系统软件关键程序包括键盘初始化、定时器初始化、按键检测等。

(1)矩阵键盘初始化程序

在key.c 文件中编写矩阵键盘初始化程序。在KeyIO 结构体数组中填写8 组GPIO 引脚数据{GPIO 引脚组和GPIO 引脚},前4 组对应矩阵键盘行线,后4 组对应矩阵键盘列线。

typedef struct{GPIO_TypeDef* GPIOX; unsigned int GPIO_Pin;} KEYIO[2][4];

KEYIO KeyIO= {{{IO1引脚组,组内序号},{IO2引脚组,组内序号},...,{IO8 引脚组,组内序号}}};

使用枚举数组定义存储GPIO 引脚可以使引脚调整更简单,可根据STM32 开发板引出的GPIO 进行调整,引脚不需要在同一GPIO 引脚组,也不需要顺序相邻。

OverflowTimes = 50;

unsigned char Key_Times[17]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

Key_Times 数组用于存储按键判定统计值,数组的1-16元素指对应矩阵键盘的16个按键,数组17 元素对应无输入按键判定计数,OverflowTimes 是统计溢出门限参数,可根据屏幕响应时间、系统负荷、实际使用体验调整。

void KEYClock_Init(void){ RCC_APB2PeriphClock Cmd(RCC_APB2_GPIOX,ENABLE);}

KEYClock_Init()函数用于打开键盘GPIO 对应的时钟,RCC_APB2_GPIOX 要包括矩阵键盘所有GPIO 所在的引脚组。键盘GPIO 初始化函数KEY_Init()完成对矩阵键盘使用GPIO 初始化设置,其中4 条行线对应GPIO 引脚设置为推挽输出即GPIO_Mode_Out_PP,4 条列线对应GPIO 引脚设置为上拉输入即GPIO_Mode_IPU,GPIO 引脚速度均设置为50MHz 即GPIO_Speed_50MHz。

(2)定时器初始化及中断处理程序

定时器初始化函数TIM4_Int_Init( )在timer.c文件中,使用TIM4 定时器,并设置中断优先级、时钟分频因子、定时量、计数模式、开启定时器4 中断。

定时器中断处理TIM4_IRQHandler( )函数如下所示,在TIM4 中断中完成软件看门狗设置、息屏计数、系统状态标志设置等。

void TIM4_IRQHandler(void) {

if (TIM_GetITStatus(TIM4, TIM_IT_Update) !=RESET) {

TIM_ClearITPendingBit(TIM4, TIM_IT_Update); //定时器像清除标志位

IWDG_Feed();//软件看门狗设置

Idle_Time++;//息屏计数器KEY_Scan_Timer();

if(Idle_Time>1800){

global_state=0;

Idle_Time=0;

Idle_Run=0; } } }

基于定时器的矩阵键盘扫描判定统计KEY_Scan_Timer(void)函数如下所示,依次将行线设置为高电平,判断可能的按键并计数统计。

void KEY_Scan_Timer(void){

unsigned char i,j,k;

extern unsigned char Key_Times[16];for(j = 0; j<4; j++){

Key_Times[16]++;//默认无输入,则Key_Times[16]加1

for(k = 0; k<4; k++) {

if(GPIO_ReadInputDataBit(KeyIO[1][k].GPIOX,KeyIO[1][k].GPIO_Pin)== 0){

Key_Times[j*4+k]++;//检测列 列值为 i

Key_Times[16]--;} }//有按键则Key_Times[16]减1 GPIO_SetBits(KeyIO[0][j].GPIOX,KeyIO[0][j].GPIO_Pin); } }

(3)基于统计溢出的单键、长按键识别程序

找出判定次数最多的键值,如果该键统计值大于溢出门限,则最终判定本次输入有效键值为该按键,如果本次有效按键和上一次按键相同,则RepeatKeyTimes 加1。在主程序循环中做长按键处理,如果本次有效按键和上一次按键相同3 次以上,则判定为长按键,执行长按键并将RepeatKeyTimes 置零。

for(i = 0; i<17; i++){

课程目标是体现课程理念、展现课程价值追求的核心部分,在经历活动实施过程中应以幼儿的成长为核心,关注幼儿的体验、情感、态度和综合能力的发展,制定经历活动的总目标。为了使活动目标具有更强的指向性和导向性,使教师在具体的实施过程中能更准确地把握教育目标,可对总目标进行分解和细化,同时,在设置经历活动总目标的基础上,针对大、中、小班幼儿的年龄特点、认知水平、实践能力,制定各个不同年龄段的具体目标,并在此基础上确立各个经历活动目标。利用三级目标体系使经历活动目标层次化,且不同层次目标间具有一致性和联系性,为教师的实践操作提供落脚点和正确方向。

if( Key_Times[i]>FirstKeyTimes){

FirstKeyTimes=Key_Times[i];

FirstKeyNumber=i; }

if(FirstKeyTimes > OverflowTimes) {

if(FirstKeyNumber==LastKeyValue){

RepeatKeyTimes++; //长按判断

}else{ RepeatKeyTimes=0; }

for(j = 0; j<17; j++){

Key_Times[j]=0;}LastKeyValue =FirstKeyNumber; } }

(4)基于统计溢出的组合键识别程序

找出判定次数前2 名的键值,如果排名第2的判定统计值大于溢出门限,且长时间按下,则最终判定本次输入有效键值为双键组合。

for(i = 0; i<17; i++){

if( Key_Times[i]>=FirstKeyTimes) {

SecondKeyTimes=FirstKeyTimes;

SecondKeyNumber=FirstKeyNumber;

FirstKeyTimes=Key_Times[i];

FirstKeyNumber=i; }

if( SecondKeyTimes > OverflowTimes){/*执行双键组合特殊操作*/ }

else if(FirstKeyTimes > OverflowTimes){

if(FirstKeyNumber==LastKeyValue){

RepeatKeyTimes++; } //长按

else { RepeatKeyTimes=0; }

for(j = 0; j<17; j++){

Key_Times[j]=0;}

LastKeyValue =FirstKeyNumber; } }

3 验证

如图6所示,在使用改进后的基于统计溢出的矩阵键盘按键识别程序后,快递柜按键输入流畅度明显提升,得到较好的使用体验评价。

图6 快递柜产品应用

4 结语

本文针对行列扫描延时去抖法进行矩阵键盘按键识别时存在的按键误判问题,使用基于统计溢出的按键识别方法改进程序设计,提高按键识别准确率,降低按键误判概率。在快递柜产品的实际应用中,键盘输入流畅度提升,用户使用体验得到改善。

猜你喜欢

键值按键键盘
你知道手机拨号键盘上为什么要有*和#吗?
键盘猫
基于有限状态机的按键检测程序设计
非请勿进 为注册表的重要键值上把“锁”
Cлово месяца
ikbc R300机械键盘
一键直达 Windows 10注册表编辑高招
一种多方向导光按键结构设计
按键的多种状态检测及消抖处理方法
解析某型号手机按键检测程序的缺陷