FPGA学习日记(16)--无源蜂鸣器驱动

该博客介绍了一个用Verilog编写的音乐蜂鸣器控制器模块,它使用参数来配置不同音符的频率,并在每个500ms周期内切换音符。通过内部计数器控制蜂鸣器的频率和占空比,从而产生不同的音调。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

module beep
#(
    parameter  CNT_MAX = 25'd24_999_999,
    parameter       DO = 18'd190839, 
    parameter       RE = 18'd170067,
    parameter       MI = 18'd151514,
    parameter       FA = 18'd143265,
    parameter       SO = 18'd127550,
    parameter       LA = 18'd113635,
    parameter       XI = 18'd101213
 
)
(
    input   wire     sys_clk          ,   
    input   wire     sys_rst_n        ,
    
    output  reg    beep
);

reg [24:0] cnt;
reg [2:0]   cnt_500ms;
reg [17:0] freq_cnt;
reg [17:0] freq_data;
wire [16:0] duty_data;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)   
        cnt <= 25'd0;
    else if (cnt == CNT_MAX)
        cnt <= 25'd0;
    else
        cnt <= 1'b1 + cnt;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0) 
        cnt_500ms <= 3'd0;
    else if((cnt_500ms == 3'd6)&&(cnt == CNT_MAX))
        cnt_500ms <= 3'd0;
    else if(cnt == CNT_MAX)
        cnt_500ms <= 1'b1 + cnt_500ms;
    else    
        cnt_500ms <= cnt_500ms;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0) 
        freq_cnt <= 18'd0;
    else  if((freq_cnt == freq_data)||(cnt == CNT_MAX))
        freq_cnt <= 18'd0;
    else 
        freq_cnt <= freq_cnt + 1'b1;
        
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0) 
         freq_data <= DO;
    else case (cnt_500ms)
        3'd0:freq_data <= DO;
        3'd1:freq_data <= RE;
        3'd2:freq_data <= MI;
        3'd3:freq_data <= FA;
        3'd4:freq_data <= SO;
        3'd5:freq_data <= LA;
        3'd6:freq_data <= XI;
        default:freq_data <= DO;
    endcase

assign duty_data = freq_data >> 1;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0) 
        beep <= 1'b0;
    else if (freq_cnt >= duty_data)
        beep <= 1'b1;
    else 
        beep <= 1'b0;
    
endmodule
`timescale 1ns/1ns
module tb_beep();

reg sys_clk;
reg sys_rst_n;

wire beep;

initial 
    begin 
        sys_clk =1'b1;
        sys_rst_n <= 1'b0;
        #20 
        sys_rst_n <= 1'b1;
    end
 
always #10 sys_clk = ~sys_clk;

beep
#(
    .  CNT_MAX(25'd24_999_999) ,
    .       DO(18'd19083) , 
    .       RE(18'd17006) ,
    .       MI(18'd15151) ,
    .       FA(18'd14326) ,
    .       SO(18'd12755) ,
    .       LA(18'd11363) ,
    .       XI(18'd10121) 
 
)
beep_inst
(
    .     sys_clk    (sys_clk)    ,   
    .     sys_rst_n  (sys_rst_n)    ,
    
    .   beep         (beep )
);
endmodule

 

 

cnt  每个周期增加一 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值