码迷,mamicode.com
首页 > 其他好文 > 详细

4*4矩阵键盘原理分析以及代码展示

时间:2016-08-09 13:26:13      阅读:271      评论:0      收藏:0      [点我收藏+]

标签:

      简单介绍下矩阵键盘的原理:

技术分享

矩阵键盘4个输入端口ROW[3:0] 接收由FPGA产生的键盘扫描输入信号,而4个输出COL[3:0] 将按键操作的信息变化输入到FPGA扫描分析电路,进而得到按键的操作码。

输入端口分别接了4个上拉电阻,当4个输入端口输入若都为1时,则有无论按哪个按键,输出都为1,所以 若刚开始的时候对四个输入端口赋0,则只要按下任何一个按键,键盘上的4个输出则肯定有1变为0,而且能够判断到是哪一列,但是并不知道是哪一行,所以此时就要用到键盘扫描,何为键盘扫描,就是只要让输入端口的一行为0,其余三行全为1,轮流扫描一遍,便可以方便的确定按键按下的准确值。

又因为实际运用的时候按键按下会有抖动现象,所以要对其进行消抖处理,消抖模块可以有很多种方法,例如状态机的消抖方法以及打拍延时,然后相或,因为这个是键值输入,若要用到打拍延时的方法进行消抖处理的话,需要对其进行一些改动,相或改为两两相等并相与 以增加时钟时间。

以下给出矩阵键盘实现的两种代码,其中一种参照赵然的书籍中提到的夏宇闻老师提供的代码。 这里用到了状态机模块进行消抖。                     

`define OK 1b1    
`define NO 1b0    
`define NoKeyIsPressed 17    
 

module keyscan0(clk,rst_n,keyscan,keyin,real_number);
 input clk,rst_n;
 input [3:0]keyin;
 output [3:0] keyscan;
 output [4:0] real_number;
 reg [3:0] state;
 reg [3:0] four_state; 
 reg [3:0] scancode,scan_state;
 reg [4:0] numberout,number_reg,number_reg1,number_reg2, real_number;   
 reg AnyKeyPressed;
 
 assign keyscan = scancode;
 
 always @(posedge clk or negedge rst_n)  
 if (!rst_n)
      begin
        scancode <=4b0000;
        scan_state<= 4b0000;
      end
 else
     if(AnyKeyPressed)
        case (scan_state)
            4b0000: begin scancode<=4b1110; scan_state<= 4b0001; end
            4b0001: begin  scancode <= {scancode[0],scancode[3:1]}; end      
        endcase 
     else  
        begin
            scancode <=4b0000;
            scan_state<= 4b0000;
        end  

 always @(posedge clk )   
 if( !(&keyin))
    begin
     AnyKeyPressed <= `OK ;  
     four_state <= 4b0000;
    end
 else 
    if(AnyKeyPressed)
       case(four_state)
         4b0000: begin  AnyKeyPressed <= `OK ;  four_state<=4b0001; end
         4b0001: begin  AnyKeyPressed <= `OK ;  four_state<=4b0010; end
         4b0010: begin  AnyKeyPressed <= `OK ;  four_state<=4b0100; end
         4b0100: begin  AnyKeyPressed <= `OK ;  four_state<=4b1000; end
         4b1000: begin  AnyKeyPressed <= `NO ;   end
         default: AnyKeyPressed <= `NO ;
       endcase
    else 
         four_state <= 4b0000;
         
always @(posedge clk or negedge rst_n)
   if(!rst_n) 
        numberout<=`NoKeyIsPressed;
    else
  casex({scancode,keyin})
    8b0111_1110: numberout <= 5d10;
    8b1011_1110: numberout <= 5d3;  
    8b1101_1110: numberout <= 5d2;
    8b1110_1110: numberout <= 5d1; 
    
    8b0111_1101: numberout <= 5d11;
    8b1011_1101: numberout <= 5d6;  
    8b1101_1101: numberout <= 5d5;
    8b1110_1101: numberout <= 5d4; 
        
    8b0111_1011: numberout <= 5d12;
    8b1011_1011: numberout <= 5d9; 
    8b1101_1011: numberout <= 5d8;
    8b1110_1011: numberout <= 5d7; 
    
    8b0111_0111: numberout <= 5d13;
    8b1011_0111: numberout <= 5d15;  
    8b1101_0111: numberout <= 5d14;
    8b1110_0111: numberout <= 5d0; 
    default: numberout <=`NoKeyIsPressed;
   endcase
   
