本实验基于Altera EP4CE10 征途Pro开发板进行设计与实现。通过设计实现按键控制蜂鸣器的发声与否,初始状态蜂鸣器不发声,按键按下发声,再次按下不发声。如此反复,通过按键控制蜂鸣器发声状态的变化。
一.开发板无源蜂鸣器发声原理的介绍
相对于有源蜂鸣器,无源蜂鸣器的成本更低,声音频率可控。而有源蜂鸣器因其内部自带振荡源,只要加上适当的直流电源即可发声,程序控制较为方便。无源蜂鸣器与有源蜂鸣器不同,因其内部不带震荡源,所以其无法向有缘蜂鸣器那样直接用直流信号驱动,这里需要使用PWM方波才能驱动其发声。
如何发出不同的声音呢?上面说到需要使用PWM方波才能驱动其发声,所以这里我们只要控制输入的PWM方波,输入不同的PWM方波发出的声音就不一样了。而不同频率和占空比的方波发出的声音是不同的,其中频率对音调有影响,占空比对音量大小有影响。所以我们只需产生不同频率和占空比的PWM方波去驱动无源蜂鸣器就能让 无源蜂鸣器发出不同的音调了。
不同音调的声音所对应的频率如下图:
而该开发板的系统时钟为50MHZ,对应的频率计数值如下:
二.蜂鸣器硬件电路原理图
功率放大器驱动:在beep端输入相应频率的PWM脉冲波即可驱动Buzzer发声。
由下图知:beep对应的FPGA管脚为J11。
三. Verilog程序设计
本设计主要包括按键消抖模块以及蜂鸣器驱动模块组成。
1.按键消抖模块:
运用软件消抖的方法:即检测出按键闭合后执行一个延时程序,根据抖动的时间5ms~10ms,我们产生一个20ms的延时,让前沿抖动消失后再一次检测键的状态,如果仍保持闭合状态电平,则确认为真正有键按下。
代码实现如下:
module key_filter
(
input wire sys_clk ,
input wire sys_rst_n ,
input wire key_in ,
output reg key_flag
);
parameter CNT_MAX = 20'd999_999 ;
reg [19:0] cnt_20ms ;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_20ms <= 20'b0;
else if(key_in == 1'b1)
cnt_20ms <= 20'b0;
else if(cnt_20ms == CNT_MAX && key_in == 1'b0)
cnt_20ms <= cnt_20ms;
else
cnt_20ms <= cnt_20ms + 1'b1;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
key_flag <= 1'b0;
else if(cnt_20ms == CNT_MAX - 1'b1)
key_flag <= ~key_flag;
else
key_flag <= key_flag ;
endmodule
通过按键按下改变key_flag信号的高低电平,按下一次进行翻转,进而用key_flag信号控制beep端的信号产生。
2. 蜂鸣器驱动模块:
在其中调用按键消抖模块,实现按键控制beep端的波形输出。
代码如下:
module beep
(
input wire sys_clk ,
input wire sys_rst_n ,
input wire key_in ,
output reg beep
);
parameter DO = 18'd190840 ;
reg [17:0] freq_cnt ;
wire [17:0] duty_data ;
wire key_flag ;
assign duty_data = DO >> 1'b1 ;
always@( posedge sys_clk or negedge sys_rst_n )
if( sys_rst_n == 1'b0 )
freq_cnt <= 18'd0 ;
else if( freq_cnt == DO )
freq_cnt <= 18'd0 ;
else
freq_cnt <= freq_cnt + 1'b1 ;
key_filter key_filter_inst
(
.sys_clk (sys_clk ),
.sys_rst_n (sys_rst_n ),
.key_in (key_in ),
.key_flag (key_flag )
);
always@( posedge sys_clk or negedge sys_rst_n )
if( sys_rst_n == 1'b0 )
beep <= 1'b0 ;
else if ( freq_cnt >= duty_data && key_flag == 1'b1 )
beep <= 1'b1 ;
else
beep <= 1'b0 ;
endmodule
通过按键控制蜂鸣器发出do音。
四.FPGA引脚配置
系统时钟,按键输入,复位信号管脚如下图:(buzzer管脚见上文)
Pin设置如下:
五. 程序上板调试
开发板接入电源线以及FPGA下载器:
可通过按键控制蜂鸣器的发声,功能成功实现。