首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

FPGA矩阵键盘驱动设计与验证

FPGA矩阵键盘驱动设计与验证

课程简介

本章我们主要是来实现用verilog语言实现矩阵键盘的驱动。提到矩阵键盘,许多读者应该不会陌生,因为学过单片机ARM的人都应该知道并用C语言做过矩阵键盘的驱动。本章作者将用verilog语言来写一个矩阵键盘(4*4)的驱动,并用LED灯的状态指示按键的状态。课后会留有和本章内容有关的作业,希望所有读者能独立完成作业。接下来就让我们一块走进今天的学习内容“矩阵键盘学习之旅”。

矩阵键盘诞生的背景

相信许多人经常用到矩阵键盘但是却不知道“它”的由来。由于最早的MCU(即单片机)其IO口相对较少,而且用到按键过多的话,就会占用过多的IO。人们为了解决这个问题就引入了“矩阵键盘”。在矩阵键盘中,每条行线和列线在交叉处都不是直接连同,而是通过一个按键直接相连,这样以来一个4*4的矩阵键盘只需要8根控制线就可以完成16个按键的控制。下面就是常见的两类4*4矩阵键盘:


  图1.芯航线矩阵键盘

     图2.淘宝

         

   注意:我们的键盘是有上拉电阻的,而淘宝上的这款没有上拉所以不能直接用的。

矩阵键盘工作原理

要说起矩阵键盘是如何工作的?就得从它的硬件原理图来理解它工作机理。啥话不说,直接上图有图有真相。

   通常我们检测矩阵键盘中某一按键是否被按下,常用的方法是行扫描法。图中一共有8条控制线,4条行控制线(ROW),4条列控制线(COL),而且可以看到8条控制线的初始状态都位高电平。那我们如何去检测某一个按键被按下,并且还能找到其具体的位置?假如我们让COL0=0,然后去逐行的进行扫描每一行,如果ROW0=0出现低电平通过20ms的延迟再次判断该行是否仍然为零,如果仍然为零,那么说明按键0被按下。其它按键的检测类似这种方法。例如:

       如果COL=4’b0100时,当检测到ROW=4’b1011,则说明“A”被按下;可能这块有些读者会说为啥不是“5”被按下?如果有读者提出这个疑惑的话,那就很有必要跟着作者学完这节课,再仔细思考思考。




总体框架图

端口列表如下:


状态转移图

现在作者就来给大家讲解今天的重点,状态转移图的设计。可能会有读者说,这个东西有什么用处?给大家举个例子,“如何去建筑一座楼房”。在建造前肯定是工程师设计建筑的建造图纸,然后工人们按照图纸进行分工建造房屋。今天作者讲的状态转移图就像是工程师设计图纸没有图纸,直接编代码,肯定会来回修改多次。下面进入正题:

       矩阵键盘的状态转移图如下所示:

       1、IDLE状态:主要是用来检测是否有按键被按下,无按键按下时,行控制线Key_Board_Row_i等于15,有按键按下时Key_Board_Row_i不等于15,则进入P_FILTER状态;

       2、P_FILTER状态: 主要是进行按键消抖检测,判断是否有按键真实被按下,如果有按键真实被按下则跳转至下一个状态READ_ROW_P获取行状态的值,否则不跳转;

       3、READ_ROW_P状态:读取行状态并将存入的寄存器中Key_Board_Row_r(ps:存入寄存器是因为按键按下的时间比较短暂,所以要将其状态缓存起来),并将第0列拉低,进入SCAN_C0状态进行行扫描;

       4、SCAN_C0状态: 进行列扫描,来判断该列是否有按键被按下(ps:通俗地讲就是确定按键位置),判断行输入是否等于15,如果不等于则说明该列有按键被按下,否则将第1列拉低,状态跳转到SCAN_C1状态进行行扫描;

       5、SCAN_C1状态: 进行列扫描,来判断该列是否有按键被按下(ps:通俗地讲就是确定按键位置),判断行输入是否等于15,如果不等于则说明该列有按键被按下,否则将第2列拉低,状态跳转到SCAN_C3状态进行行扫描;

       6、SCAN_C2状态: 进行列扫描,来判断该列是否有按键被按下(ps:通俗地讲就是确定按键位置),判断行输入是否等于15,如果不等于则说明该列有按键被按下,否则将第3列拉低,状态跳转到SCAN_C3状态进行行扫描;

       7、SCAN_C3状态: 进行列扫描,来判断该列是否有按键被按下(ps:通俗地讲就是确定按键位置),判断行输入是否等于15,如果不等于则说明该列有按键被按下,否则状态跳转到PRESS_RESULT状态输出扫描结果;

       8、PRESS_RESULT状态: 输出扫描结果。这块给大家教一种比较特别的方法来确定整个键盘上只有一个按键被按下:4位行控制线如果4位行线值加起来如果等于3则说明有一行被按下:

(Key_Board_Row_i[0]+ Key_Board_Row_i[1]+Key_Board_Row_i[2]+ Key_Board_Row_i[3]=3),同样如果4位列控制线值加起来如果等于1则说明有一列被按下:

(Col_Tmp [0]+ Col_Tmp [1]+ Col_Tmp [2]+ Col_Tmp[3]=1)

通过这两个参数的限定,确保了只有一个按键被按下。如果不满足,则不产生检测成功标志信号。状态跳转到WAIT_R等待按键释放状态

       9、WAIT_R状态: 等待按键释放,如果Key_Board_Row_i=15则说明按键被释放,状态跳转到释放消抖状态R_FILTER

       10、R_FILTER状态:检测按键是否完全被释放如果释放则跳转到READ_ROW_R状态读取按键行输入状态,读取行的状态。

       11、READ_ROW_R状态:读取按键行输入状态。


通过这些状态,我们把一个按键按下,到释放的过程完美的进行了一次检测,最终将输出结果用LED灯的状态表示。接下来,就是照着下面的状态转移图敲写程序。这下读者们可以自由选择语言编程,Verilog或者VHDL随意选,然后去盖起自己的矩阵键盘“大厦”。


返回列表