首页 > 其他 > 详细

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

时间:2015-08-11 09:44:29      阅读:217      评论:0      收藏:0      [点我收藏+]

        没有多大的技术含量,就是将用按键少的矩阵按键转化为普通按键,减少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 = 20d999999;         
     `endif
         
    `ifdef  CLK_24M
        parameter  t_20ms = 20d479999;         
     `endif
     
     `ifdef  CLK_20M
        parameter  t_20ms = 20d399999;         
     `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  =  3d0;        /* 初始化 */
 localparam key_shake_1     =  3d1;        /* 消抖1 */
 localparam KEY_h_1         =  3d2;        /* 检测第一列 */
 localparam KEY_h_2         =  3d3;        /* 检测第二列 */
 localparam KEY_h_3         =  3d4;        /* 检测第三列 */ 
 localparam KEY_h_4         =  3d5;        /* 检测第四列 */
 localparam KEY_pressed     =  3d6;        /* 按键值输出*/
 localparam key_shake_2     =  3d7;        /* 消抖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 != 4hf)   next_state = key_shake_1;
                                 else  next_state = NO_KEY_pressed;
                            end
                    key_shake_1:     
                             begin
                                     if(l_in != 4hf)   next_state = KEY_h_1;
                                     else  next_state = NO_KEY_pressed;
                                 end
                    KEY_h_1:
                            begin
                                 if(l_in != 4hf)   next_state = KEY_pressed;
                                 else  next_state = KEY_h_2;
                                end
                    KEY_h_2:
                            begin
                                if(l_in != 4hf)   next_state = KEY_pressed;
                                 else  next_state = KEY_h_3;
                             end
                    KEY_h_3:
                            begin
                                if(l_in != 4hf)   next_state = KEY_pressed;
                                 else  next_state = KEY_h_4;
                                end
                    KEY_h_4:
                            begin
                                 if(l_in != 4hf)   next_state = KEY_pressed;
                                 else  next_state = NO_KEY_pressed;
                                end
                 KEY_pressed:
                            begin
                                 if(l_in != 4hf)   next_state = key_shake_2;
                                    else  next_state = NO_KEY_pressed;
                                end
                     key_shake_2:
                            begin
                                 if(l_in != 4hf)   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 <= 4d0;
          h_out_reg<= 4d0;
          h_out <= 4d0;
          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 <= 4d0;   
              key_pressed_flag <= 0;
             end
         KEY_h_1:
              begin
                h_out <= 4b1110;                             
               end
         KEY_h_2:
              begin
                 h_out <= 4b1101;                             
                end
         KEY_h_3:
              begin
                 h_out <= 4b1011;                             
                end
         KEY_h_4:
              begin
                 h_out <= 4b0111;                             
                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 <= 16h0000;     
    else 
        begin
            if(key_pressed_flag) 
              begin
                  case ({h_out_reg,l_in_reg})
                        8b1110_1110 :  temp_key_val <= 16h0001;
                        8b1110_1101 :  temp_key_val <= 16h0002;
                        8b1110_1011 :  temp_key_val <= 16h0004;
                        8b1110_0111 :  temp_key_val <= 16h0008;
                            
                        8b1101_1110 :  temp_key_val <= 16h0010;
                        8b1101_1101 :  temp_key_val <= 16h0020;
                        8b1101_1011 :  temp_key_val <= 16h0040;
                        8b1101_0111 :  temp_key_val <= 16h0080;
                            
                        8b1011_1110 :  temp_key_val <= 16h0100;
                        8b1011_1101 :  temp_key_val <= 16h0200;
                        8b1011_1011 :  temp_key_val <= 16h0400;
                        8b1011_0111 :  temp_key_val <= 16h0800;

                        8b0111_1110 :  temp_key_val <= 16h1000;
                        8b0111_1101 :  temp_key_val <= 16h2000;
                        8b0111_1011 :  temp_key_val <= 16h4000;
                        8b0111_0111 :  temp_key_val <= 16h8000;
                     
                    default: temp_key_val <= 16h0000;
                endcase    
             end
                    else  temp_key_val <= 16h0000;  
    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 <= 8hff;
        end
      else 
        begin
          case(vaule)
                 d0: temp_data <= 8hc0;
                 d1: temp_data <= 8hf9;
                 d2: temp_data <= 8ha4;
                 d3: temp_data <= 8hb0;
                 d4: temp_data <= 8h99;
                 d5: temp_data <= 8h92;
                 d6: temp_data <= 8h82;
                 d7: temp_data <= 8hf8;
                 d8: temp_data <= 8h80;
                 d9: temp_data <= 8h98;
                 d10: temp_data <= 8h88;
                 d11: temp_data <= 8h83;
                 d12: temp_data <= 8hc6;
                 d13: temp_data <= 8ha1;
                 d14: temp_data <= 8h86;
                 d15: temp_data <= 8h8e;
                 default :temp_data <= 8hff;
             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  = 4hf;
                
                #(5*t)    rst_n = 1; 
            
                #(100*t)     l_in = 4b1110;
                #(500*t)   l_in = 4b1111;
                
                #(1000*t)    l_in = 4b1101;
                #(500*t)   l_in = 4b1111; 
                
                #(1000*t)    l_in = 4b1011;
                #(500*t)   l_in = 4b1111; 
                
                #(1000*t)    l_in = 4b0111;
                #(500*t)   l_in = 4b1111; 
                
                #(1000*t)    l_in = 4b1110;
                #(500*t)   l_in = 4b1111; 
                
          end
            
    endmodule 
 

 技术分享

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

原文:http://www.cnblogs.com/fhyfhy/p/4671920.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!