实验设计目标
在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式。在矩阵键盘中,行线和列线不直接连通,而是通过一个按键进行连接。本实验实现的功能非常简单,为矩阵键盘的十六个按键编号为0~15,按下哪一个按键,数码管就显示该按键对应编号的十六进制数。
实验设计思路
如下是本文所使用的FPGA开发板上板载矩阵键盘的原理图。
图9.1 矩阵键盘原理图
从图9.2中可以看到,键盘的列线已经都设置了上拉电阻,在没有按下按键时,键盘列线的为高电平。若给键盘的某一行输入低电平,并按下该行的一个按键,那么该按键连接的列线的输出就会被拉低。因此,使用FPGA驱动矩阵键盘时,一般通过输送高/低电平给矩阵键盘的行信号,并读取键盘列信号来判断是否有按键按下。举个例子,按照上图中,Key_Row[0]~Key_Row[3]为矩阵键盘的行信号,Key_Col[0]~Key_Col[3]为矩阵键盘的列信号,若给Key_Row[0]输送低电平,读取键盘列信号Key_Col[3:0]的结果为1011,则说明KEY2被按下了。
图9.2 基于FPGA的矩阵键盘驱动
对于列线已设置上拉的矩阵键盘,应该通过对所用的行线输送低电平信号,读取列信号的值,如果某一列的信号低电平,则说名该行列交叉处的按键被按下。由于本例中将使用所有的按键,如果对所有的行线都输送低电平信号,即使读到了某一列的电平信号为低也无法判定是哪一行的按键,这时就需要采用行扫描法。其原理也非常简单,即按照合适的扫描频率依次给各行输送低电平信号,当前行列电平信号均为低的按键就是被按下的按键。
图9.3 顶层电路框图
根据实例二的需求进行功能划分,一共有四个功能模块,分别是按键扫描模块、按键消抖模块、独热码转BCD码模块和数码管段码译码模块。其中,按键扫描模块负责监测矩阵键盘的列信号并对矩阵键盘进行逐行扫描,并将判定后的按键信号输出;按键消抖模块负责接收按键扫描模块得到的按键信号并进行消抖处理;独热码转二进制数模块则用于将消抖后的按键信号转换为二进制数;最后由数码管段码译码模块进行译码并驱动数码管的显示。
功能模块图与输入输出引脚说明
该工程包含顶层模块keyboard_instance与底层模块keyboard_scan、key_filter、onehot2binary和Digitron_NumDisplay_module。整个工程的模块功能图参考图9.3即可。下面介绍一下顶层模块各主要引脚的功能:
- clk_50M:50MHz的基准时钟信号输入。
- RSTn:系统复位输入信号。低电平有效,控制是否开始扫描矩阵键盘。
- col:矩阵键盘的列信号。
- row:矩阵键盘的行信号,通过顺序对4个信号赋值0,获取按键信息。
- Digitron_Out:七段数码管的显示输出,共有八位总线。
- DigitronCS_Out:数码管的片选信号,共有四位总线。
程序设计
下面给出了矩阵扫描模块的参考代码,通过移位操作周期性地为矩阵键盘的行信号输送1110、1101、1011、0111的电平信号,实现行扫描。可以注意到,在时序设计上,行信号的移位操作是在扫描时钟的上升沿进行的,而列信号的采集是在扫描时钟的下降沿进行的。分析代码不难得出,如果有按键按下(这里仅考虑一次只按下一个按键),该模块的按键信号输出key会是一个16bit的独热码。
图9.4 矩阵键盘扫描方式
下面给出了独热码转二进制模块,实现将消抖后的按键信号转化为可供现成的数码管段码译码模块进行显示译码的编码。由于位数较少,直接使用查表的方法实现。另外,该模块引入了时序电路,还含有实例一中那个带使能端的寄存器类似的功能,即松开按键后,该模块的输入为16bit的全零信号,此时按照如下代码的描述将不会更新编码输出,而是保持上次按下按键时相同的输出,故不需要一直按住按键来保持数码管的显示。
图9.5 独热码转二进制模块
FPGA管脚配置
以下是Anlogic FPGA的IO Constraint,CLK时钟输入信号、数码管片选信号DigitronCS_Out和数码管输出显示信号Digitron_Out的配置方式与实验六相同,DIG1~DIG2显示按键信息,复位信号RSTn与SW0相连,col和row与矩阵键盘8个引脚相连。
set_pin_assignment { DigitronCS_Out[0] } { LOCATION = C9; IOSTANDARD = LVCMOS33; }
set_pin_assignment { DigitronCS_Out[1] } { LOCATION = B6; IOSTANDARD = LVCMOS33; }
set_pin_assignment { DigitronCS_Out[2] } { LOCATION = A5; IOSTANDARD = LVCMOS33; }
set_pin_assignment { DigitronCS_Out[3] } { LOCATION = A3; IOSTANDARD = LVCMOS33; }
set_pin_assignment { Digitron_Out[0] } { LOCATION = A4; IOSTANDARD = LVCMOS33; }
set_pin_assignment { Digitron_Out[1] } { LOCATION = A6; IOSTANDARD = LVCMOS33; }
set_pin_assignment { Digitron_Out[2] } { LOCATION = B8; IOSTANDARD = LVCMOS33; }
set_pin_assignment { Digitron_Out[3] } { LOCATION = E8; IOSTANDARD = LVCMOS33; }
set_pin_assignment { Digitron_Out[4] } { LOCATION = A7; IOSTANDARD = LVCMOS33; }
set_pin_assignment { Digitron_Out[5] } { LOCATION = B5; IOSTANDARD = LVCMOS33; }
set_pin_assignment { Digitron_Out[6] } { LOCATION = A8; IOSTANDARD = LVCMOS33; }
set_pin_assignment { Digitron_Out[7] } { LOCATION = C8; IOSTANDARD = LVCMOS33; }
set_pin_assignment { RSTn } { LOCATION = A9; IOSTANDARD = LVCMOS33; }
set_pin_assignment { clk_50M } { LOCATION = R7; IOSTANDARD = LVCMOS33; }
set_pin_assignment { col[0] } { LOCATION = E11; IOSTANDARD = LVCMOS33; }
set_pin_assignment { col[1] } { LOCATION = D11; IOSTANDARD = LVCMOS33; }
set_pin_assignment { col[2] } { LOCATION = C11; IOSTANDARD = LVCMOS33; }
set_pin_assignment { col[3] } { LOCATION = F10; IOSTANDARD = LVCMOS33; }
set_pin_assignment { row[0] } { LOCATION = E10; IOSTANDARD = LVCMOS33; }
set_pin_assignment { row[1] } { LOCATION = C10; IOSTANDARD = LVCMOS33; }
set_pin_assignment { row[2] } { LOCATION = F9; IOSTANDARD = LVCMOS33; }
set_pin_assignment { row[3] } { LOCATION = D9 ; IOSTANDARD = LVCMOS33; }
实验结果
当按下矩阵键盘时候,数码管最低位会以16进制显示编号。
END
文章来源:https://www.yuque.com/yingmuketang/01/qah40q
推荐内容
- 【安路 EG4S20 版本】基础板卡信息及使用教程:芯片和板卡简介
- 【安路 EG4S20 版本】基础板卡信息及使用教程:第一工程
- 【安路 EG4S20 版本】基础板卡信息及使用教程:使用ChipWatcher
- 【安路 EG4S20 版本】基础板卡信息及使用教程:使用Modelsim
- 【安路 EG4S20 版本】基础实验设计与实现:实验1 流水灯
- 【安路 EG4S20 版本】基础实验设计与实现:实验2 集成逻辑门及其基本应用
- 【安路 EG4S20 版本】基础实验设计与实现:实验3 译码器 编码器
- 【安路 EG4S20 版本】基础实验设计与实现:实验4 数据选择器
- 【安路 EG4S20 版本】基础实验设计与实现:实验5 触发器
- 【安路 EG4S20 版本】基础实验设计与实现:实验6 加法计数器
- 【安路 EG4S20 版本】基础实验设计与实现:实验7 抢答器
- 【安路 EG4S20 版本】基础实验设计与实现:实验8 功能数字钟
更多内容请关注走进FPGA专栏