always @(posedge clk or negedge rst_n)     
begin
    if (!rst_n)
    begin
      number_reg <= 0;
    end
    else
        if( numberout<=5d15 && numberout>=5d0)
            begin
                 number_reg <= numberout;  
            end
        else
            begin
                if(AnyKeyPressed == `NO)
                    number_reg <= `NoKeyIsPressed;  
            end
           
 end
         
always @(posedge clk or negedge rst_n) 
 if (!rst_n)
    state <= 4b0000;
 else 
    case (state)
4d0: begin   
            number_reg1 <= number_reg;
            state <=4d1;
        end
4d1: begin 
            if(number_reg == number_reg1)
                state <= 4d2;
            else
                state <= 4d0;
        end
4d2: begin
            if (number_reg == number_reg1)                  
                state <= 4d3;
            else
                state <= 4d0;
        end                     
4d3: begin
            if (number_reg == number_reg1)                
                state <= 4d4;
            else
                state <= 4d0;   
        end          
4d4: begin   
             if(number_reg == number_reg1)
                state <=4d5;
             else
                state <= 4d0; 
        end
4d5: begin 
            if(number_reg == number_reg1)
                state <= 4d6;
            else
                state <= 4d0;
        end
4d6: begin
            if (number_reg == number_reg1)                  
                state <= 4d7;
            else
                state <= 4d0;
        end                     
4d7: begin
            if (number_reg == number_reg1)                
                  state <= 4d8;
            else
                  state <= 4d0;   
        end          
4d8: begin 
            if (number_reg == number_reg1)    
                  state <=4d9;
            else
                  state <= 4d0;  
        end
4d9: begin 
            if(number_reg == number_reg1)
                  state <= 4d10;
            else
                  state <= 4d0;
        end
4d10: begin
            if (number_reg == number_reg1)                  
                  state <= 4d11;
            else
                 state <= 4d0;
        end                     
4d11: begin
            if (number_reg == number_reg1)                
                 state <= 4d12;
            else
                 state <= 4d0;   
        end          
4d12: begin 
            if(number_reg == number_reg1)
              state <= 4d13;
            else
              state <= 4d0;
        end
4d13: begin
            if (number_reg == number_reg1)                  
                  state <= 4d14;
            else
                 state <= 4d0;
        end                     
4d14: begin
            if (number_reg == number_reg1)                
             state <= 4d15;
            else
             state <= 4d0;   
        end                 
4d15: begin
            if (number_reg == number_reg1 ) 
                begin                 
                    state <= 4d0;
                    real_number <=number_reg; 
                end
            else
                         state <= 4b0000;   
        end                        
  default:   state <= 4b0000;   
  endcase   
endmodule

另一种:

module key_bd(
input CLK_1K,
input RSTN,
input [3:0]ROW,
output reg[3:0]COL,
output [3:0]real_num,
output flag_pos
//output reg[3:0]key_value,

//output reg[23:0]num_out
);

reg [3:0]state;
reg [3:0]four_state;
reg [3:0]key_value;
reg flag;

parameter NO = 6b000_001;
parameter S0 = 6b000_010;
parameter S1 = 6b000_100;
parameter S2 = 6b001_000;
parameter S3 = 6b010_000;
parameter YES= 6b100_000;

reg [5:0]CS,NS;
always@(posedge CLK_1K or negedge RSTN)  
begin
if(~RSTN)
    CS <= NO;
else
    CS <= NS;
end

always@(*)
    case(CS)
    NO:if(ROW != 4hF)
            NS <= S0;
        else
            NS <= NO;
    S0:if(ROW != 4hF)
            NS <= YES;
        else
            NS <= S1;
    S1:if(ROW != 4hF)
            NS <= YES;
        else
            NS <= S2;
    S2:if(ROW != 4hF)
            NS <= YES;
        else
            NS <= S3;
    S3:if(ROW != 4hF)
            NS <= YES;
        else
            NS <= NO;
    YES:if(ROW != 4hF)
            NS <= YES;
        else
            NS <= NO;
    endcase

reg [3:0]ROW_val,COL_val;

always@(posedge CLK_1K or negedge RSTN)
begin
if(!RSTN)
    begin
    COL <= 0;
    flag <= 0;
    end
else
        case(NS)
            NO:begin
                COL <= 0;
                flag <= 0;
                end
            S0:begin
                COL <= 4b1110;
                end
            S1:begin
                COL <= 4b1101;
                end
            S2:begin
                COL <= 4b1011;
                end
            S3:begin
                COL <= 4b0111;
                end
            YES:begin
                COL_val <= COL;
                ROW_val <= ROW;
                flag <= 1;
                end
        endcase
end
/////////////////////////////////////////////////////////
reg flag_pre;
always@(posedge CLK_1K or negedge RSTN)
begin
    if(~RSTN)
        flag_pre <= 0;
    else
        flag_pre <= flag;
end

//assign flag_pos = (~flag_pre)&flag;
assign flag_pos = flag_pre & (~flag);
/////////////////////////////////////////////////////////
always@(posedge CLK_1K or negedge RSTN)
begin
    if(~RSTN)
        key_value <= 0;
    else 
        if(flag)
        case({ROW_val,COL_val})
        8b1110_1110: key_value <= 4h1;
        8b1110_1101: key_value <= 4h2;
        8b1110_1011: key_value <= 4h3;
        8b1110_0111: key_value <= 4ha;
        
        8b1101_1110: key_value <= 4h4;
        8b1101_1101: key_value <= 4h5;
        8b1101_1011: key_value <= 4h6;
        8b1101_0111: key_value <= 4hb;
        
        8b1011_1110: key_value <= 4h7;
        8b1011_1101: key_value <= 4h8;
      8b1011_1011: key_value <= 4h9;
        8b1011_0111: key_value <= 4hc;
        
        8b0111_1110: key_value <= 4h0;
        8b0111_1101: key_value <= 4he;
        8b0111_1011: key_value <= 4hf;
        8b0111_0111: key_value <= 4hd;
        endcase
end

key_esk #(4) K1(
.CLK_1K(CLK_1K),
.key_in(key_value),
.key_out(real_num)
);

endmodule 

 

4*4矩阵键盘原理分析以及代码展示

标签:

原文地址:http://www.cnblogs.com/zhouzheng/p/5752732.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!