1 module juzhen 2 ( 3 input clk, 4 input rst_n, 5 input [3:0] col_data, 6 output reg [3:0] row_data, 7 output key_flag, //the mark of key is pressed 8 output reg [3:0] key_value, 9 10 output reg key_flag_r0 11 ); 12 parameter SCAN_IDLE = 3'b000; 13 parameter SCAN_JITTER= 3'b001; 14 parameter SCAN_COL0 = 3'b011; 15 parameter SCAN_COL1 = 3'b010; 16 parameter SCAN_COL2 = 3'b110; 17 parameter SCAN_COL3 = 3'b100; 18 parameter SCAN_READ = 3'b101; 19 parameter SCAN_JTTTER2= 3'b111; 20 21 reg [19:0] cnt; 22 reg [2:0] current_state; 23 reg [2:0] next_state; 24 always @(posedge clk or negedge rst_n)begin 25 if(!rst_n) begin cnt<=0; end 26 else 27 begin 28 if(cnt>=20'h7ffff) begin cnt<=0;end 29 else cnt<=cnt+1;end 30 end 31 always@(posedge clk or negedge rst_n) 32 begin 33 if(!rst_n) 34 current_state <= SCAN_IDLE; 35 else if(cnt == 20'h7ffff) current_state <= next_state; 36 end 37 always@* 38 begin case(current_state) 39 SCAN_IDLE : //init 40 if(col_data != 4'b0000) next_state = SCAN_JITTER; //初始化 41 else next_state = SCAN_IDLE; 42 SCAN_JITTER: //escape the jitter 43 if(col_data != 4'b0000) next_state = SCAN_COL0;//消除抖动 44 else next_state = SCAN_IDLE; 45 SCAN_COL0 : //1th row 46 if(col_data != 4'b0000) next_state = SCAN_READ;else next_state = SCAN_COL1; 47 SCAN_COL1 : //2th row 48 if(col_data != 4'b0000) next_state = SCAN_READ;else next_state = SCAN_COL2; 49 SCAN_COL2 : //3th row 50 if(col_data != 4'b0000) next_state = SCAN_READ;else next_state = SCAN_COL3; 51 SCAN_COL3 : //4th row 52 if(col_data != 4'b0000) next_state = SCAN_READ;else next_state = SCAN_IDLE; 53 SCAN_READ : //lock the vaule 54 if(col_data != 4'b0000) next_state = SCAN_JTTTER2;else next_state = SCAN_IDLE; 55 SCAN_JTTTER2: //when your hand is gone 56 if(col_data != 4'b0000) next_state = SCAN_JTTTER2;else next_state = SCAN_IDLE; 57 endcase 58 end 59 reg [3:0] col_data_r; 60 reg [3:0] row_data_r; 61 62 63 always@(posedge clk or negedge rst_n) 64 65 begin if(!rst_n) begin row_data <= 4'b1111;key_flag_r0 <= 0;end 66 else if(cnt == 20'h7ffff)begin 67 case(next_state) 68 SCAN_IDLE : begin row_data <= 4'b1111;key_flag_r0 <= 0;end //SCAN_JITTER: 69 SCAN_COL0 : row_data <= 4'b0001; 70 SCAN_COL1 : row_data <= 4'b0010; 71 SCAN_COL2 : row_data <= 4'b0100; 72 SCAN_COL3 : row_data <= 4'b1000; 73 SCAN_READ : begin 74 row_data_r <= row_data; 75 col_data_r <= col_data; 76 key_flag_r0 <= 1; 77 end 78 //SCAN_JTTTER2: 79 default:; //default vaule 80 endcase 81 end 82 end 83 always @(posedge clk or negedge rst_n) 84 begin if(!rst_n)key_value <= 0; 85 else if(cnt == 20'h7fff) 86 begin 87 if(key_flag_r0 == 1'b1) //the mark of key is pressed 88 begin 89 case ({row_data_r,col_data_r}) //row_data Row, col_data Col 90 8'b0001_0001: key_value <= 4'd0; 91 8'b0010_0001: key_value <= 4'd1; 92 8'b0100_0001: key_value <= 4'd2; 93 8'b1000_0001: key_value <= 4'd3; 94 8'b0001_0010: key_value <= 4'd4; 95 8'b0010_0010: key_value <= 4'd5; 96 8'b0100_0010: key_value <= 4'd6; 97 8'b1000_0010: key_value <= 4'd7; 98 8'b0001_0100: key_value <= 4'd8; 99 8'b0010_0100: key_value <= 4'd9; 100 8'b0100_0100: key_value <= 4'd10; 101 8'b1000_0100: key_value <= 4'd11; 102 8'b0001_1000: key_value <= 4'd12; 103 8'b0010_1000: key_value <= 4'd13; 104 8'b0100_1000: key_value <= 4'd14; 105 8'b1000_1000: key_value <= 4'd15; 106 default : key_value <= key_value; 107 endcase 108 end 109 else 110 key_value <= key_value; 111 end 112 end 113 //Capture the falling endge 114 reg key_flag_r2,key_flag_r1; 115 always@(posedge clk or negedge rst_n) 116 begin 117 if(!rst_n) 118 begin 119 key_flag_r1 <= 0; 120 key_flag_r2 <= 0; 121 end 122 else 123 begin 124 key_flag_r1 <= key_flag_r0; 125 key_flag_r2 <= key_flag_r1; 126 end 127 end 128 assign key_flag = key_flag_r2 & ~key_flag_r1; //when your hand is gone 129 endmodule
4*4矩阵经常用的到,实现的过程就是行扫描或者列扫描,画好状态机的状态,取得对应行列的值即确定具体哪个按键被按下。