[Verilog] 薄膜建盤4X4 電路程式設計
最近研究需要用到4X4薄膜鍵盤設計。
就稍微研究了一下,有些資料參考這網站介紹還蠻清楚的。
原理就是,行1~行4送掃描碼,列1~列4讀值。
例如:
1. 行1~行4送 (0111)2進制的值,如果列1~列4讀到(0111)就表示Key 1被按下了。
2. 行1~行4送 (1101)2進制的值,如果列1~列4讀到(1011)就表示Key 6被按下了。
所以Verilog在寫程式的時候就要看現在是送那一列的掃描碼, 讀進來後是哪一個為0代表被按下。
[Note] 其中每個列的訊號端需要接一個pull high電組 ,以防止腳位浮接。
程式碼如下:
1 // -------------------------------------------------------------------- 2 // Copyright (c) 2011 by TKU ICLAB. 3 // -------------------------------------------------------------------- 4 /* use follow instruction to call the function 5 6 4X4 Keypad 7 Pin1 Pin2 Pin3 Pin4 Pin5 Pin6 Pin7 Pin8 8 function row1 row2 row3 row4 col1 col2 col3 col4 9 10 FPGA PIN iKey_Read[3] ~ iKey_Read[0] | oKey_Scan[3] ~ oKey_Scan[0] 11 12 */ 13 `define default_netype none 14 module Keypad4X4_top ( 15 iClk_50M, // 50Mhz 16 iRst_n, // reset_n 17 18 iKey_Read, // Key Read 19 oKey_Scan, // Key Scan code 20 21 oDval, // a trigger 22 oKeyCode, // Key code4 23 oKey 24 25 ); 26 //=========================================================================== 27 // PORT declarations 28 //=========================================================================== 29 input iClk_50M; 30 input iRst_n; 31 32 input [3:0] iKey_Read; // Key Read 33 output [3:0] oKey_Scan; // Key Scan code 34 35 output oDval; // a trigger 36 output [4:0] oKeyCode; // Key code 37 output [15:0] oKey; 38 //============================================================================= 39 // REG/WIRE declarations 40 //============================================================================= 41 reg [15:0] oKey; 42 reg oDval, rDval; 43 reg [3:0] oKey_Scan; 44 reg [4:0] oKeyCode; 45 wire wClk_1khz; 46 wire [2:0] wKey_Dly; 47 reg [1:0] rCnt, rSt; 48 reg [4:0] rKeyCode, rKeyCode_d1, rKeyCode_d2, rKeyCode_d3; 49 reg [3:0] rKey_Read_Dly0, rKey_Read_Dly1; 50 reg [3:0] rKey_Read; 51 wire wclk4X; 52 reg rPressKey; 53 //============================================================================= 54 // Structural coding 55 //============================================================================= 56 ///* 57 Clkdiv #( .CLKFREQ(50000000), .EXCEPTCLK(500000), .multipleX(4) ) UX1 58 ( 59 .iClk50M(iClk_50M), // 50Mhz clock 60 .iRst_n(iRst_n), 61 .oClk(wClk_1khz), // 1ms clock 62 .oSampClk(wclk4X), // multipleX expect clock, for SignalTap use 63 ); 64 //*/ 65 66 //// send column scan 67 always@(posedge wClk_1khz or negedge iRst_n) begin 68 if(!iRst_n) begin 69 rCnt <= 0; 70 oKey_Scan <= 0; 71 rSt <= 0; 72 end 73 else begin 74 case(rSt) 75 2'b00: begin oKey_Scan <= 4'b0111; rCnt <= rCnt+2'b1; 76 if(rCnt == 3) rSt <= rSt + 1; 77 else rSt <= rSt; end // 1 column 78 2'b01: begin oKey_Scan <= 4'b1011; rCnt <= rCnt+2'b1; 79 if(rCnt == 3) rSt <= rSt + 1; 80 else rSt <= rSt; 81 end // 2 column 82 2'b10: begin oKey_Scan <= 4'b1101; rCnt <= rCnt+2'b1; 83 if(rCnt == 3) rSt <= rSt + 1; 84 else rSt <= rSt; end // 3 column 85 default: begin oKey_Scan <= 4'b1110; rCnt <= rCnt+2'b1; 86 if(rCnt == 3) rSt <= rSt + 1; 87 else rSt <= rSt; end // 4 column 88 endcase 89 end 90 end 91 92 // send column scan 93 always@(posedge wClk_1khz or negedge iRst_n) begin 94 if(!iRst_n) begin 95 oKey <= 0; 96 rDval <= 0; 97 rKeyCode <= 0; 98 rPressKey <= 0; 99 end 100 else begin 101 oKey <= oKey; 102 // read row 103 case(iKey_Read) 104 4'b0111: begin // 1 row 105 oKey[3:0] <= 0; 106 case(oKey_Scan) 107 4'b0111: begin rDval <= 1; rKeyCode <= 5'd1; oKey[0] <= 1; end//'1' 108 4'b1011: begin rDval <= 1; rKeyCode <= 5'd2; oKey[1] <= 1; end//'2' 109 4'b1101: begin rDval <= 1; rKeyCode <= 5'd3; oKey[2] <= 1; end//'3' 110 4'b1110: begin rDval <= 1; rKeyCode <= 5'd10; oKey[3] <= 1; end//'A' 111 default: begin rDval <= 0; rKeyCode <= 5'd16; oKey[3:0] <= 0;end//'E' 112 endcase 113 end 114 4'b1011: begin // 2 row 115 oKey[7:4] <= 0; 116 case(oKey_Scan) 117 4'b0111: begin rDval <= 1; rKeyCode <= 5'd4; oKey[4] <= 1;end//'4' 118 4'b1011: begin rDval <= 1; rKeyCode <= 5'd5; oKey[5] <= 1;end//'5' 119 4'b1101: begin rDval <= 1; rKeyCode <= 5'd6; oKey[6] <= 1;end//'6' 120 4'b1110: begin rDval <= 1; rKeyCode <= 5'd11; oKey[7] <= 1;end //'B' 121 default: begin rDval <= 0; rKeyCode <= 5'd16; oKey[7:4] <= 0;end //'E' 122 endcase 123 end 124 4'b1101: begin // 3 row 125 oKey[11:8] <= 0; 126 case(oKey_Scan) 127 4'b0111: begin rDval <= 1; rKeyCode <= 5'd7; oKey[8] <= 1;end//'7' 128 4'b1011: begin rDval <= 1; rKeyCode <= 5'd8; oKey[9] <= 1;end//'8' 129 4'b1101: begin rDval <= 1; rKeyCode <= 5'd9; oKey[10] <= 1;end//'9' 130 4'b1110: begin rDval <= 1; rKeyCode <= 5'd12; oKey[11] <= 1;end//'C' 131 default: begin rDval <= 0; rKeyCode <= 5'd16; oKey[11:8] <= 0;end //'E' 132 endcase 133 end 134 4'b1110: begin // 4 row 135 oKey[15:12] <= 0; 136 case(oKey_Scan) 137 4'b0111: begin rDval <= 1;rKeyCode <= 5'd14; oKey[12] <= 1; end//'*' 138 4'b1011: begin rDval <= 1;rKeyCode <= 5'd0; oKey[13] <= 1;end//'0' 139 4'b1101: begin rDval <= 1;rKeyCode <= 5'd15; oKey[14] <= 1;end//'#' 140 4'b1110: begin rDval <= 1;rKeyCode <= 5'd13; oKey[15] <= 1;end//'D' 141 default: begin rDval <= 0;rKeyCode <= 5'd16; oKey[15:12] <= 0;end//'E' 142 endcase 143 end 144 4'b1111: begin // 4 row 145 rDval <= 0; rKeyCode <= 5'd16; oKey <= oKey; 146 case(oKey_Scan) 147 4'b0111: begin rDval <= 1; rKeyCode <= 5'd1; oKey[0] <= 0; 148 oKey[4] <= 0;oKey[8] <= 0;oKey[12] <= 0;end//'1' 149 4'b1011: begin rDval <= 1; rKeyCode <= 5'd2; oKey[1] <= 0; 150 oKey[5] <= 0;oKey[9] <= 0;oKey[13] <= 0;end//'1'end//'2' 151 152 4'b1101: begin rDval <= 1; rKeyCode <= 5'd3; oKey[2] <= 0; 153 oKey[6] <= 0;oKey[10] <= 0;oKey[14] <= 0;end//'1'end//'3' 154 4'b1110: begin rDval <= 1; rKeyCode <= 5'd10; oKey[3] <= 0; 155 oKey[7] <= 0;oKey[11] <= 0;oKey[15] <= 0;end//'1'end//'A' 156 default: begin rDval <= 0; rKeyCode <= 5'd16; oKey <= oKey;end//'E' 157 endcase 158 159 160 end 161 default: begin 162 rDval <= 0; rKeyCode <= 5'd16; 163 oKey <= oKey;// No key press 164 end 165 endcase 166 end 167 end 168 169 170 171 // disbounce 172 always@(posedge wClk_1khz or negedge iRst_n) begin 173 if(!iRst_n) begin 174 oDval <= 0; 175 oKeyCode <= 5'd16; 176 end 177 else begin 178 if( rDval ) begin 179 oKeyCode <= rKeyCode; 180 oDval <= 1; 181 end 182 else begin 183 oKeyCode <= oKeyCode; 184 oDval <= 0; 185 186 end 187 end 188 end 189 190 endmodule