1. 按键KEY0短按(按键消抖模块)

  1. //--------------------------------
  2. // key_debounce:按键消抖模块
  3. // 输入:
  4. // clk: 系统时钟
  5. // rst_n: 系统复位
  6. // key: 按键状态输入
  7. // 输出:
  8. // key_flag: 按键是否被按下标志位
  9. // key_value: 按键被按下后的值(为0)
  10. //--------------------------------
  11. module key_debounce(
  12. input clk,
  13. input rst_n,
  14. input key,
  15. output reg key_flag,
  16. output reg key_value
  17. );
  18. reg key_buf; // 暂存按键值
  19. reg [19:0] counter; // 20ms-20bit
  20. always @(posedge clk or negedge rst_n) begin
  21. if(!rst_n) begin
  22. key_buf <= 1'b1;
  23. counter <= 20'd0;
  24. end
  25. else begin
  26. key_buf <= key;
  27. if(key_buf != key) // 电平发生了变化,可能有按键被按下
  28. counter <= 20'd1000_000;
  29. else if(key_buf == key) // 电平处在保持状态时,计时20ms
  30. if(counter > 20'd0)
  31. counter <= counter - 1'd1;
  32. else
  33. counter <= counter;
  34. else
  35. counter <= counter;
  36. end
  37. end
  38. always @(posedge clk or negedge rst_n) begin
  39. if(!rst_n) begin
  40. key_flag <= 1'b0;
  41. key_value <= 1'b1;
  42. end
  43. else begin
  44. if(counter == 20'd1) begin // 电平状态保持了20ms,可以采样了
  45. key_flag <= 1'b1;
  46. key_value <= key;
  47. end
  48. else begin // 电平正在保持状态或者说还未保持20ms
  49. key_flag <= 1'b0;
  50. key_value <= key_value;
  51. end
  52. end
  53. end
  54. endmodule