当前位置:   article > 正文

25.无源蜂鸣器驱动设计

25.无源蜂鸣器驱动设计

        相对于有源蜂鸣器,无源蜂鸣器的成本更低,声音频率可控。而有源蜂鸣器因其内部
自带振荡源,只要加上适当的直流电源即可发声,程序控制较为方便。

(1)设计定义:设计一个无源蜂鸣器的驱动程序,实现7个音调的循环发声,每个音调持续0.5s,占空比为50%。

(2)Visio视图:

(2)Verilog代码:

  1. module beep(clk,reset_n,beep);
  2. input clk;
  3. input reset_n;
  4. output reg beep;
  5. //0.5s = 500_000_000ns = 20ns * 25_000_000; 需要一个十五位的寄存器去计数
  6. reg[24:0]cnt;
  7. reg[2:0]cnt_500ms;
  8. //freq最大值为190840,可以用一个二十位的寄存器去计数
  9. reg[19:0]freq_cnt;
  10. reg[19:0]freq_data;
  11. wire[19:0]duty_data;
  12. parameter MCNT_Time = 25'd24_999_999;
  13. parameter Do = 20'd190839 ;
  14. parameter Re = 20'd170067 ;
  15. parameter Mi = 20'd151514 ;
  16. parameter Fa = 20'd143265 ;
  17. parameter So = 20'd127550 ;
  18. parameter La = 20'd113635 ;
  19. parameter Si = 20'd101213 ;
  20. //500ms计数器模块设计
  21. always@(posedge clk or negedge reset_n)
  22. if(!reset_n)
  23. cnt <= 25'd0;
  24. else if(cnt == MCNT_Time)
  25. cnt <= 25'd0;
  26. else
  27. cnt <= cnt + 25'd1;
  28. //cnt_500ms计数器模块设计
  29. always@(posedge clk or negedge reset_n)
  30. if(!reset_n)
  31. cnt_500ms <= 3'd0;
  32. else if((cnt_500ms == 3'd6) && (cnt == MCNT_Time))
  33. cnt_500ms <= 3'd0;
  34. else if(cnt == MCNT_Time)
  35. cnt_500ms <= cnt_500ms + 3'd1;
  36. else
  37. cnt_500ms <= cnt_500ms;
  38. //freq_cnt计数器模块设计
  39. always@(posedge clk or negedge reset_n)
  40. if(!reset_n)
  41. freq_cnt <= 20'd0;
  42. else if((freq_cnt == freq_data) || (cnt == MCNT_Time))
  43. freq_cnt <= 20'd0;
  44. else
  45. freq_cnt <= freq_cnt + 20'd1;
  46. //freq_data设计
  47. always@(posedge clk or negedge reset_n)
  48. if(!reset_n)
  49. freq_data <= Do;
  50. else begin
  51. case(cnt_500ms)
  52. 3'd0: freq_data <= Do;
  53. 3'd1: freq_data <= Re;
  54. 3'd2: freq_data <= Mi;
  55. 3'd3: freq_data <= Fa;
  56. 3'd4: freq_data <= So;
  57. 3'd5: freq_data <= La;
  58. 3'd6: freq_data <= Si;
  59. default:freq_data <= Do;
  60. endcase
  61. end
  62. //duty_data设计
  63. assign duty_data = (freq_data >> 1);
  64. //beep输出设计
  65. always@(posedge clk or negedge reset_n)
  66. if(!reset_n)
  67. beep <= 1'd0;
  68. else if(freq_cnt > duty_data)
  69. beep <= 1'd1;
  70. else
  71. beep <= 1'd0;
  72. endmodule

(3)仿真文件代码;

  1. `timescale 1ns / 1ps
  2. module beep_tb;
  3. reg clk;
  4. reg reset_n;
  5. wire beep;
  6. beep beep_inst(
  7. .clk(clk),
  8. .reset_n(reset_n),
  9. .beep(beep)
  10. );
  11. defparam beep_inst.MCNT_Time = 25'd24_999_9;
  12. defparam beep_inst.Do = 20'd1908 ;
  13. defparam beep_inst.Re = 20'd1700 ;
  14. defparam beep_inst.Mi = 20'd1515 ;
  15. defparam beep_inst.Fa = 20'd1432 ;
  16. defparam beep_inst.So = 20'd1275 ;
  17. defparam beep_inst.La = 20'd1136 ;
  18. defparam beep_inst.Si = 20'd1012 ;
  19. initial clk = 1'b1;
  20. always #10 clk = ~clk;
  21. initial begin
  22. reset_n = 1'b0;
  23. #15;
  24. reset_n = 1'b1;
  25. #50_000_000;
  26. $stop;
  27. end
  28. endmodule

(4)仿真波形:

(5)引脚绑定:

  1. set_property IOSTANDARD LVCMOS33 [get_ports reset_n]
  2. set_property IOSTANDARD LVCMOS33 [get_ports clk]
  3. set_property IOSTANDARD LVCMOS33 [get_ports beep]
  4. set_property PACKAGE_PIN N15 [get_ports reset_n]
  5. set_property PACKAGE_PIN W19 [get_ports clk]
  6. set_property PACKAGE_PIN M17 [get_ports beep]

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小桥流水78/article/detail/835500
推荐阅读
相关标签
  

闽ICP备14008679号