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

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

时间: 2024-08-24 15:18:06

矩阵按键转化为普通单个按键的相关文章

c++中键盘的单个按键的刷新

运行环境Vs2013 为了实现小游戏中按键的使用. 在游戏中常常把主要的行为放在while()中所以常用的键盘输入函数就不再使用,因为有其暂停作用.而这在游戏中是不允许的. 而且游戏使用的往往是少数几个键,所以若能找到一种能判断某键是否按下的算法,那么一样能解决问题. // 测试3.cpp : 定义控制台应用程序的入口点.// #include "stdafx.h"#include<iostream> #include<windows.h> using name

按键检测程序应&quot;等待按键释放&quot;

按键S4是下拉,S1.S2.S3为上拉.一定要等待按键释放,否则按一次S1可能会运行key_scan()函数好几次. 1 /******************************************************************************* 2 * Function Name : key_scan 3 * Description : 按键扫描.优先级S4>S0>S1>S2.一定要等待按键释放 4 * Input : None 5 * Output

Thinkpad个性化设置:F1~F12恢复正常按键,Fn与Ctrl按键互换

一.F1~F12恢复正常按键 联想Thinkpad的F1~F12键功能与其他笔记本是相反的! 也就是说,如果不按着Fn,按那几个功能键,实现的是属性设置的功能,比如直接按下F1键是静音,F2键是音量降低,F3是音量增加等等.如果按下Fn+F1键,则打开的是F1的功能,也就是系统帮助功能. 不过这样的设置在BIOS里可以设置,就是可以给它反过来,操作如下: 开机按F1键,不用按Fn键,进入BIOS,选择第一项Config,再选择Keyboard/Mouse,进入选项后,Change to "F1-

手动按键复位程序(包含按键消抖)

1 //这是一个按键复位程序 2 module stable_key( 3 i_clkin, 4 i_inKey, 5 o_outKey 6 ); 7 8 input i_clkin; 9 input i_inKey; 10 output o_outKey; 11 12 reg key=1; 13 reg key_get = 1; //key输出指示信号 14 reg [20:0] cntK = 0; 15 reg o_outKey_r = 1; 16 17 always@(posedge i_

Android官方开发文档Training系列课程中文版:键盘输入处理之处理键盘按键

原文地址:http://android.xsoftlab.net/training/keyboard-input/commands.html 当用户将焦点给到可编辑文本的View时,例如EditText这种,并且该设备还拥有实体键盘,那么所有的输入都会被系统处理.然而,如果你希望可以拦截或者直接处理键盘的输入事件的话,你可以通过实现回调方法KeyEvent.Callback接口来做到.比如onKeyDown()和onKeyMultiple(). Activity与View都实现了KeyEvent

单片机独立按键与矩阵按键

独立按键 首先既然是检测输入,对于当然要使能上拉电阻,来检测变化.因为除了P0口外,P2,P3,P4都是内置上拉电阻的准双向IO口,作为输入前需要拉为高电平. 当有按键按下,致使单片机的某个引脚接地,变为低电平时,我们就认为这个按键按下了.当按键松开后,由于输入不会锁存,所以此时拉高的引脚回归到高电平. 独立按键的内部原理. 独立按键的4个引脚中,两两为一组.每一组的2个引脚是连在一起的,当按键按键时,2个组又连接了,也就是4个脚都连接一起了. 按键的很重要注意点就是消除抖动,消抖.因为人按下按

51单片机按键连击

51单片机按键双击 关键字:51单片机  按键双击 //hnrain 改 //适用于CEPARK 51开发板 /****************************************************************************************** *********************** www.cepark.com            电子园 按键高阶攻略设计大赛 名称:        2*4矩阵键盘扫描 (状态机) 功能:       

按键消抖之终极解决方案

1.按键消抖的原理 图1.按键抖动示意图 我们平常所用的按键为机械弹性开关,由于触点的弹性作用,按键在闭合时不会马上稳定的接通,而是有一段时间的抖动,在断开时也不会立即断开.抖动时间由按键的机械特性所决定,一般为5ms~10ms.所以我们在做按键检测时都要加一个消抖的过程. 按键消抖主要有两种方案: 一是延时重采样:二是持续采样. 从理论上来说,延时(如10ms)重采样的准确率肯定低于持续采样. 2.按键消抖的方法 (1)延时重采样 延时重采样的意思是,当第一次检测到键值由'1'变为'0'时,再

android 虚拟按键是通过哪种机制上报的?

1.在normal mode下,tp button也是和其他触摸事件一样,以坐标形式的input_event进行上报.在初始化时会通过tpd_button_setting()函数依据定义在tpd_custom_XXX.h文件里的配置信息将虚拟按键的坐标信息写在/sys/board_properties/virtualkeys.mtk-tpd中. 工作时.tp driver将按下的点的坐标进行上报.Android上层会读取sys中的按键配置信息.再推断上报的坐标是否属于某个按键的坐标范围,以此将坐