矩阵按键转化为普通单个按键

        没有多大的技术含量,就是将用按键少的矩阵按键转化为普通按键,减少IO口的使用,一个按键一个作用,按键松开则按键结束。

      转化程序:

       

         
         
         
        /********************************Copyright**************************************                           
        **----------------------------File information--------------------------
        ** File name  :keyboard_to_key.v  
        ** CreateDate :2015.
        ** Funtions   :
        ** Operate on :M5C06N3L114C7
        ** Copyright  :All rights reserved. 
        ** Version    :V1.0
        **---------------------------Modify the file information----------------
        ** Modified by   :
        ** Modified data :        
        ** Modify Content:
        *******************************************************************************/
         
    module  keyboard_to_key  (
                      clk,
                      rst_n,
                      l_in,
                      h_out,
                                    
                                    key_0,
                                    key_1,
                                    key_2,
                                    key_3,
                                    key_4,
                                    key_5,
                                    key_6,
                                    key_7,
                                    key_8,
                                    key_9,
                                    key_10,
                                    key_11,
                                    key_12,
                                    key_13,
                                    key_14,
                                    key_15,
                                    
                                    seg_bit,
                                    seg_data
                               );
         input          clk;
         input          rst_n;
         
         input   [3:0]     l_in;             //列输入,一般接上拉,为高电平
         output  [3:0]     h_out;            //行输出信号,低有效 
         
         output          key_0;
         output          key_1;
         output          key_2;
         output          key_3;
         output          key_4;
         output          key_5;
         output          key_6;
         output          key_7;
         output          key_8;
         output          key_9;
         output          key_10;
         output          key_11;
         output          key_12;
         output          key_13;
         output          key_14;
         output          key_15;
         
         output          seg_bit;
         output    [7:0] seg_data;
 //*************************************
 /* 分频Ƶ*20ms,用于消抖 .状态机直接用clk_20ms,则可以跳过消抖*/
