一、基本信息

image.png
image.png
image.png

  • 按键消抖模块( key_debounce):对按键信号延时采样,将消抖后的按键信号和按键数据有效信号输出
    至 beep_control 模块。
  • 蜂鸣器控制模块( beep_control):根据输入的按键信号和按键数据有效信号,来控制蜂鸣器的鸣叫。

image.png
实际生成的RTL视图:
image.png
注意事项:

  1. 蜂鸣器默认驱动电流较小,需要修改驱动电流为12mA或16mA。
  2. 如果修改了默认的驱动电流,也需要同时修改默认的I/O Standard,否则会出现Pin <pin name> is missing an I/O standard assignment错误。

image.png

二、代码编写

  1. //----------------- Copyright (c) -----------------
  2. // Copyright(C) ZHJ0125 2022
  3. // All rights reserved
  4. //-------------------------------------------------
  5. // File Name : key_beep.v
  6. // Created Date : 2022-04-15 15:51
  7. // Modified Date : 2022-04-15 15:51
  8. // Created By : ZHJ0125
  9. // Last Version : V0.1
  10. // Descriptions : 使用按键控制蜂鸣器发声。
  11. // 初始状态为蜂鸣器(不)鸣叫,按下开关后蜂鸣器开始鸣叫;
  12. // 再次按下开关,蜂鸣器停止鸣叫。以此循环。
  13. //-------------------------------------------------
  14. module key_beep(
  15. input clk,
  16. input rst_n,
  17. input key,
  18. output beep
  19. );
  20. wire key_flag;
  21. wire key_value;
  22. key_debounce u_key_debounce(
  23. .clk(clk),
  24. .rst_n(rst_n),
  25. .key(key),
  26. .key_flag(key_flag),
  27. .key_value(key_value)
  28. );
  29. beep_control u_beep_control(
  30. .clk(clk),
  31. .rst_n(rst_n),
  32. .key_flag(key_flag),
  33. .key_value(key_value),
  34. .beep(beep)
  35. );
  36. endmodule
  37. //--------------------------------
  38. // key_debounce:按键消抖模块
  39. //--------------------------------
  40. module key_debounce(
  41. input clk,
  42. input rst_n,
  43. input key,
  44. output reg key_flag,
  45. output reg key_value
  46. );
  47. reg key_buf; // 暂存按键值
  48. reg [19:0] counter; // 20ms-20bit
  49. always @(posedge clk or negedge rst_n) begin
  50. if(!rst_n) begin
  51. key_buf <= 1'b1;
  52. counter <= 20'd0;
  53. end
  54. else begin
  55. key_buf <= key;
  56. if(key_buf != key) // 电平发生了变化,可能有按键被按下
  57. counter <= 20'd1000_000;
  58. else if(key_buf == key) // 电平处在保持状态时,计时20ms
  59. if(counter > 20'd0)
  60. counter <= counter - 1'd1;
  61. else
  62. counter <= counter;
  63. else
  64. counter <= counter;
  65. end
  66. end
  67. always @(posedge clk or negedge rst_n) begin
  68. if(!rst_n) begin
  69. key_flag <= 1'b0;
  70. key_value <= 1'b1;
  71. end
  72. else begin
  73. if(counter == 20'd1) begin // 电平状态保持了20ms,可以采样了
  74. key_flag <= 1'b1;
  75. key_value <= key;
  76. end
  77. else begin // 电平正在保持状态或者说还未保持20ms
  78. key_flag <= 1'b0;
  79. key_value <= key_value;
  80. end
  81. end
  82. end
  83. endmodule
  84. //--------------------------------
  85. // beep_control:蜂鸣器处理模块
  86. //--------------------------------
  87. module beep_control(
  88. input clk,
  89. input rst_n,
  90. input key_flag,
  91. input key_value,
  92. output reg beep
  93. );
  94. always @(posedge clk or negedge rst_n) begin
  95. if(!rst_n)
  96. beep <= 1'b0; // 复位默认状态蜂鸣器(不)鸣叫
  97. else begin
  98. if(key_flag && ~(key_value)) // 按键被按下一次
  99. beep <= ~beep;
  100. else
  101. beep <= beep;
  102. end
  103. end
  104. endmodule

key_beep.mp4 (7.87MB)

附录