蜂鸣器播放《两只老虎》

这篇具有很好参考价值的文章主要介绍了蜂鸣器播放《两只老虎》。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

  通过往期的按键控制蜂鸣器课程,我们了解了蜂鸣器器件,本次课程将使用蜂鸣器,播放我小时候经常听的《两只老虎》音乐,来勾起我童年的回忆。


一、回顾蜂鸣器

  我们回顾一下蜂鸣器的知识:

  1. 按照工作原理可分为:压电式蜂鸣器和电磁式蜂鸣器。
  2. 按照音源可分为:有源蜂鸣器和无源蜂鸣器。
  3. 有源蜂鸣器:内部有振荡源,直接通以直流电即可发出声音。
  4. 无源蜂鸣器:内部无振荡源,需要通以方波、PWM信号才能发出声音。

蜂鸣器播放《两只老虎》

图1. 蜂鸣器原理图

  无源蜂鸣器需要输入一定频率的方波或者脉冲宽度调制(Pulse Width Modulation,PWM)信号,蜂鸣器就可以发出声音。输入不同频率的信号,蜂鸣器可以发出不同音色的声音。《红楼梦》中“未见其人先闻其声”指的是王熙凤,就是因为每个人发出的声音频率不同,所以音色也会不同,我们可以通过音色就知道谁是谁。


二、乐谱知识

2.1 音符音频

  音频(Audio),指人耳可以听到的声音频率在20HZ~20kHz之间的声波。乐普是由音符组成的,不同的音符拥有不同的频率。音频和周期的关系如下公式所示。
T ( 周 期 ) = 1 f ( 频 率 ) (1) T(周期) = \frac{1}{f(频率)}\tag1 T()=f()1(1)

蜂鸣器播放《两只老虎》

表1. 音频表

  我们可以根据表中音符频率用公式(1)计算出音符振动的周期,单位微秒。Cyclone IV开发板的晶振是50MHz,振动一次是20纳秒,使用周期时间除以20纳秒得出音符振动的次数。比如高音的DO计算方式如下公式(2)所示。

D O ( 高 ) = 955 × 1 0 3 20 = 47750 (2) DO(高) = \frac{955\times10^3}{20}\tag2=47750 DO()=20955×103=47750(2)

2.2 两只老虎乐谱

  两只老虎乐谱一共有34个音符,1对应DO,2对应RE,3对应MI…。一个音符持续的时间很短,需要设置一个持续时间,重复播放该音符,这样我们才能听得出来。本实验中设置音符持续时间(节拍)300毫秒,要想使两只老虎听起来更完美,同学们下去得学习乐谱中节拍知识,根据乐谱中节拍设置音符的持续时间。

蜂鸣器播放《两只老虎》

图2. 两只老虎乐谱

三、系统框图

蜂鸣器播放《两只老虎》

图3. 系统框图

四、模块调用

蜂鸣器播放《两只老虎》

图4. 模块关系示意图

五、模块原理图

蜂鸣器播放《两只老虎》

图5. 模块原理图

六、工程源码

6.1 音符选择模块代码

module freq_select
(
	input  wire 	clk  ,//时钟信号
	input  wire 	rst_n,//复位信号
	
	output reg		flag//pwm标志     
	
);
parameter   CNT_MAX = 24'd14_999_999;//300ms
parameter   NUM_FRE = 6'd33			;//34个音符
parameter   DO  	= 16'd47750		;//1
parameter   RE  	= 16'd42250		;//2
parameter   MI  	= 16'd37900		;//3
parameter   FA  	= 16'd37550		;//4
parameter   SO  	= 16'd31850		;//5
parameter   LA      = 16'd28400		;//6
parameter   XI      = 16'd25400		;//7
reg  [23:0]  cnt_delay   ;//300ms计数器
reg  [5:0]	 lut_data    ;//乐谱数据寄存器
reg  [15:0]	 cnt_freq    ;//音符音频计数器
reg  [15:0]	 freq_data   ;//音符数据寄存器
wire [14:0]  duty_data   ;//占空比数据
wire 		 end_note    ;//音符结束标志
wire 		 end_spectrum;//音谱结束标志
//单个音符持续时间计时模块
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		cnt_delay <= 24'd0;
	end 
	else if(cnt_delay == CNT_MAX)begin
		cnt_delay <= 24'd0;
	end 
	else begin
		cnt_delay <= cnt_delay + 1'd1;
	end 
