本实验要求完成的内容是用 Verilog HDL 硬件描述语言设计矩阵键盘值读取电路,实现对 4*4 矩阵键盘按下键的键值的扫描和读取,并在七段显示器上显示按下的对应键值。
按键盘的定义,按下 “*” 键则在七段显示器是显示 “E” 键值。按下“#”键在七段显示器上显示 “F” 键值。其它的键则按键盘上的标识进行显示。
一、实验分析与设计
键盘扫描的实现过程如下:对于 4×4 键盘,要识别按键,只需要知道是哪一行和哪一列即可。
为了完成这一识别过程,可首先固定输出入4 行为高电位,然后输出 4 列的值。
再读入输入的 4 行的值,通常高电位会被低电位拉低。即如果输出某列值为 0 ,且该列有按键被按下,那么按键的行值会被列值拉低为 0 。
如果读入的 4 行均为高电位,那么该列肯定没有按键按下。否则,如果读入的 4 行有一位为低电位,那么表示该列有按键被按下,根据输入 4 行的值,可确定按键的行值。这样便可以获取到按键的位置。
即如果输出列值KEY_C = {1,0,1,1}。如何获取行值为KEY_R = {1,1,1,1},表示第二列无按键按下; 获取行值为KEY_R = {1,1,0,1},表示第二列有按键按下,且行值为3。可得按键位置。
二、程序代码
module sy2(clk,key_R,key_C,Q);
input clk;
input[3:0] key_R; //输入四行
output reg[3:0] key_C; //输出四列
output reg[7:0] Q; //对应的值
reg flag;
reg [1:0]row;
always @(posedge clk) //检测该列是否有按键被按下
begin
if(key_R==4'b1111) //无值按下
flag=0;
else //有值按下
flag=1;
if(flag==0) //判断下一列
row=row+1;
end
always @(posedge clk)
begin
case(row)
0:key_C=4'b1110;
1:key_C=4'b1101;
2:key_C=4'b1011;
3:key_C=4'b0111;
endcase
end
always @(posedge clk)
begin
case({key_R,key_C})
8'b11101110:Q=8'h06;
8'b11101101:Q=8'h5b;
8'b11101011:Q=8'h4f;
8'b11100111:Q=8'h77;
8'b11011110:Q=8'h66;
8'b11011101:Q=8'h6d;
8'b11011011:Q=8'h7d;
8'b11010111:Q=8'h7c;
8'b10111110:Q=8'h07;
8'b10111101:Q=8'h7f;
8'b10111011:Q=8'h6f;
8'b10110111:Q=8'h39;
8'b01111110:Q=8'h79;
8'b01111101:Q=8'h3f;
8'b01111011:Q=8'h71;
8'b01110111:Q=8'h5e;
endcase
end
endmodule
注意Key_R和Key_C与按键的引脚连接
三、ModelSim仿真
Test Bench文件
`timescale 1 ps/ 1 ps
module sy2_vlg_tst();
reg [3:0] KEY_C;
reg [3:0] KEY_R;
// wires
wire [7:0] Q;
sy2 i1 (
.KEY_C(KEY_C),
.KEY_R(KEY_R),
.Q(Q)
);
initial
begin
KEY_R = 4'b1111;
KEY_C = 4'b1111;
//第一行
#10
KEY_R[0] = 0;
KEY_C[0] = 0;
#10
KEY_C[0] = 1;
KEY_C[1] = 0;
#10
KEY_C[1] = 1;
KEY_C[2] = 0;
#10
KEY_C[2] = 1;
KEY_C[3] = 0;
#10
KEY_R[0] = 1;
KEY_C[3] = 1;
//第二行
#10
KEY_R[1] = 0;
KEY_C[0] = 0;
#10
KEY_C[0] = 1;
KEY_C[1] = 0;
#10
KEY_C[1] = 1;
KEY_C[2] = 0;
#10
KEY_C[2] = 1;
KEY_C[3] = 0;
#10
KEY_R[1] = 1;
KEY_C[3] = 1;
//第三行
#10
KEY_R[2] = 0;
KEY_C[0] = 0;
#10
KEY_C[0] = 1;
KEY_C[1] = 0;
#10
KEY_C[1] = 1;
KEY_C[2] = 0;
#10
KEY_C[2] = 1;
KEY_C[3] = 0;
#10
KEY_R[2] = 1;
KEY_C[3] = 1;
//第四行
#10
KEY_R[3] = 0;
KEY_C[0] = 0;
#10
KEY_C[0] = 1;
KEY_C[1] = 0;
#10
KEY_C[1] = 1;
KEY_C[2] = 0;
#10
KEY_C[2] = 1;
KEY_C[3] = 0;
#10
KEY_R[3] = 1;
KEY_C[3] = 1;
$display("Running testbench");
end
endmodule
仿真波形结果如下: