Menu Close

FPGA 应用 – 蜂鸣器实验

在FPGA 实验中, 我们也会使用蜂鸣器作为人机交互的接口, 蜂鸣器在硬件设计中经常会被使用。 最熟悉的就是我们平时使用的台式计算机。几乎每个计算机都保留了蜂鸣器的功能。 蜂鸣器的硬件设计通常比较简单, 硬件连接也比较容易, 在硬件电路设计中, 往往被用来作为调试和警告来使用。 比如计算机的蜂鸣器有很多不同的发声方式, 代表着不同的硬件状态。部分使用方式列举如下:

1长3短:键盘控制器错误。

1长9短:主板Flash RAM或EPROM错误,BIOS损坏。

不断地响(长声):内存条未插紧或损坏。

不停地响:电源、显示器未和显卡连接好。

重复短响:电源有问题。

无声音无显示:电源有问题。

所以我们有必要学习蜂鸣器的使用, 同时在fpga设计中,如果能够灵活应用蜂鸣器,可以作为帮助我们快速检测 bug 的一个手段。当然在学习中如果能编写出不同音响效果也增加了我们学习FPGA的趣味性。

在PRX100T-D的开发板中, 我们使用的是表贴的(SMT) 7.5mm * 7.5mm * 2.5mm 的器件。具体型号可以参考该板的BOM。硬件原理如图1和图2所示:

%title插图%num

图1

 

%title插图%num

图2

只要在buzzer 端提供不同频率信号, 蜂鸣器就可以连续发声根据官方的手册中提供的图3所示的频响曲线:
%title插图%num

图3

从上图我们可以看到, 在100hz 到10k hz 下,蜂鸣器可以正常发出声音。(纵坐标单位dB)

 

根据蜂鸣器的特性, 我们设计了一个实验: 利用PRX100T-D 开发板中的7个按键, 实现 1,2,3,4,5,6,7 (do, re, mi, fa, so, la, si):

1: 523.25Hz,   1911132 ns
2: 587.33Hz,  1702620 ns
3: 659.26Hz,  1516852 ns
4: 698.46Hz,  1431721 ns
5: 783.99Hz,  1275526 ns
6: 880.00Hz, 1136363 ns
7: 987.77Hz,   1012381 ns

 

FPGA 代码如下:

module TOP#
(
    SIM_MODE = "FALSE"
)
(
    input IN_CLK_50M, //外部时钟
    input [7:1] PB,   //外部按键 消抖后选择需要的使用

    output buzzer,    //buzzer pin 输出pin

    output led        //fpga心跳 
);

//==================================================================================
//时钟模块 复位电路
wire clk_50m;
wire locked;

pll SYS_PLL
(
    .clk_in1 (IN_CLK_50M),

    .locked (locked), 
    .clk_out1 (clk_50m), 
    .reset (1'b0)
);

wire pb_rst; //按键复位脉冲 高电平有效
wire rst_r_n; //复位寄存

assign rst_r_n = locked; //低有效 locked 或按键触发
//==================================================================================
reg [31:0] rst_cnt = 0; //复位延时计数
reg sys_rst_n = 0; //系统时钟 locked 系统复位

always @ (posedge clk_50m)
if(!rst_r_n)
    sys_rst_n <= 0;
else
begin
    if(rst_cnt >= 500) //delay 500ms
        sys_rst_n <= 1;
    else
    begin
        sys_rst_n <= 0; //计数不到 保持复位状态
        rst_cnt <= rst_cnt +1;
    end
end

wire sys_clk = clk_50m; 
//==================================================================================
wire [7:1] pb_flag = 0; // PRX100T-D low level = button press 
always @ (posedge sys_clk)
pb_flag <= ~PB;

//==================================================================================


buzzer_top 
#(
    .MAIN_CLK (50)
)
buzzer_top_inst
(
    .sys_clk (sys_clk), //系统时钟

    .pb_flag (pb_flag),
    .buzzer (buzzer),

    .rst_n (sys_rst_n)
);


//==================================================================================

reg [23:0] led_cnt = 0;
always @ (posedge sys_clk)
if(!sys_rst_n) led_cnt <= 0;
else led_cnt <= led_cnt + 1;

assign led = led_cnt[23];

//==================================================================================
endmodule

 

端口设计:

 

input IN_CLK_50M, //外部时钟

input [7:1] PB, //外部按键 消抖后选择需要的使用output buzzer, //buzzer pin 输出pinoutput led //fpga心跳

其中 PB 为prx100t上的7个按键,buzzer 为 蜂鸣器的输出, led 为 fpga的心跳灯

 

buzzer 模块例化为:

buzzer_top
#(
    .MAIN_CLK (50)
)
buzzer_top_inst
(
    .sys_clk (sys_clk), //系统时钟
    .pb_flag (pb_flag),
    .buzzer (buzzer),
    .rst_n (sys_rst_n)
);

由于prx100t-d硬件设计中,按键平时为高, 按下键后 PB为低。 所以:

 

reg [7:1] pb_flag = 0; // PRX100T-D low level = button press

always @ (posedge sys_clk) pb_flag <= ~PB;

fpga phy 代码:

localparam CLK_NS = MAIN_CLK == 50 ? 20 : 10;

localparam DO_FREQ_X2 = 1911132/2; // 523.25Hz, 1911132 ns
//=============================================================
reg [23:0] do_ns = 0;
always @ (posedge sys_clk)
if(do_ns >= DO_FREQ_X2) do_ns <= 0;
else do_ns <= do_ns + CLK_NS;

wire do_r = (do_ns >= DO_FREQ_X2) ? 1’b1 : 1’b0; // 523.25Hz, 1911132 ns
always @ (posedge sys_clk)
if(do_r) do_freq <= ~do_freq;

这时 do_freq 输出为 1 (do)对应的频率(523.25Hz),以此类推可以得到其它6个音符的频率,程序细节可以参照工程中的程序。

按键选择代码:

wire [6:0] audio_key = pb_flag;


always @ (posedge sys_clk)
if(!rst_n) buzzer <= 0;
else case (audio_key)
7’b000_0001: buzzer <= do_freq; // 按键1, 选择 do
7’b000_0010: buzzer <= re_freq; // 按键2, 选择 re
7’b000_0100: buzzer <= mi_freq; // 按键3, 选择 mi
7’b000_1000: buzzer <= fa_freq; // 按键4, 选择 fa
7’b001_0000: buzzer <= so_freq; // 按键5, 选择 so
7’b010_0000: buzzer <= la_freq; // 按键6, 选择 la
7’b100_0000: buzzer <= si_freq; // 按键7, 选择 si
default: ;
endcase

 

总结:本文根据不同的按键, 选择do, re, mi, fa, so, la, si 等不同的频率。这里仅介绍了音符的简单设计方法,以此类推只要有足够的按键,全音符,和弦甚至乐曲等音乐内容都可以实现。

实验视频:

工程代码(注册用户可见)

本文隐藏内容 登陆 后才可以浏览

相关资料下载:

buzzer_cmt-7525-80-smt-tr

 

Posted in FPGA, FPGA, FPGA, IP开发, 开发板, 教材与教案, 文章

发表评论

相关链接