//  `define   CLK_50M 
//  `define   CLK_24M 
   `define   CLK_20M 
     
     
    `ifdef  CLK_50M
        parameter  t_20ms = 20'd999999;         
     `endif
         
    `ifdef  CLK_24M
        parameter  t_20ms = 20'd479999;         
     `endif
     
     `ifdef  CLK_20M
        parameter  t_20ms = 20'd399999;         
     `endif
     
  reg    [19:0]   cnt;
 always @(posedge clk or negedge rst_n)
  begin
    if(!rst_n)
      begin
           cnt <= 'd0;
        end
      else 
       begin
         if(cnt == t_20ms)  cnt <= 'd0;
         else cnt <= cnt + 'd1;                 
       end
  end
    
  wire    shake_over;
    assign  shake_over = (cnt == t_20ms);
 //******************状态机******************
 localparam NO_KEY_pressed  =  3'd0;        /* 初始化 */
 localparam key_shake_1     =  3'd1;        /* 消抖1 */
 localparam KEY_h_1         =  3'd2;        /* 检测第一列 */
 localparam KEY_h_2         =  3'd3;        /* 检测第二列 */
 localparam KEY_h_3         =  3'd4;        /* 检测第三列 */ 
 localparam KEY_h_4         =  3'd5;        /* 检测第四列 */
 localparam KEY_pressed     =  3'd6;        /* 按键值输出*/
 localparam key_shake_2     =  3'd7;        /* 消抖2 */ 
 
 /* 3-1 */
 reg     [2:0]      current_state;
 reg     [2:0]      next_state;
 reg                key_pressed_flag; 
 always @(posedge clk or negedge rst_n)
 begin
  if(!rst_n)
   begin
      current_state <= 0;
    end
  else if(shake_over)
    begin
      current_state <= next_state;
    end
    else 
         current_state <=  current_state ;    
  end
    
 /* 3-2 */
always @(*) 
 begin
     next_state     = NO_KEY_pressed;
         case(current_state)
                    NO_KEY_pressed:
                       begin
                                 if(l_in != 4'hf)   next_state = key_shake_1;
                                 else  next_state = NO_KEY_pressed;
                            end
                    key_shake_1:     
                             begin
                                     if(l_in != 4'hf)   next_state = KEY_h_1;
                                     else  next_state = NO_KEY_pressed;
                                 end
                    KEY_h_1:
                            begin
                                 if(l_in != 4'hf)   next_state = KEY_pressed;
                                 else  next_state = KEY_h_2;
                                end
                    KEY_h_2:
                            begin
                                if(l_in != 4'hf)   next_state = KEY_pressed;
                                 else  next_state = KEY_h_3;
                             end
                    KEY_h_3:
                            begin
                                if(l_in != 4'hf)   next_state = KEY_pressed;
                                 else  next_state = KEY_h_4;
                                end
                    KEY_h_4:
                            begin
                                 if(l_in != 4'hf)   next_state = KEY_pressed;
                                 else  next_state = NO_KEY_pressed;
                                end
                 KEY_pressed:
                            begin
                                 if(l_in != 4'hf)   next_state = key_shake_2;
                                    else  next_state = NO_KEY_pressed;
                                end
                     key_shake_2:
                            begin
                                 if(l_in != 4'hf)   next_state = key_shake_2;
                                 else  next_state = NO_KEY_pressed;
                                end
                     default:next_state = NO_KEY_pressed;
    endcase
end

/* 3-3  */

 reg    [3:0]   l_in_reg;
 reg    [3:0]   h_out_reg;
 reg    [3:0]   h_out; 
always @(posedge clk or negedge rst_n)
 begin
  if(!rst_n)
   begin
          l_in_reg <= 4'd0;
          h_out_reg<= 4'd0;
          h_out <= 4'd0;
          key_pressed_flag <= 0;
    end
  else if(shake_over)
    begin
     case(next_state)
         NO_KEY_pressed:
            begin
              l_in_reg <= l_in_reg;
              h_out_reg<= h_out_reg;
              h_out <= 4'd0;   
              key_pressed_flag <= 0;
             end
         KEY_h_1:
              begin
                h_out <= 4'b1110;                             
               end
         KEY_h_2:
              begin
                 h_out <= 4'b1101;                             
                end
         KEY_h_3:
              begin
                 h_out <= 4'b1011;                             
                end
         KEY_h_4:
              begin
                 h_out <= 4'b0111;                             
                end
         KEY_pressed:
           begin
               l_in_reg <= l_in;
               h_out_reg<= h_out;
              end
         key_shake_2:  begin key_pressed_flag <= 1;   end
         default:;
        endcase
   end
 end
    
      
 
 reg      [15:0]      temp_key_val; 
 always @(posedge clk or negedge rst_n)
  begin
   if(!rst_n) temp_key_val <= 16'h0000;     
    else 
        begin
            if(key_pressed_flag) 
              begin
                  case ({h_out_reg,l_in_reg})
                        8'b1110_1110 :  temp_key_val <= 16'h0001;
                        8'b1110_1101 :  temp_key_val <= 16'h0002;
                        8'b1110_1011 :  temp_key_val <= 16'h0004;
                        8'b1110_0111 :  temp_key_val <= 16'h0008;
                            
                        8'b1101_1110 :  temp_key_val <= 16'h0010;
                        8'b1101_1101 :  temp_key_val <= 16'h0020;
                        8'b1101_1011 :  temp_key_val <= 16'h0040;
                        8'b1101_0111 :  temp_key_val <= 16'h0080;
                            
                        8'b1011_1110 :  temp_key_val <= 16'h0100;
                        8'b1011_1101 :  temp_key_val <= 16'h0200;
                        8'b1011_1011 :  temp_key_val <= 16'h0400;
                        8'b1011_0111 :  temp_key_val <= 16'h0800;

                        8'b0111_1110 :  temp_key_val <= 16'h1000;
                        8'b0111_1101 :  temp_key_val <= 16'h2000;
                        8'b0111_1011 :  temp_key_val <= 16'h4000;
                        8'b0111_0111 :  temp_key_val <= 16'h8000;
                     
                    default: temp_key_val <= 16'h0000;
                endcase    
             end
                    else  temp_key_val <= 16'h0000;  
    end
 end
 
 assign {key_15,key_14,key_13,key_12,key_11,key_10,key_9,key_8,key_7,key_6,key_5,key_4,key_3,key_2,key_1,key_0} = temp_key_val;
 
   key_signl   key_signl_1 (  
                       .clk(clk),
                                         .rst_n(rst_n),
                                         
                                         .key_0(key_0),
                                         .key_1(key_1),
                                         .key_2(key_2),
                                         .key_3(key_3),
                                         .key_4(key_4),
                                         .key_5(key_5),
                                         .key_6(key_6),
                                         .key_7(key_7),
                                         .key_8(key_8),
                                         .key_9(key_9),
                                         .key_10(key_10),
                                         .key_11(key_11),
                                         .key_12(key_12),
                                         .key_13(key_13),
                                         .key_14(key_14),
                                         .key_15(key_15),
                                         
                                        .seg_bit(seg_bit),
                                         .seg_data(seg_data)
                                         
                         );
                                             
                                             
 endmodule
 

     辅助验证程序:

      

 
  
    /********************************Copyright**************************************                           
    **----------------------------File information--------------------------
    ** File name  :key_signl.v  
    ** CreateDate :2015.
    ** Funtions   : 测试单个按键的好与坏,按下按键是,数码管会显示响应的值,没有按下时,数码管无显示
    ** Operate on :M5C06N3L114C7
    ** Copyright  :All rights reserved. 
    ** Version    :V1.0
    **---------------------------Modify the file information----------------
    ** Modified by   :
    ** Modified data :        
    ** Modify Content:
    *******************************************************************************/
     
    
     module key_signl(  
                       clk,
                                         rst_n,
                                         
                                         key_0,
                                         key_1,
                                         key_2,
                                         key_3,
                                         key_4,
                                         key_5,
                                         key_6,
                                         key_7,
                                         key_8,
                                         key_9,
                                         key_10,
                                         key_11,
                                         key_12,
                                         key_13,
                                         key_14,
                                         key_15,
                                         
                       seg_bit,
                                         seg_data
                                         
                         );
        input            clk;
        input            rst_n;
        
        input            key_0;
        input            key_1;
        input            key_2;
        input            key_3;
        input            key_4;
        input            key_5;
        input            key_6;
        input            key_7;
        input            key_8;
        input            key_9;
        input            key_10;
        input            key_11;
        input            key_12;
        input            key_13;
        input            key_14;
        input            key_15;
        
        output           seg_bit;
        output   [7:0]   seg_data;
        

  //---------------------------------------------//
     
     reg      [3:0]    vaule;
     reg               prass_flag;
     always @(posedge clk or negedge rst_n)
     begin
      if(!rst_n)
       begin
          vaule  <= 0;
                prass_flag <= 0;
        end
      else 
        begin
          if(key_0 == 0)        begin  prass_flag <= 1;  vaule <= 0; end
                else if(key_1 == 0)   begin  prass_flag <= 1;  vaule <= 1; end
              else if(key_2 == 0)   begin  prass_flag <= 1;  vaule <= 2; end
                else if(key_3 == 0)   begin  prass_flag <= 1;  vaule <= 3; end
                else if(key_4 == 0)   begin  prass_flag <= 1;  vaule <= 4; end
              else if(key_5 == 0)   begin  prass_flag <= 1;  vaule <= 5; end
                else if(key_6 == 0)   begin  prass_flag <= 1;  vaule <= 6; end
                else if(key_7 == 0)   begin  prass_flag <= 1;  vaule <= 7; end
              else if(key_8 == 0)   begin  prass_flag <= 1;  vaule <= 8; end
                else if(key_9 == 0)   begin  prass_flag <= 1;  vaule <= 9; end
                else if(key_10 == 0)   begin  prass_flag <= 1;  vaule <= 10; end
              else if(key_11 == 0)   begin  prass_flag <= 1;  vaule <= 11; end
                else if(key_12 == 0)   begin  prass_flag <= 1;  vaule <= 12; end
                else if(key_13 == 0)   begin  prass_flag <= 1;  vaule <= 13; end
              else if(key_14 == 0)   begin  prass_flag <= 1;  vaule <= 14; end
                else if(key_15 == 0)   begin  prass_flag <= 1;  vaule <= 15; end
        else  begin  prass_flag <= 0;  vaule <= 0; end
        end
      end
        
    
   reg     [7:0]     temp_data;         //共阳数码管
    always @(posedge clk or negedge rst_n)
     begin
      if(!rst_n)
       begin
          temp_data <= 8'hff;
        end
      else 
        begin
          case(vaule)
                 'd0: temp_data <= 8'hc0;
                 'd1: temp_data <= 8'hf9;
                 'd2: temp_data <= 8'ha4;
                 'd3: temp_data <= 8'hb0;
                 'd4: temp_data <= 8'h99;
                 'd5: temp_data <= 8'h92;
                 'd6: temp_data <= 8'h82;
                 'd7: temp_data <= 8'hf8;
                 'd8: temp_data <= 8'h80;
                 'd9: temp_data <= 8'h98;
                 'd10: temp_data <= 8'h88;
                 'd11: temp_data <= 8'h83;
                 'd12: temp_data <= 8'hc6;
                 'd13: temp_data <= 8'ha1;
                 'd14: temp_data <= 8'h86;
                 'd15: temp_data <= 8'h8e;
                 default :temp_data <= 8'hff;
             endcase
        end
      end
        
 assign  seg_data = temp_data;
 assign  seg_bit = ~prass_flag;

endmodule

    仿真程序:

        

 
 
/********************************Copyright**************************************                           
**----------------------------File information--------------------------
** File name  :testbench.v  
** CreateDate :2015.07
** Funtions   : 测试文件
** Operate on :M5C06N3L114C7
** Copyright  :All rights reserved. 
** Version    :V1.0
**---------------------------Modify the file information----------------
** Modified by   :
** Modified data :        
** Modify Content:
*******************************************************************************/
 
   module  testbench;
     reg          clk;
         reg          rst_n;
         
         reg   [3:0]     l_in;             //列输入,一般接上拉,为高电平
         wire  [3:0]     h_out;            //行输出信号,低有效 
         
         wire          key_0;
         wire          key_1;
         wire          key_2;
         wire          key_3;
         wire          key_4;
         wire          key_5;
         wire          key_6;
         wire          key_7;
         wire          key_8;
         wire          key_9;
         wire          key_10;
         wire          key_11;
         wire          key_12;
         wire          key_13;
         wire          key_14;
         wire          key_15;
         
         wire          seg_bit;
         wire    [7:0] seg_data;
         
  keyboard_to_key  u1(
                      .clk,
                      .rst_n,
                      .l_in,
                  .h_out,
                                    
                                    .key_0,
                                    .key_1,
                                    .key_2,
                                    .key_3,
                                    .key_4,
                                    .key_5,
                                    .key_6,
                                    .key_7,
                                    .key_8,
                                    .key_9,
                                    .key_10,
                                    .key_11,
                                    .key_12,
                                    .key_13,
                                    .key_14,
                                    .key_15,
                                    
                                    .seg_bit,
                                    .seg_data
                               );
     
     defparam  u1.t_20ms = 99;
     parameter tck = 24;
     parameter t = 1000/tck;
     
     always 
       #(t/2) clk = ~clk;
    
     
     
         initial 
          begin
            clk = 0;
                rst_n = 0;
                l_in  = 4'hf;
                
                #(5*t)    rst_n = 1; 
            
                #(100*t)     l_in = 4'b1110;
                #(500*t)   l_in = 4'b1111;
                
                #(1000*t)    l_in = 4'b1101;
                #(500*t)   l_in = 4'b1111; 
                
                #(1000*t)    l_in = 4'b1011;
                #(500*t)   l_in = 4'b1111; 
                
                #(1000*t)    l_in = 4'b0111;
                #(500*t)   l_in = 4'b1111; 
                
                #(1000*t)    l_in = 4'b1110;
                #(500*t)   l_in = 4'b1111; 
                
          end
            
    endmodule 
 

 

原文地址:https://www.cnblogs.com/fhyfhy/p/4671920.html