矩阵键盘的示意图如下图所示,为了判别某个按键按下的键值信息,采用端口扫描的方式,一般采用:向R端口扫描输入一组只有0的4为数据,如1110、1101、1011、0111,若有按键按下,则C端口有相应信息,如图S1口按下,则有{R,C}=1110_0111。
按键排列方式
`timescale 1ns / 1ps
//
// 4x4矩阵按键
//
module scan(
output reg[3:0] a,
output reg[7:0]led,
input sys_clk,
input reset,
input [3:0] b,
output seg_cel //数码管位选
);
reg [4:0] keyvalue;
reg [1:0] q;
assign seg_sel= 1'b0;
always @ (posedge sys_clk or negedge reset) begin
if(!reset)
a <= 4'b1111;
else begin
q <= q+1; //循环扫描按键
case(q)
0:a <= 4'b1110;
1:a <= 4'b1101;
2:a <= 4'b1011;
3:a <= 4'b0111;
default: a <= 4'b1111;
endcase
//*********************//
//判断键位
//*********************//
case({a,b})
8'b1110_0111:keyvalue <=4'h0;
8'b1110_1011:keyvalue <=4'h1;
8'b1110_1101:keyvalue <=4'h2;
8'b1110_1110:keyvalue <=4'h3;
8'b1101_0111:keyvalue <=4'h4;
8'b1101_1011:keyvalue <=4'h5;
8'b1101_1101:keyvalue <=4'h6;
8'b1101_1110:keyvalue <=4'h7;
8'b1011_0111:keyvalue <=4'h8;
8'b1011_1011:keyvalue <=4'h9;
8'b1011_1101:keyvalue <=4'ha;
8'b1011_1110:keyvalue <=4'hb;
8'b0111_0111:keyvalue <=4'hc;
8'b0111_1011:keyvalue <=4'hd;
8'b0111_1101:keyvalue <=4'he;
8'b0111_1110:keyvalue <=4'hf;
default: ;
endcase
end
end
//*********************//
//点亮数码管
//*********************//
always @ (posedge sys_clk or negedge reset) begin
if(!reset)
led <= 8'b0000_0000;
else begin
case(keyvalue)
4'h0:led <= 8'b1000_0000;
4'h1:led <= 8'b0100_0000;
4'h2:led <= 8'b0010_0000;
4'h3:led <= 8'b0001_0000;
4'h4:led <= 8'b0000_1000;
4'h5:led <= 8'b0000_0100;
4'h6:led <= 8'b0000_0010;
4'h7:led <= 8'b0000_0001;
4'h8:led <= 8'b0000_0010;
4'h9:led <= 8'b0000_0100;
4'ha:led <= 8'b0000_1000;
4'hb:led <= 8'b0001_0000;
4'hc:led <= 8'b0010_0000;
4'hd:led <= 8'b0100_0000;
4'he:led <= 8'b1000_0000;
4'hf:led <= 8'b0000_0000;
endcase
end
end
endmodule