本次设计采用FPGA驱动4x4矩阵键盘,这个原理其实很简单,但是我在做的时候曾经理解错了一个地方,导致走了一天的弯路,因为感觉比较有意思,所以想在这分享一下。
014x4矩阵键盘驱动原理
首先看一下矩阵键盘的原理图,矩阵键盘的原理与独立按键类似,可以将单独的一行或一列当做一个独立按键使用。图中的row_one ~ row_four表示矩阵键盘的四行,col_one~col_four表示矩阵键盘的四列。
矩阵键盘的扫描识别可以通过行列扫描来完成,首先我们先将4行的I/O口(row_one、row_two、row_three、row_four)全部输出高电平,4列的I/O口(col_one、col_two、col_three、col_four)全部输出低电平,若是这4行按键里有按键按下,那么按键按下的那一行对应的I/O口电平就会被拉低,这样我们就能确定按下按键的行坐标。接下来便需要确定列坐标,获取列坐标的方法与行坐标的方法类似,就是先让4行的I/O口全部输出低电平,4列的I/O口全部输出高电平,这样按键按下的那一列I/O口的电平就会被拉低,这样我们便确定了对应的列坐标,如此便能获取到对应按下按键的行列坐标。
02设计思路
这里需要讨论的便是如何实现4×4矩阵键盘的程序,其逻辑流程图如下图所示。首先需要定义8个输出端口,分别表示四行四列,然后先让四行的I/O输出高电平,四列的I/O输出低电平,这是初始状态。然后便是编写消抖程序,当有按键按下时,首先便是进行消抖,利用状态机编写消抖程序,识别判断当前状态是否为抖动。确定为按键按下后便开始判断4行中哪一行的电平被拉低,这样便能确定是哪一行的按键被按下,这里需要定义一个表示行的标志位,用来标志是哪一行按键按下。随后便将四行的I/O输出低电平,四列的I/O输出高电平,然后便开始逐列判断哪一列的电平被拉低,如此便能判断按下按键的列坐标。此处也需要定义一个表示列的标志位。最后便是综合判断,通过行的标志位和列的标志位来判断按下按键的行列坐标,如此便确定具体按下的按键。
接下来看程序(此处分享的程序为没有带按键消抖的,只是按照矩阵键盘的扫描识别思路大致写了一下),首先是端口的定义,定义四行四列,但是有一点,原理上讲解的是输出电平,在这里这四个端口先定义为输入状态,因为这不是顶层文件,在顶层文件中再定义为输出。然后定义的key_lock为输出控制端,我这里是利用矩阵键盘设置的密码锁,每一个矩阵按键对应一个键值,当按下四个按键对应密码正确时,key_lock输出高电平。key_row_flag为行标志位,当检测到第一行的按键被按下时标志位置1,当第一行的按键被按下时标志位置2,同理,第三行置3第四行便置4。key_col_flag为列标志位,原理与行标志位一样。然后row_flag与col_flag为行扫描标志位与列扫描标志位,当row_flag为1时进行行扫描,当col_flag为1时进行列扫描。key_output为输出按下对应按键的键值。key_row_col为当前扫描状态,为1时表示行扫描结束,为2时表示列扫描结束,标志列扫描结束后便开始获取按键的键值。
接下来便开始看行扫描,行扫描和列扫描初始状态为row_flag为1、col_flag为0。然后开始捕捉四行的引脚哪一行的引脚出现下降沿置0,若有一行的引脚被拉低置0时,行标志位立刻记下是第几行被拉低,然后行列状态标志位便置1,行扫描标志位row_flag清零,列扫描标志位置1,开始进入列扫描。
然后就是列扫描,在列扫描中与行扫描原理一样,检测每一列引脚的电平,若其中一列的电平被拉低,则列标志位立刻记录被拉低的列数为第几列,然后恢复行扫描标志位准备进入下一轮扫描,同时将列扫描标志位清零,行列状态标志位置2,准备进入判断按下按键键值模式。
接下来便是开始判断按下按键的键值,因为我这里只需要0~9这十个数字,而矩阵键盘有16个按键,所以写的稍微简单一点。从第一行第一列开始为1,第一行第二列为2,后面的依次类推。将第四列和第四行的键值全部设置的为0。这里进入判断键值的条件为行列标志位key_row_col置2,也就是必须在列扫描完成之后才能进入判断。
这里在键值判断完成之后便是将当前获取的键值存储起来。这里因为行列标志位key_row_col比按键输出键值key_output差了一个时钟周期,所以赋值错误,然后我便重新定义了一个寄存器key_row_col_r用来过渡一下。下面定义的one起初是为了在key_row_col为2时不重复赋值才写的,是为了避免赋值后面输出的按键键值,也就是20ns的周期中只进去赋值一次,但是后面发现了时序相差一个时钟周期便在else中加入了那段,还未解决便定义了寄存器key_row_col_r,这才得以解决。
最后便是设置密码,输出控制部分。此处将密码设置为2653。
接下来便是波形仿真部分,在这里写入2653每一个键值对应按键的行列坐标便可。仿真脚本文件写好之后便可导入仿真。
03仿真波形
在仿真波形图中根据写入的对应键值来观察行、列标志位中的行列坐标是否正确,然后根据行列坐标来观察按键输出键值key_output是否一致,key_temp系列的值为存储的四位密码,当每一位与设置的密码一致时,key_lock输出高电平。
全部0条评论
快来发表一下你的评论吧 !