回答

收藏

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

FPGA/DSP FPGA/DSP 5649 人阅读 | 0 人回复 | 2017-07-27

简单介绍下矩阵键盘的原理:


矩阵键盘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
复制代码
另一种:
  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
复制代码
关注下面的标签,发现更多相似文章
分享到:
回复

使用道具 举报

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

本版积分规则

关闭

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