end 

//音符计时模块
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		cnt_freq <= 16'd0;
	end 
	else if(end_note)begin
		cnt_freq <= 16'd0;
	end 
	else begin
		cnt_freq <= cnt_freq + 1'd1;
	end 
end 

//音谱计时模块
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		lut_data <= 6'd0;
	end 
	else if(end_spectrum)begin
		lut_data <= 6'd0;
	end 
	else if(cnt_delay == CNT_MAX)begin
		lut_data <= lut_data + 1'd1;
	end 
	else begin
		lut_data <= lut_data;
	end 
end 

//音符查找表模块
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		freq_data <= DO;
	end 
	else begin
		case(lut_data)
			6'd0:	freq_data <= DO;
			6'd1:	freq_data <= RE;
			6'd2:	freq_data <= MI;						
			6'd3:	freq_data <= DO;					
			6'd4:	freq_data <= DO;					
			6'd5:	freq_data <= RE;					
			6'd6:	freq_data <= MI;					
			6'd7:	freq_data <= DO;					
			6'd8:	freq_data <= MI;					
			6'd9:	freq_data <= FA;					
			6'd10:	freq_data <= SO;
			6'd11:	freq_data <= MI;
			6'd12:	freq_data <= FA;
			6'd13:	freq_data <= SO;
			6'd14:	freq_data <= SO;
			6'd15:	freq_data <= LA;
			6'd16:	freq_data <= SO;
			6'd17:	freq_data <= FA;
			6'd18:	freq_data <= MI;
			6'd19:	freq_data <= DO;
			6'd20:	freq_data <= SO;
			6'd21:	freq_data <= LA;
			6'd22:	freq_data <= SO;
			6'd23:	freq_data <= FA;
			6'd24:	freq_data <= MI;
			6'd25:	freq_data <= DO;
			6'd26:	freq_data <= RE;
			6'd27:	freq_data <= SO;
			6'd28:	freq_data <= DO;
			6'd29:	freq_data <= DO;
			6'd30:	freq_data <= RE;
			6'd31:	freq_data <= SO;
			6'd32:	freq_data <= DO;
			6'd33:	freq_data <= DO;
			default:freq_data <= DO;
		endcase  
	end         
end  

assign duty_data = freq_data >> 1;//占空比50%

assign end_note = cnt_freq == freq_data;
assign end_spectrum = lut_data == NUM_FRE && cnt_delay == CNT_MAX;
//pwm信号产生模块
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		flag <= 1'b0;
	end 
	else begin
		flag <= (cnt_freq >= duty_data) ? 1'b1 : 1'b0; 
	end 	 
end         
endmodule                

6.2 pwm产生模块代码

module gen_pwm
(
	input  wire 	clk  ,//时钟
	input  wire 	rst_n,//复位信号
	input  wire 	flag ,//pwm标志信号
	
	output reg 		beep//蜂鸣器信号
);

//pwm控制蜂鸣器模块
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		beep <= 1'b1;
	end 
	else if(flag)begin
		beep <= 1'b0;
	end 	
	else begin
		beep <= 1'b1;
	end 
end 
endmodule 

6.3 顶层模块代码

module pwm_beep(
	input  wire clk  ,
	input  wire rst_n,
	
	output wire beep
);

