矩陣鍵盤掃瞄

2021-10-01 23:54:02 字數 3414 閱讀 7309

矩陣鍵盤掃瞄

module matrix_keyboard

(input clk_50m, // 50m時鐘

input rst_n, // 復位

input [3:0] row, // 矩陣鍵盤行輸入

output reg [3:0] col, // 矩陣鍵盤列輸出

output reg key_flag, // 按鍵按下標誌

output reg [3:0] key_val // 按鍵掃瞄值

);parameter no_key_pressed = 3』d0, // 沒有按鍵按下狀態

scan_col0 = 3』d1, // 掃瞄第一列

scan_col1 = 3』d2, // 掃瞄第二列

scan_col2 = 3』d3, // 掃瞄第三列

scan_col3 = 3』d4, // 掃瞄第四列

key_pressed = 3』d5; // 按鍵按下狀態

reg clk_50hz; // 掃瞄頻率50hz

reg [31:0] clk_cnt; // 分頻計數器

reg [ 2:0] current_state, next_state; // 狀態值

// 此always塊分頻出50hz的矩陣鍵盤掃瞄時鐘

always @(posedge clk_50m, negedge rst_n) begin

if(!rst_n) begin

clk_cnt <= 32』d0;

clk_50hz <= 1』b0;

endelse if(clk_cnt == 32』d49_9999) begin

clk_cnt <= 32』d0;

clk_50hz <= ~clk_50hz;

endelse

clk_cnt <= clk_cnt + 1』b1;

end// 三段式狀態機第一段:當前狀態的改變

always @(posedge clk_50hz, negedge rst_n) begin

if(!rst_n)

current_state <= no_key_pressed;

else

current_state <= next_state;

end// 三段式狀態機第二段:下一狀態的改變

always @(*) begin

case(current_state)

no_key_pressed: begin

if(row != 4』b1111) // 行輸入如果不是全1,表示有按鍵按下,掃瞄第一列

next_state = scan_col0;

else

next_state = no_key_pressed;

endscan_col0: begin

if(row != 4』b1111) // 如果掃瞄到不是全1,則直接判斷按鍵值,否則掃瞄下一列。

next_state = key_pressed;

else

next_state = scan_col1;

endscan_col1: begin

if(row != 4』b1111) // 如果掃瞄到不是全1,則直接判斷按鍵值,否則掃瞄下一列。

next_state = key_pressed;

else

next_state = scan_col2;

endscan_col2: begin

if(row != 4』b1111) // 如果掃瞄到不是全1,則直接判斷按鍵值,否則掃瞄下一列。

next_state = key_pressed;

else

next_state = scan_col3;

endscan_col3: begin

if(row != 4』b1111) // 如果掃瞄到不是全1,則直接判斷按鍵值,否則掃瞄下一列。

next_state = key_pressed;

else

next_state = no_key_pressed;

endkey_pressed: begin

if(row != 4』b1111) // 如果掃瞄到不是全1,則直接判斷按鍵值,否則掃瞄下一列。

next_state = key_pressed;

else

next_state = no_key_pressed;

endendcase

end// 三段式狀態機第三段:變數的改變

always @(posedge clk_50hz, negedge rst_n) begin

if(!rst_n) begin

col <= 4』d0;

key_flag <= 1』b0;

endelse begin

case(next_state)

no_key_pressed: begin

col <= 4』d0;

key_flag <= 1』b0;

end// 低電平表示掃瞄那一列

scan_col0: col <= 4』b1110;

scan_col1: col <= 4』b1101;

scan_col2: col <= 4』b1011;

scan_col3: col <= 4』b0111;

key_pressed: begin

key_flag <= 1』b1;

// 通過行列組合的值,判斷出是哪乙個按鍵按下

case()

8』b1110_1110: key_val <= 4』d0;

8』b1101_1110: key_val <= 4』d1;

8』b1011_1110: key_val <= 4』d2;

8』b0111_1110: key_val <= 4』d3;

8'b1110_1101: key_val <= 4'd4;

8'b1101_1101: key_val <= 4'd5;

8'b1011_1101: key_val <= 4'd6;

8'b0111_1101: key_val <= 4'd7;

8'b1110_1011: key_val <= 4'd8;

8'b1101_1011: key_val <= 4'd9;

8'b1011_1011: key_val <= 4'd10;

8'b0111_1011: key_val <= 4'd11;

8'b1110_0111: key_val <= 4'd12;

8'b1101_0111: key_val <= 4'd13;

8'b1011_0111: key_val <= 4'd14;

8'b0111_0111: key_val <= 4'd15;

endcase

endendcase

end

end

endmodule

矩陣鍵盤掃瞄

矩陣鍵盤掃瞄一般採取行列掃瞄法。比如先拉低所有列線,拉高行線,之後讀取行線狀態,如果行線有一行為低,則假設有按鍵按下,此時再延時20毫秒左右後判 斷行線的某一行是否仍然為低,若為低則確認有鍵按下。這時可以進行按鍵鍵值判斷,即判別在哪一行哪一列有按鍵按下。判斷的方法是通過拉高列線,依次置行線 的某一行...

矩陣鍵盤掃瞄

根據矩陣鍵盤的原理圖可知,當沒有按鍵按下時,p1 0xf0 然後依次將p1 0 p1 3單獨置低電平,其他置高,再掃瞄各列的狀態,來判斷是哪個按鍵按下,比如,將p1 0輸出低電平,其他的引腳都輸出高電平,即p1 0xfe,那麼當第1行有按鍵按下時p1的相應值為,1x1 01111110 0x7e 1...

矩陣鍵盤掃瞄原理

當乙個按鍵兩端分別接乙個io口,乙個io口置高電平另乙個置低電平,當按下按鍵時高電平io口電平被拉低,另一端還是為低電平,這時檢測io口值就是兩個低電平。把上述方法應用到矩陣鍵盤上,如果把4個行引腳接p2前4位io口 p2.0 p2.3 都置低電平,把4個列引腳接p2後4位io口 p2.4 p2.7...