矩陣鍵盤掃瞄
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...