parameter   CNT_MAX = 24'd14_999_999;//300ms
parameter   DO  	= 16'd47750		;//1
parameter   RE  	= 16'd42250		;//2
parameter   MI  	= 16'd37900		;//3
parameter   FA  	= 16'd37550		;//4
parameter   SO  	= 16'd31850		;//5
parameter   LA      = 16'd28400		;//6
parameter   XI  	= 16'd25400		;//7
wire flag;

//实例化音频选择模块
freq_select#(
.CNT_MAX 	(CNT_MAX),
.DO  	  	(DO)     ,
.RE  	  	(RE)     ,
.MI  	  	(MI)     ,
.FA  	  	(FA)     ,
.SO  	  	(SO)     ,
.LA     	(LA)     ,
.XI  	  	(XI)
) u_freq_select(

.clk		(clk)  ,
.rst_n		(rst_n),
		
.flag		(flag)
);
//实例化pwm产生模块
gen_pwm	u_gen_pwm
(
.clk		(clk)  ,
.rst_n		(rst_n),
.flag		(flag) ,
		
.beep		(beep)
);
endmodule 

七、仿真测试

7.1 测试代码

`timescale 1ns/1ns
module pwd_beep_tb();

parameter   CNT_MAX = 24'd21;//一个音符持续时间
parameter   DO  	= 16'd7;//1
parameter   RE  	= 16'd6;//2
parameter   MI  	= 16'd5;//3
parameter   FA  	= 16'd4;//4
parameter   SO  	= 16'd3;//5
parameter   LA      = 16'd2;//6
parameter   XI  	= 16'd1;//7
parameter 	CYCLE   = 20;
reg 	clk  ;
reg 	rst_n;
wire 	beep ;

always #(CYCLE/2) clk = ~clk;

initial begin
	clk   = 1'b0		 ;
	rst_n = 1'b0		 ;
	#(CYCLE)    		 ;
	rst_n = 1'b1		 ;
	#(7*CYCLE*CNT_MAX*34);
	$stop				 ;

end

pwm_beep#(
.CNT_MAX (CNT_MAX),
.DO		 (DO)	  ,	
.RE		 (RE)	  ,	
.MI		 (MI)     ,
.FA		 (FA)	  ,
.SO		 (SO)	  ,
.LA		 (LA)	  ,
.XI		 (XI)	
)	u_pwm_beep(
.clk  	(clk)  ,
.rst_n	(rst_n),
			
.beep		(beep)
);
endmodule 

7.2 仿真结果

蜂鸣器播放《两只老虎》

图6. 仿真结果

八、管脚信息

蜂鸣器播放《两只老虎》

图7. pin planner
元件 管脚
KEY1 E15
KEY2 E16
KEY3 M16
KEY4 M15
CLOCK(时钟) E1
BUZZER(蜂鸣器) J1
表2. 管脚信息表

九、运行效果

蜂鸣器播放两只老虎


总结

  以上就是本期蜂鸣器播放两只老虎的主要内容,通过本次的学习,同学们下去可以使用蜂鸣器播放其他音乐,只要你手里面有乐谱,原理上是可以编写任何音乐。赶紧行动起来,成为一个会写代码的音乐家吧!谢谢你的观看。文章来源地址https://www.toymoban.com/news/detail-400664.html

到了这里,关于蜂鸣器播放《两只老虎》的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 《FPGA学习》->蜂鸣器播放

    🍎 与其担心未来,不如现在好好努力。在这条路上,只有奋斗才能给你安全感。你若努力,全世界都会为你让路。 蜂鸣器的发声原理由振动装置和谐振装置组成,而蜂鸣器又分为无源他激型与有源自激型。本实验采用无源蜂鸣器,蜂鸣器的发声不同是靠频率不同进行控制的

    2024年02月08日
    浏览(46)
  • FPGA拾忆_(10):按键控制蜂鸣器_边沿检测_按键消抖

    1.硬件特征: 轻触式(回弹式)按键         略 蜂鸣器: 分为蜂鸣器按照结构原理不同可分为压电式蜂鸣器和电磁式蜂鸣器。 压电式蜂鸣器主要由多谐振荡器、压电蜂鸣片、 阻抗匹配器及共鸣箱、外壳等组成; 电磁式蜂鸣器由振荡器、电磁线圈、磁铁、振动膜片及外壳等组

    2024年04月10日
    浏览(41)
  • PADS-按键、蜂鸣器、继电器PCB封装设计

    放置一个表贴端点,更改矩形尺寸,同时计算与原点的距离,这里我们按7.9+0.2最大值来放置   分步与重复,放置右边的端点,然后根据样式,先画一个矩形,然后改变宽的尺寸,3.8/1.2得出1.9 同样改一下长的坐标6.3/2=3.15  把线宽改细一点 W 0.1,或者双击改线宽  添加倒角

    2024年02月13日
    浏览(55)
  • 【FPGA】五、蜂鸣器播放音乐

    文章目录 前言 一、蜂鸣器简介 二、音频音符简介 三、任务要求 四、程序设计 1、设计思路  2、程序代码    总结         蜂鸣器(Buzzer)是现代常用的一种电子发声器,主要用于产生声音信号。它是一种一体化结构的电子讯响器,采用直流电压供电,被广泛用于计算机、

    2024年02月11日
    浏览(49)
  • 【STM32】控制LED灯和蜂鸣器的按键实验

    🐱作者:一只大喵咪1201 🐱专栏:《STM32学习》 🔥格言: 你只管努力,剩下的交给时间! 本喵这次介绍的实验是按键实验,同样使用STM32F103ZE型号的芯片,在开发板上有4个按键,实验目的是每按一个按键就会让LED灯或者是蜂鸣器的工作状态发生反转,下面本喵来详细介绍。

    2024年02月03日
    浏览(62)
  • STM32 蜂鸣器介绍 配置 播放音节

             蜂鸣器一般被分为两类 : 有源蜂鸣器 和 无源蜂鸣器 。 其中源是振荡源 。 有源蜂鸣器内部有振荡电路,可以把直流电源转换为一定频率的脉冲信号。 因为它一直输出一定的频率,我们无法改变频率,所以声音只有一种,我们只能通过电源,控制它发不发声。

    2024年02月04日
    浏览(43)
  • STM32蜂鸣器播放音乐(代码全)

    在STM32F103ZET6板子上使用蜂鸣器播放音乐,我们可以将其分为几个模块:初始化模块、蜂鸣器控制模块、音乐播放模块和主函数模块。以下是一个简单的示例代码,使用STM32 HAL库和定时器来驱动蜂鸣器播放音乐。 首先,确保你已经配置了STM32CubeMX或STM32CubeIDE,并生成了HAL库代码

    2024年04月25日
    浏览(43)
  • key_beep按键控制蜂鸣器程序及流程图

    使用按键控制蜂鸣器发声。 初始状态为蜂鸣器鸣叫,按下开关后蜂鸣器停 止鸣叫,再次按下开关,蜂鸣器重新鸣叫。

    2024年02月12日
    浏览(50)
  • 使用单片机控制蜂鸣器播放音乐的代码

    在嵌入式系统中,单片机常常被用于控制各种外设,其中包括蜂鸣器。蜂鸣器是一种能够发出声音的电子元件,可以通过单片机的控制来播放各种音乐或声效。本文将介绍如何使用单片机控制蜂鸣器播放音乐,并提供相应的源代码。 在开始编写代码之前,我们首先需要确定使

    2024年02月01日
    浏览(39)
  • STM32第三课:按键控制LED灯,光敏传感器控制蜂鸣器

            STM32的第三课,我们来学习如何使用按键来控制LED灯的亮灭。上一节课我们通过代码控制了LED的状态,但是还是处于一种较为低级的方式控制LED灯,缺少交互性,用按键进行控制属于更高的一个层次。然后我们将学习通过光敏传感器控制蜂鸣器的通断,让我们的学

    2024年04月29日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包