1. 4*4键盘的结构为4行4列,共16个交叉点,代表16个按键,行编号为A,列编号为B。按下某键后,辨别和读取键值一般采用如下方法:
向A端口扫描输入一组只含有一个0的4位数据,若有按键按下,B端口会输出相应的数据,然后结合A、B端口的数据,判断按键的位置。
2. 整个键盘扫描检测,设计思想还是编码译码。扫描时钟用1KHz,用一个模4的计数器,每个计数值对应一行,编码A。组合读入的列编码,
根据查找表,就很容易确定按键位置,按键值。
3. 4*4矩阵键盘扫描检测程序:
1 /*4*4 keyboard scan and display */ 2 //2020-11-04 3 //by YongFengXie 4 module key4x4(rst,clk50M,a,b,led7s); 5 input clk50M; //keyboard scan clock 6 input rst; 7 input [3:0] b; 8 output reg [3:0] a; // output scan signal to keyboard 9 output reg [6:0] led7s; 10 reg [3:0] keyvalue; 11 reg [1:0] q; //counter 4 12 reg clk; // 1KHz 13 reg [14:0] count; //div counter,50M to 1K 14 15 always @(posedge rst or posedge clk50M) 16 // 50M divide 25 000 to 1K Hz 17 begin 18 if(rst) 19 begin 20 clk <= 0; 21 count <= 0; 22 q<=0; 23 end 24 else if(count == 25000) 25 begin 26 count <= 0; 27 clk <= ~clk; 28 end 29 else 30 count <= count + 1; 31 end 32 33 always @(posedge clk) 34 begin 35 q <= q+1; 36 case(q) // send data to keyboard A port 37 0: a<=4'b1110; 38 1: a<=4'b1101; 39 2: a<=4'b1011; 40 3: a<=4'b0111; 41 default: a<=4'b0000; 42 endcase 43 case({a,b}) // judge keyvalue 44 8'b1110_0111: begin keyvalue<=4'b0000; 45 led7s<=7'b1000000; 46 end // key0 47 8'b1110_1011: begin keyvalue<=4'b0001; 48 led7s<=7'b1111001; 49 end // key1 50 8'b1110_1101: begin keyvalue<=4'b0010; 51 led7s<=7'b0100100; 52 end // key2 53 8'b1110_1110: begin keyvalue<=4'b0011; 54 led7s<=7'b0110000; 55 end // key3 56 8'b1101_0111: begin keyvalue<=4'b0100; 57 led7s<=7'b0011001; 58 end // key4 59 8'b1101_1011: begin keyvalue<=4'b0101; 60 led7s<=7'b0010010; 61 end // key5 62 8'b1101_1101: begin keyvalue<=4'b0110; 63 led7s<=7'b0000010; 64 end // key6 65 8'b1101_1110: begin keyvalue<=4'b0111; 66 led7s<=7'b1111000; 67 end // key7 68 8'b1011_0111: begin keyvalue<=4'b1000; 69 led7s<=7'b0000000; 70 end // key8 71 8'b1011_1011: begin keyvalue<=4'b1001; 72 led7s<=7'b0010000; 73 end // key9 74 8'b1011_1101: begin keyvalue<=4'b1010; 75 led7s<=7'b0001000; 76 end // keyA 77 8'b1011_1110: begin keyvalue<=4'b1011; 78 led7s<=7'b0000011; 79 end // keyB 80 8'b0111_0111: begin keyvalue<=4'b1100; 81 led7s<=7'b1000110; 82 end // keyC 83 8'b0111_1011: begin keyvalue<=4'b1101; 84 led7s<=7'b0100001; 85 end // keyD 86 8'b1110_1101: begin keyvalue<=4'b1110; 87 led7s<=7'b0000110; 88 end // keyE 89 8'b0111_1110: begin keyvalue<=4'b1111; 90 led7s<=7'b0001110; 91 end // keyF 92 default:begin keyvalue<=4'b0000;led7s<=7'b1111111;end 93 endcase 94 end 95 96 endmodule 97 98 99
测试代码:
1 /*4*4 keyboard scan and display testbench */ 2 //2020-11-04 3 //by YongFengXie 4 `timescale 10ns/1ns 5 module key4x4_tb; 6 reg clk50M; //keyboard scan clock 7 reg rst; 8 reg [3:0] b; 9 wire [3:0] a; // output scan signal to keyboard 10 wire [6:0] led7s; 11 12 key4x4 ub(rst,clk50M,a,b,led7s); 13 14 initial begin 15 clk50M=0; 16 rst=1; 17 b=4'b0000; 18 #2 rst=0; 19 #1600000 $stop; 20 end 21 22 always #1 clk50M=~clk50M; 23 24 initial begin #100000 b=4'b0111; 25 #100000 b=4'b1011; 26 #100000 b=4'b1101; 27 #100000 b=4'b1110; 28 end 29 30 endmodule
仿真结果:
4. 总结:
参照王金明的设计,其实还是有很多问题:1。矩阵键盘需要淘;2。仿真因为包含分频,所以测试模块还不完善,16个按键,16种组合,每种持续时长都是需要考虑。