蜂鸣器演奏音乐

  1.产生pwm模块,通过音乐乐谱,产生pwm     

module gen_pwm(
   input wire  clk,//时钟信号
   input wire  rst_n,
   
   output wire pwm  //脉宽调制信号
);
parameter CNT300MS=24'd14_999_999;//300ms最大数
parameter NOTES   =6'd33;//音符最大数
//************音符参数定义*********//
parameter DO=16'd47749,
          RE=16'd42549,
		  MI=16'd37899,
		  FA=16'd37549,
		  SO=16'd31849,
		  LA=16'd28399,
		  XI=16'd25399;
reg [15:0] cnt_freq;//音频计数寄存器

reg [15:0] X;
wire[15:0] duty_data;//占空比数据

wire      start_cnt_freq;//开始音频计数条件
wire      end_cnt_freq;//结束音频计数条件
//*************************************//
//******音符计数*************//
reg [5:0] cnt_note;//音符计数寄存器
wire  start_cnt_note;//音符开始计数条件
wire  end_cnt_note;//音符结束条件条件
//*****300ms计数*******************//
reg [23:0] cnt_300ms;//300ms计数寄存器
wire       start_cnt_300ms;//300ms开始计数条件
wire       end_cnt_300ms;//300ms结束计数条件

//300ms计数器
always @(posedge clk or negedge rst_n)begin
  if(!rst_n)begin//初始化
     cnt_300ms <= 24'd0;//计数寄存器值置零
  
  end
  else if (start_cnt_300ms)begin//开启计数
      if(end_cnt_300ms)begin//满足记到最大数
	     cnt_300ms<=24'd0;//计数寄存器清零
	  
	  end
	  else begin
	     cnt_300ms<=cnt_300ms+24'd1;//不满足,每次加一
	  end
  
  end
   else begin
     cnt_300ms<=cnt_300ms;//保持
   end
end
assign start_cnt_300ms=1'b1;
assign end_cnt_300ms=(start_cnt_300ms && cnt_300ms==CNT300MS);//结束条件

//34个音符计数器
always @(posedge clk or negedge rst_n)begin
  if(!rst_n)begin
      cnt_note <= 6'd0;
  end
  else if(start_cnt_note)begin
     if(end_cnt_note)begin
	   cnt_note<=6'd0;
	 end
	 else begin
	   cnt_note <= cnt_note +6'd1;
	 end
  end
  else  begin
     cnt_note<=cnt_note; 
   end	 

end
assign start_cnt_note=end_cnt_300ms;//****重点*****//
assign end_cnt_note=(start_cnt_note && cnt_note==NOTES);
//音频计数器
always @(posedge clk or negedge rst_n)begin
   if(!rst_n)begin
      cnt_freq <= 16'd0;
   end
   else if(start_cnt_freq)begin
      if(end_cnt_freq)begin
	     cnt_freq <= 16'd0;
	  end
	  else begin
	     cnt_freq <= cnt_freq + 1'd1;
	  end
   end
   else begin
       cnt_freq <= cnt_freq;
   end

end
assign start_cnt_freq = 1'b1;
assign end_cnt_freq=(start_cnt_freq && cnt_freq==X);

//音频查找表
always @(*)begin
   case(cnt_note)
      6'd0: X=DO;//1
	  6'd1: X=RE;//2
	  6'd2: X=MI;//3	
	  6'd3: X=DO;//4
	  6'd4: X=DO;//1
	  6'd5: X=RE;//2
	  6'd6: X=MI;//3
	  6'd7: X=DO;//4
	  6'd8: X=MI;//3
	  6'd9: X=FA;//4
	  6'd10:X=SO;//5
	  6'd11:X=MI;//3
	  6'd12:X=FA;//4
	  6'd13:X=SO;//5
	  6'd14:X=SO;//5
	  6'd15:X=LA;//6
	  6'd16:X=SO;//5
	  6'd17:X=FA;//4
	  6'd18:X=MI;//3
	  6'd19:X=DO;//1
	  6'd20:X=SO;//5
	  6'd21:X=LA;//6
	  6'd22:X=SO;//5
	  6'd23:X=FA;//4
	  6'd24:X=MI;//3
	  6'd25:X=DO;//1
	  6'd26:X=RE;//2
	  6'd27:X=SO;//5
	  6'd28:X=DO;//1
	  6'd29:X=DO;//1
	  6'd30:X=RE;//2
	  6'd31:X=SO;//5
	  6'd32:X=DO;//1
	  6'd33:X=DO;//1
	  default:X=DO ;
   endcase

end
assign duty_data=X >>1;//50%的占空比
assign pwm=(cnt_freq > duty_data) ? 1'b1:1'b0;
endmodule

   2.蜂鸣器控制模块,用于开启蜂鸣器,并播放音乐

module beep_ctrl
   (
      input wire clk,
	  input wire rst_n,
	  input wire pwm,
	  
	  output reg beep
   
   );
always @(posedge clk or negedge rst_n)begin
  if(!rst_n)begin
     beep <= 1'b1;
  end
  else if(pwm)begin//根据pwm信号开启蜂鸣器
     beep <= 1'b0;
  end
  else begin
     beep <= 1'b1;
  end
end
endmodule 

   3.顶层模块

     

module music_top
 (
    input wire clk,
	input wire rst_n,
	
	output wire beep
 );
 
wire pwm; 
gen_pwm  gen_pwm_inst
 (
     . clk  (clk),//时钟信号
     . rst_n(rst_n),
         
     . pwm  (pwm)//脉宽调制信号
);

beep_ctrl beep_ctrl
   (
      .clk   (clk),
	  .rst_n (rst_n),
	  .pwm   (pwm),
	 
	  . beep (beep)
   
   );

endmodule

  通过这篇文章,从中获得学习灵感:蜂鸣器播放《两只老虎》_FPGA中国创新中心的博客-CSDN博客

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值