本文介绍在EBAZ4205平台上用PL的资源驱动无源蜂鸣器
注,扩展板上有部分蜂鸣器规格错了,装成了压电式的,导致无法出声,看到的请在购买链接联系我
详细的工程创建过程可以参考项目1,本文仅介绍 蜂鸣器驱动模块部分的实现
1.)电路部分
无源蜂鸣器的驱动部分如上图所示,当三极管导通时,蜂鸣器上流过电流,当三极管关闭,蜂鸣器上电流停止流过。
蜂鸣器的驱动部分连接到EBAZ4205 的D18管脚
2)无源蜂鸣器简单介绍
无源蜂鸣器不像有源蜂鸣器那样只要通上电就会发出声音,无源蜂鸣器内部没有振荡驱动单元,需要以一定的振荡频率去驱动蜂鸣器,让蜂鸣器以特定的频率进行发声, 缺点是驱动方式稍复杂,优点就是可以发出不同音调的声音。
以下为查资料得知的每个乐调对应的频率。
根据每个音调的频率值,可以计算得出PWM发送模块的预重装值,以下为计算得出的音调频率与对应PWM发送模块输出相应频率的预重装值。(对应的是50M时钟下的值)
计算举例 50M频率下 1S的振荡次数是 50_000_000次, 而261.6hz的周期是1秒循环261.6次,那么在50M频率下 261.6hz的一个周期相当于振荡50_000_000/261.6=191_131 即下图中的预重装值
因为驱动蜂鸣器PWM 的占空比是50%,所以高电平低电平各占一半,所以高低电平的预装周期分别为 整个周期的一半,即完整预装值/2, 也可以用右移一位来替代
3) 代码实现
`timescale 1ns / 1ps module BEEP_MODULE( input clk,//50m 波形 output reg beep ); parameter D0=191130; parameter RE=170241; parameter MI=151698; parameter FA=143183; parameter SO=127550; parameter LA=113635; parameter XI=101234; //PWM 发声模块,用来产生特定的PWM波形 reg [16:0]beep_pwm_count; reg [16:0]beep_pwm; always@(posedge clk) if(beep_pwm_count>=beep_pwm)begin beep_pwm_count<=17'd0; beep<=~beep; end else beep_pwm_count<=beep_pwm_count+1'b1; reg [2:0]voice_mode; parameter T500_MS = 26'd25_000_000 ; reg [24:0]time_count;// //初始化寄存器用 initial begin voice_mode<=3'd0; time_count<=25'd0; end //0.5秒定时器,每0.5秒改变一次声调,通过voice_mode来调整音调 always@(posedge clk) if(time_count>=T500_MS)begin time_count<=25'd0; if(voice_mode>=3'd6)voice_mode<=3'd0; else voice_mode<=voice_mode+1'b1; end else time_count<=time_count+1'b1; //将当前voice_mode对应的音调值赋给 beep_pwm寄存器 //向右移动一位的作用是,预设值是实际波长的一半 always@(posedge clk) case(voice_mode) 3'd0:beep_pwm<=D0>>1; 3'd1:beep_pwm<=RE>>1; 3'd2:beep_pwm<=MI>>1; 3'd3:beep_pwm<=FA>>1; 3'd4:beep_pwm<=SO>>1; 3'd5:beep_pwm<=LA>>1; 3'd6:beep_pwm<=XI>>1; endcase endmodule
4)完整工程