4x4的矩阵键盘
程序员文章站
2022-04-24 09:42:36
...
- 做矩阵键盘的预备条件:按键消抖。
- 矩阵键盘的大体思路:
如果会独立按键的话,相对来说只是多了一个行遍历,检测是出具体行数就对应出了坐标,即特定按键。
独立按键原理图:
初始每个键位都输出逻辑“1”,那个按键被按下去,该按键对应的接口输出逻辑“0”。松开又为“1”。
矩阵键盘不过是原来一行现在变成了多行,处理办法就是从上到下依次给行接口置零,如果检测到有按键按下则重头开始遍历。具体可以采用状态机实现。
矩阵键盘原理图:
状态机
按键消抖代码略
module RowcontrollerAndValueout(
input clk,
input rst_n,
inout [3:0]list,
output reg [3:0]row,
output reg [15:0] value
);
listpress uut_listpress(//该模块为按键消抖处理
.clk(clk),
.rst_n(rst_n),
.list(list),
.press(press)//此接口引出的是处理后的list按键
);
wire[3:0] press; //列按键按下键值,高电平有效
//状态机采样键值
reg[3:0] nstate,cstate;
parameter K_IDLE = 4'd0; //空闲状态,等待
parameter K_H1OL = 4'd1; //key_h[0]拉低
parameter K_H2OL = 4'd2; //key_h[1]拉低
parameter K_H3OL = 4'd3; //key_h[2]拉低
parameter K_H4OL = 4'd4; //key_h[3]拉低
parameter K_CHCK = 4'd5;
//状态切换
always @(posedge clk or negedge rst_n)
if(!rst_n) cstate <= K_IDLE;
else cstate <= nstate;
always @(cstate or press or list)
case(cstate)
K_IDLE: if(press != 4'b0000) nstate <= K_H1OL;
else nstate <= K_IDLE;
K_H1OL: nstate <= K_H2OL;
K_H2OL: if(list != 4'b1111) nstate <= K_IDLE;
else nstate <= K_H3OL;
K_H3OL: if(list != 4'b1111) nstate <= K_IDLE;
else nstate <= K_H4OL;
K_H4OL: if(list != 4'b1111) nstate <= K_IDLE;
else nstate <= K_CHCK;
K_CHCK: nstate <= K_IDLE;
default: ;
endcase
//-------------------------------------
//采样键值
reg[3:0] new_value; //新采样数据
reg new_rdy; //新采样数据有效
always @(posedge clk or negedge rst_n)
if(!rst_n) begin
row <= 4'b0000;
new_value <= 4'd0;
new_rdy <= 1'b0;
end
else begin
case(cstate)
K_IDLE: begin
row <= 4'b0000;
new_value <= 4'd0;
new_rdy <= 1'b0;
end
K_H1OL: begin
row <= 4'b1110;
new_value <= 4'd0;
new_rdy <= 1'b0;
end
K_H2OL: begin
case(list)
4'b1110: begin
row <= 4'b0000;
new_value <= 4'd0;
new_rdy <= 1'b1;
end
4'b1101: begin
row <= 4'b0000;
new_value <= 4'd1;
new_rdy <= 1'b1;
end
4'b1011: begin
row <= 4'b0000;
new_value <= 4'd2;
new_rdy <= 1'b1;
end
4'b0111: begin
row <= 4'b0000;
new_value <= 4'd3;
new_rdy <= 1'b1;
end
default: begin
row <= 4'b1101;
new_value <= 4'd0;
new_rdy <= 1'b0;
end
endcase
end
K_H3OL: begin
case(list)
4'b1110: begin
row <= 4'b0000;
new_value <= 4'd4;
new_rdy <= 1'b1;
end
4'b1101: begin
row <= 4'b0000;
new_value <= 4'd5;
new_rdy <= 1'b1;
end
4'b1011: begin
row <= 4'b0000;
new_value <= 4'd6;
new_rdy <= 1'b1;
end
4'b0111: begin
row <= 4'b0000;
new_value <= 4'd7;
new_rdy <= 1'b1;
end
default: begin
row <= 4'b1011;
new_value <= 4'd0;
new_rdy <= 1'b0;
end
endcase
end
K_H4OL: begin
case(list)
4'b1110: begin
row <= 4'b0000;
new_value <= 4'd8;
new_rdy <= 1'b1;
end
4'b1101: begin
row <= 4'b0000;
new_value <= 4'd9;
new_rdy <= 1'b1;
end
4'b1011: begin
row <= 4'b0000;
new_value <= 4'd10;
new_rdy <= 1'b1;
end
4'b0111: begin
row <= 4'b0000;
new_value <= 4'd11;
new_rdy <= 1'b1;
end
default: begin
row <= 4'b0111;
new_value <= 4'd0;
new_rdy <= 1'b0;
end
endcase
end
K_CHCK: begin
case(list)
4'b1110: begin
row <= 4'b0000;
new_value <= 4'd12;
new_rdy <= 1'b1;
end
4'b1101: begin
row <= 4'b0000;
new_value <= 4'd13;
new_rdy <= 1'b1;
end
4'b1011: begin
row <= 4'b0000;
new_value <= 4'd14;
new_rdy <= 1'b1;
end
4'b0111: begin
row <= 4'b0000;
new_value <= 4'd15;
new_rdy <= 1'b1;
end
default: begin
row <= 4'b0000;
new_value <= 4'd0;
new_rdy <= 1'b0;
end
endcase
end
default: ;
endcase
end
//-------------------------------------
//产生最新键值
always @(posedge clk or negedge rst_n)
if(!rst_n) value <= 16'h0000;
else if(new_rdy) value <= {value[11:0],new_value};
endmodule
上一篇: 如何搭建一个Vue脚手架(vue-cli)并创建一个项目?
下一篇: Js常用方法总结