查看: 4914|回复: 0

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

[复制链接]
  • TA的每日心情
    慵懒
    2014-11-28 09:29
  • 签到天数: 3 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    发表于 2017-7-27 18:37:31 | 显示全部楼层 |阅读模式
    分享到:
    简单介绍下矩阵键盘的原理:
    index4.png

    矩阵键盘4个输入端口ROW[3:0] 接收由FPGA产生的键盘扫描输入信号,而4个输出COL[3:0] 将按键操作的信息变化输入到FPGA扫描分析电路,进而得到按键的操作码。
    输入端口分别接了4个上拉电阻,当4个输入端口输入若都为1时,则有无论按哪个按键,输出都为1,所以 若刚开始的时候对四个输入端口赋0,则只要按下任何一个按键,键盘上的4个输出则肯定有1变为0,而且能够判断到是哪一列,但是并不知道是哪一行,所以此时就要用到键盘扫描,何为键盘扫描,就是只要让输入端口的一行为0,其余三行全为1,轮流扫描一遍,便可以方便的确定按键按下的准确值。
    又因为实际运用的时候按键按下会有抖动现象,所以要对其进行消抖处理,消抖模块可以有很多种方法,例如状态机的消抖方法以及打拍延时,然后相或,因为这个是键值输入,若要用到打拍延时的方法进行消抖处理的话,需要对其进行一些改动,相或改为两两相等并相与 以增加时钟时间。
    以下给出矩阵键盘实现的两种代码,其中一种参照赵然的书籍中提到的夏宇闻老师提供的代码。 这里用到了状态机模块进行消抖。
    1. define OK 1'b1   
    2. define NO 1'b0   
    3. define NoKeyIsPressed 17   


    4. module keyscan0(clk,rst_n,keyscan,keyin,real_number);
    5. input clk,rst_n;
    6. input [3:0]keyin;
    7. output [3:0] keyscan;
    8. output [4:0] real_number;
    9. reg [3:0] state;
    10. reg [3:0] four_state;
    11. reg [3:0] scancode,scan_state;
    12. reg [4:0] numberout,number_reg,number_reg1,number_reg2, real_number;   
    13. reg AnyKeyPressed;

    14. assign keyscan = scancode;

    15. always @(posedge clk or negedge rst_n)  
    16. if (!rst_n)
    17.       begin
    18.         scancode <=4'b0000;
    19.         scan_state<= 4'b0000;
    20.       end
    21. else
    22.      if(AnyKeyPressed)
    23.         case (scan_state)
    24.             4'b0000: begin scancode<=4'b1110; scan_state<= 4'b0001; end
    25.             4'b0001: begin  scancode <= {scancode[0],scancode[3:1]}; end      
    26.         endcase
    27.      else  
    28.         begin
    29.             scancode <=4'b0000;
    30.             scan_state<= 4'b0000;
    31.         end  

    32. always @(posedge clk )   
    33. if( !(&keyin))
    34.     begin
    35.      AnyKeyPressed <= `OK ;  
    36.      four_state <= 4'b0000;
    37.     end
    38. else
    39.     if(AnyKeyPressed)
    40.        case(four_state)
    41.          4'b0000: begin  AnyKeyPressed <= `OK ;  four_state<=4'b0001; end
    42.          4'b0001: begin  AnyKeyPressed <= `OK ;  four_state<=4'b0010; end
    43.          4'b0010: begin  AnyKeyPressed <= `OK ;  four_state<=4'b0100; end
    44.          4'b0100: begin  AnyKeyPressed <= `OK ;  four_state<=4'b1000; end
    45.          4'b1000: begin  AnyKeyPressed <= `NO ;   end
    46.          default: AnyKeyPressed <= `NO ;
    47.        endcase
    48.     else
    49.          four_state <= 4'b0000;
    50.          
    51. always @(posedge clk or negedge rst_n)
    52.    if(!rst_n)
    53.         numberout<=`NoKeyIsPressed;
    54.     else
    55.   casex({scancode,keyin})
    56.     8'b0111_1110: numberout <= 5'd10;
    57.     8'b1011_1110: numberout <= 5'd3;  
    58.     8'b1101_1110: numberout <= 5'd2;
    59.     8'b1110_1110: numberout <= 5'd1;
    60.    
    61.     8'b0111_1101: numberout <= 5'd11;
    62.     8'b1011_1101: numberout <= 5'd6;  
    63.     8'b1101_1101: numberout <= 5'd5;
    64.     8'b1110_1101: numberout <= 5'd4;
    65.         
    66.     8'b0111_1011: numberout <= 5'd12;
    67.     8'b1011_1011: numberout <= 5'd9;
    68.     8'b1101_1011: numberout <= 5'd8;
    69.     8'b1110_1011: numberout <= 5'd7;
    70.    
    71.     8'b0111_0111: numberout <= 5'd13;
    72.     8'b1011_0111: numberout <= 5'd15;  
    73.     8'b1101_0111: numberout <= 5'd14;
    74.     8'b1110_0111: numberout <= 5'd0;
    75.     default: numberout <=`NoKeyIsPressed;
    76.    endcase
    77.    
    78. always @(posedge clk or negedge rst_n)     
    79. begin
    80.     if (!rst_n)
    81.     begin
    82.       number_reg <= 0;
    83.     end
    84.     else
    85.         if( numberout<=5'd15 && numberout>=5'd0)
    86.             begin
    87.                  number_reg <= numberout;  
    88.             end
    89.         else
    90.             begin
    91.                 if(AnyKeyPressed == `NO)
    92.                     number_reg <= `NoKeyIsPressed;  
    93.             end
    94.            
    95. end
    96.          
    97. always @(posedge clk or negedge rst_n)
    98. if (!rst_n)
    99.     state <= 4'b0000;
    100. else
    101.     case (state)
    102. 4'd0: begin   
    103.             number_reg1 <= number_reg;
    104.             state <=4'd1;
    105.         end
    106. 4'd1: begin
    107.             if(number_reg == number_reg1)
    108.                 state <= 4'd2;
    109.             else
    110.                 state <= 4'd0;
    111.         end
    112. 4'd2: begin
    113.             if (number_reg == number_reg1)                  
    114.                 state <= 4'd3;
    115.             else
    116.                 state <= 4'd0;
    117.         end                     
    118. 4'd3: begin
    119.             if (number_reg == number_reg1)               
    120.                 state <= 4'd4;
    121.             else
    122.                 state <= 4'd0;   
    123.         end         
    124. 4'd4: begin   
    125.              if(number_reg == number_reg1)
    126.                 state <=4'd5;
    127.              else
    128.                 state <= 4'd0;
    129.         end
    130. 4'd5: begin
    131.             if(number_reg == number_reg1)
    132.                 state <= 4'd6;
    133.             else
    134.                 state <= 4'd0;
    135.         end
    136. 4'd6: begin
    137.             if (number_reg == number_reg1)                  
    138.                 state <= 4'd7;
    139.             else
    140.                 state <= 4'd0;
    141.         end                     
    142. 4'd7: begin
    143.             if (number_reg == number_reg1)               
    144.                   state <= 4'd8;
    145.             else
    146.                   state <= 4'd0;   
    147.         end         
    148. 4'd8: begin
    149.             if (number_reg == number_reg1)   
    150.                   state <=4'd9;
    151.             else
    152.                   state <= 4'd0;  
    153.         end
    154. 4'd9: begin
    155.             if(number_reg == number_reg1)
    156.                   state <= 4'd10;
    157.             else
    158.                   state <= 4'd0;
    159.         end
    160. 4'd10: begin
    161.             if (number_reg == number_reg1)                  
    162.                   state <= 4'd11;
    163.             else
    164.                  state <= 4'd0;
    165.         end                     
    166. 4'd11: begin
    167.             if (number_reg == number_reg1)               
    168.                  state <= 4'd12;
    169.             else
    170.                  state <= 4'd0;   
    171.         end         
    172. 4'd12: begin
    173.             if(number_reg == number_reg1)
    174.               state <= 4'd13;
    175.             else
    176.               state <= 4'd0;
    177.         end
    178. 4'd13: begin
    179.             if (number_reg == number_reg1)                  
    180.                   state <= 4'd14;
    181.             else
    182.                  state <= 4'd0;
    183.         end                     
    184. 4'd14: begin
    185.             if (number_reg == number_reg1)               
    186.              state <= 4'd15;
    187.             else
    188.              state <= 4'd0;   
    189.         end                 
    190. 4'd15: begin
    191.             if (number_reg == number_reg1 )
    192.                 begin                 
    193.                     state <= 4'd0;
    194.                     real_number <=number_reg;
    195.                 end
    196.             else
    197.                          state <= 4'b0000;   
    198.         end                        
    199.   default:   state <= 4'b0000;   
    200.   endcase   
    201. endmodule
    复制代码
    另一种:
    index5.png
    1. module key_bd(
    2. input CLK_1K,
    3. input RSTN,
    4. input [3:0]ROW,
    5. output reg[3:0]COL,
    6. output [3:0]real_num,
    7. output flag_pos
    8. //output reg[3:0]key_value,

    9. //output reg[23:0]num_out
    10. );

    11. reg [3:0]state;
    12. reg [3:0]four_state;
    13. reg [3:0]key_value;
    14. reg flag;

    15. parameter NO = 6'b000_001;
    16. parameter S0 = 6'b000_010;
    17. parameter S1 = 6'b000_100;
    18. parameter S2 = 6'b001_000;
    19. parameter S3 = 6'b010_000;
    20. parameter YES= 6'b100_000;

    21. reg [5:0]CS,NS;
    22. always@(posedge CLK_1K or negedge RSTN)  
    23. begin
    24. if(~RSTN)
    25.     CS <= NO;
    26. else
    27.     CS <= NS;
    28. end

    29. always@(*)
    30.     case(CS)
    31.     NO:if(ROW != 4'hF)
    32.             NS <= S0;
    33.         else
    34.             NS <= NO;
    35.     S0:if(ROW != 4'hF)
    36.             NS <= YES;
    37.         else
    38.             NS <= S1;
    39.     S1:if(ROW != 4'hF)
    40.             NS <= YES;
    41.         else
    42.             NS <= S2;
    43.     S2:if(ROW != 4'hF)
    44.             NS <= YES;
    45.         else
    46.             NS <= S3;
    47.     S3:if(ROW != 4'hF)
    48.             NS <= YES;
    49.         else
    50.             NS <= NO;
    51.     YES:if(ROW != 4'hF)
    52.             NS <= YES;
    53.         else
    54.             NS <= NO;
    55.     endcase

    56. reg [3:0]ROW_val,COL_val;

    57. always@(posedge CLK_1K or negedge RSTN)
    58. begin
    59. if(!RSTN)
    60.     begin
    61.     COL <= 0;
    62.     flag <= 0;
    63.     end
    64. else
    65.         case(NS)
    66.             NO:begin
    67.                 COL <= 0;
    68.                 flag <= 0;
    69.                 end
    70.             S0:begin
    71.                 COL <= 4'b1110;
    72.                 end
    73.             S1:begin
    74.                 COL <= 4'b1101;
    75.                 end
    76.             S2:begin
    77.                 COL <= 4'b1011;
    78.                 end
    79.             S3:begin
    80.                 COL <= 4'b0111;
    81.                 end
    82.             YES:begin
    83.                 COL_val <= COL;
    84.                 ROW_val <= ROW;
    85.                 flag <= 1;
    86.                 end
    87.         endcase
    88. end
    89. /////////////////////////////////////////////////////////
    90. reg flag_pre;
    91. always@(posedge CLK_1K or negedge RSTN)
    92. begin
    93.     if(~RSTN)
    94.         flag_pre <= 0;
    95.     else
    96.         flag_pre <= flag;
    97. end

    98. //assign flag_pos = (~flag_pre)&flag;
    99. assign flag_pos = flag_pre & (~flag);
    100. /////////////////////////////////////////////////////////
    101. always@(posedge CLK_1K or negedge RSTN)
    102. begin
    103.     if(~RSTN)
    104.         key_value <= 0;
    105.     else
    106.         if(flag)
    107.         case({ROW_val,COL_val})
    108.         8'b1110_1110: key_value <= 4'h1;
    109.         8'b1110_1101: key_value <= 4'h2;
    110.         8'b1110_1011: key_value <= 4'h3;
    111.         8'b1110_0111: key_value <= 4'ha;
    112.         
    113.         8'b1101_1110: key_value <= 4'h4;
    114.         8'b1101_1101: key_value <= 4'h5;
    115.         8'b1101_1011: key_value <= 4'h6;
    116.         8'b1101_0111: key_value <= 4'hb;
    117.         
    118.         8'b1011_1110: key_value <= 4'h7;
    119.         8'b1011_1101: key_value <= 4'h8;
    120.         8'b1011_1011: key_value <= 4'h9;
    121.         8'b1011_0111: key_value <= 4'hc;
    122.         
    123.         8'b0111_1110: key_value <= 4'h0;
    124.         8'b0111_1101: key_value <= 4'he;
    125.         8'b0111_1011: key_value <= 4'hf;
    126.         8'b0111_0111: key_value <= 4'hd;
    127.         endcase
    128. end

    129. key_esk #(4) K1(
    130. .CLK_1K(CLK_1K),
    131. .key_in(key_value),
    132. .key_out(real_num)
    133. );

    134. endmodule
    复制代码
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-12-29 08:09 , Processed in 0.126250 second(s), 18 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.