欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

4x4的矩阵键盘

程序员文章站 2022-04-24 09:42:36
...
  1. 做矩阵键盘的预备条件:按键消抖。
  2. 矩阵键盘的大体思路:
    如果会独立按键的话,相对来说只是多了一个行遍历,检测是出具体行数就对应出了坐标,即特定按键。
    独立按键原理图:4x4的矩阵键盘
    初始每个键位都输出逻辑“1”,那个按键被按下去,该按键对应的接口输出逻辑“0”。松开又为“1”。
    矩阵键盘不过是原来一行现在变成了多行,处理办法就是从上到下依次给行接口置零,如果检测到有按键按下则重头开始遍历。具体可以采用状态机实现。
    矩阵键盘原理图:4x4的矩阵键盘
    状态机
    4x4的矩阵键盘
    按键消抖代码略
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