zoukankan      html  css  js  c++  java
  • 矩阵按键转化为普通单个按键

            没有多大的技术含量,就是将用按键少的矩阵按键转化为普通按键,减少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 
     

     

  • 相关阅读:
    JS控制SVG缩放+鼠标控制事件
    JS多线程之Web Worker
    通过Java调用Python脚本
    Cornerstone的使用
    SVN服务器的搭建
    Python 函数作用域
    RDD转换算子(transformantion)
    Spark RDD简介
    Django 外键
    Django 模型常用属性
  • 原文地址:https://www.cnblogs.com/fhyfhy/p/4671920.html
Copyright © 2011-2022 走看看