FPGA实现蜂鸣器播放音乐实验,以儿歌《两只老虎》为例

**

FPGA实现蜂鸣器播放音乐

**

实现功能:

开发板上电后,通过蜂鸣器播放《两只老虎》。

设计思路

原理:想要让蜂鸣器播放音乐,就需要知道每个音符的频率,再通过换算将频率转换为周期,再结合开发板具体的系统时钟周期,便可计算出每个音符对应多少个系统时钟周期个数,通过对这些个数计数,便可控制蜂鸣器播放不同的音符,也就能播放歌曲。
例:音符1(dou)的频率是523HZ,它的周期是:1/523s,换算成ns是1912045ns,开发板时钟系统频率如果是50MHZ,则每个系统时钟周期是20ns,所以上述是1912045/20个系统周期个数。
具体每个音符的频率可参照下图对照表:

音符与频率对照表

在这里插入图片描述

《两只老虎》简谱

在这里插入图片描述

代码(全):

module beep_music  (
//输入与输出信号定义
input              clk  ,
input              rst_n,

output             beep
);
//中间信号定义
reg     [16:0]     cnt0    ;       //产生PWM的计数器
wire               add_cnt0;
wire               end_cnt0;

reg     [7:0]      cnt1    ;      //每个音符持续时间的计数器
wire               add_cnt1;
wire               end_cnt1;

reg     [5:0]      cnt2    ;     //《两只老虎》共32个音节
wire               add_cnt2;
wire               end_cnt2;

reg     [16:0]     pre_set ;    //存放每个音节的频率在系统中的时钟个数

//每个音符对应的系统周期计数,中音
localparam  M1=95602,           //音符1do
	        M2=85178,           //音符rui
	        M3=75872,           //音符mi
	        M4=71633,           //音符fa
	        M5=63775,           //音符so
	        M6=56818,           //音符la
	        M7=50607;           //音符xi

//每个音符对应的系统周期计数,低音音符so,频率392
//周期是1/392s,换算成ns是2551020ns,每个
//系统时钟周期是20ns,所以上述是2551020/20个系统周期个数127,551
localparam  D5=127551;         //音符so,低音


//每个音节的频率在系统时钟周期下对应的系统周期个数
//--------------------------------------------
//比如:音符1的频率是523HZ,它的周期是1/523s,换算成ns是1912045ns,每个
//系统时钟周期是20ns,所以上述是1912045/20个系统周期个数,即cnt0的计数
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        cnt0<=0;
    end
    else if(add_cnt0)begin
        if(end_cnt0)
            cnt0<=0;
        else
            cnt0<=cnt0+1;  
    end
end
assign add_cnt0=1'b1;
assign end_cnt0=add_cnt0 && cnt0==pre_set-1;
assign beep=(cnt0>=(pre_set/2))?1:0;          //每个音符的占空比为50%


//每个音符持续一段时间
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        cnt1<=0;
    end
    else if(add_cnt1)begin
        if(end_cnt1)
            cnt1<=0;
        else
            cnt1<=cnt1+1; 
    end
end
assign add_cnt1=end_cnt0;
assign end_cnt1=add_cnt1 && cnt1==150-1;

//计32个音符(两只老虎共32音节)
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        cnt2<=0;  
    end
    else if(add_cnt2)begin
        if(end_cnt2)
            cnt2<=0;   
        else 
            cnt2<=cnt2+1;
    end
end
assign add_cnt2=end_cnt1;
assign end_cnt2=add_cnt2 && cnt2==32-1;

//存放歌曲的简谱
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        pre_set<=0;  
    end
    else begin
        case(cnt2)
                0:pre_set<=M1;
				1:pre_set<=M2;
				2:pre_set<=M3;
				3:pre_set<=M1;
				4:pre_set<=M1;
				5:pre_set<=M2;
				6:pre_set<=M3;
				7:pre_set<=M1;
				8:pre_set<=M3;
				9:pre_set<=M4;
				10:pre_set<=M5;
				11:pre_set<=M3;
				12:pre_set<=M4;
				13:pre_set<=M5;
				14:pre_set<=M5;
				15:pre_set<=M6;
				16:pre_set<=M5;
				17:pre_set<=M4;
				18:pre_set<=M3;
				19:pre_set<=M1;
				20:pre_set<=M5;
				21:pre_set<=M6;
				22:pre_set<=M5;
				23:pre_set<=M4;
				24:pre_set<=M3;
				25:pre_set<=M1;
				26:pre_set<=M2;
				27:pre_set<=D5;
				28:pre_set<=M1;
				29:pre_set<=M2;
				30:pre_set<=D5;
				31:pre_set<=M1;
				default:pre_set<=0;
        endcase
    end
end
endmodule
  • 7
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
FPGA蜂鸣器播放音乐的方法是利用计数器产生PWM波形,根据乐谱设置震荡周期,并给蜂鸣器赋值。在无源蜂鸣器中,有震荡源直接通直流电就可发声,而无震荡源则需要通震荡波才能发声。 具体实现方法如下: 1. 首先,通过FPGA的计数器模块产生PWM波形。计数器的计数频率可以根据需要调整,一般情况下,计数频率越高,音质越好。通过设置计数器的初始值和周期,可以控制PWM信号的频率和占空比。 2. 根据乐谱将音符的频率转换为对应的震荡周期。音符的周期可以通过时钟频率除以音符频率得到,或者通过音符周期除以时钟周期得到。根据乐谱的要求,设置计数器的初始值和周期,使得计数器在每个音符周期内完成一个完整的循环。 3. 将计数器的值传递给蜂鸣器,使其发出对应频率的声音。通过将计数器的值赋给蜂鸣器的输入端口,可以控制蜂鸣器的振动和声音的产生。 总结:FPGA蜂鸣器播放音乐的方法是通过计数器产生PWM波形,根据乐谱设置震荡周期,并将计数器的值赋给蜂鸣器实现对应频率的声音。这样就可以利用FPGA蜂鸣器播放出音乐。<span class="em">1</span><span class="em">2</span> #### 引用[.reference_title] - *1* *2* [蜂鸣器播放音乐 fpga实现](https://blog.csdn.net/xianyudewo/article/details/120525690)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值