FPGA的学习:无源蜂鸣器的实现

Posted 石小舟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FPGA的学习:无源蜂鸣器的实现相关的知识,希望对你有一定的参考价值。

然后编写程序:

`timescale  1ns/1ns
module  beep
#(
    parameter   TIME_500MS =   25'd24999999,   //0.5s计数值
    parameter   DO  =   18'd190839 ,   //"哆"音调分频计数值(频率262)
    parameter   RE  =   18'd170067 ,   //"来"音调分频计数值(频率294)
    parameter   MI  =   18'd151514 ,   //"咪"音调分频计数值(频率330)
    parameter   FA  =   18'd143265 ,   //"发"音调分频计数值(频率349)
    parameter   SO  =   18'd127550 ,   //"梭"音调分频计数值(频率392)
    parameter   LA  =   18'd113635 ,   //"拉"音调分频计数值(频率440)
    parameter   XI  =   18'd101214     //"西"音调分频计数值(频率494)
)
(
    input   wire        sys_clk     ,   //系统时钟,频率50MHz
    input   wire        sys_rst_n   ,   //系统复位,低有效

    output  reg         beep            //输出蜂鸣器控制信号
);
//reg   define
reg     [24:0]  cnt         ;   //0.5s计数器
reg     [17:0]  freq_cnt    ;   //音调计数器
reg     [2:0]   cnt_500ms   ;   //0.5s个数计数
reg     [17:0]  freq_data   ;   //音调分频计数值

//wire  define
wire    [16:0]  duty_data   ;   //占空比计数值
//设置50%占空比:音阶分频计数值的一半即为占空比的高电平数
assign  duty_data   =   freq_data   >>    1'b1;

//cnt:0.5s循环计数器
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt <=  25'd0;
    else    if(cnt == TIME_500MS )
        cnt <=   25'd0;
    else
        cnt <=  cnt +   1'b1;

//cnt_500ms:对500ms个数进行计数,每个音阶鸣叫时间0.5s,7个音节一循环
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_500ms   <=  3'd0;
    else    if(cnt == TIME_500MS && cnt_500ms ==  6)
        cnt_500ms   <=  3'd0;
    else    if(cnt == TIME_500MS)
        cnt_500ms   <=  cnt_500ms + 1'b1;

//不同时间鸣叫不同的音阶
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        freq_data   <=  DO;
    else    case(cnt_500ms)
        0:  freq_data   <=   DO;
        1:  freq_data   <=   RE;
        2:  freq_data   <=   MI;
        3:  freq_data   <=   FA;
        4:  freq_data   <=   SO;
        5:  freq_data   <=   LA;
        6:  freq_data   <=   XI;
        default:  freq_data   <=   DO;
    endcase

//freq_cnt:当计数到音阶计数值或跳转到下一音阶时,开始重新计数
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        freq_cnt    <=  18'd0;
    else    if(freq_cnt == freq_data || cnt == TIME_500MS)
        freq_cnt    <=  18'd0;
    else
        freq_cnt    <=  freq_cnt +  1'b1;

//beep:输出蜂鸣器波形
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        beep    <=  1'b0;
    else    if(freq_cnt >= duty_data)
        beep    <=  1'b1;
    else
        beep    <=  1'b0;

endmodule

接着编写仿真代码

`timescale  1ns/1ns
module  tb_beep();
//reg   define
reg     sys_clk     ;   //时钟
reg     sys_rst_n   ;   //复位
//对时钟,复位信号赋初值
initial
    begin
        sys_clk     =   1'b1;
        sys_rst_n   <=  1'b0;
        #100
        sys_rst_n   <=  1'b1;
    end

//产生时钟信号
always #10 sys_clk =   ~sys_clk;
beep
#(
    .TIME_500MS(25'd24999),   //0.5s计数值
    .DO        (18'd190  ),   //"哆"音调分频计数值(频率262)
    .RE        (18'd170  ),   //"来"音调分频计数值(频率294)
    .MI        (18'd151  ),   //"咪"音调分频计数值(频率330)
    .FA        (18'd143  ),   //"发"音调分频计数值(频率349)
    .SO        (18'd127  ),   //"梭"音调分频计数值(频率392)
    .LA        (18'd113  ),   //"拉"音调分频计数值(频率440)
    .XI        (18'd101  )    //"西"音调分频计数值(频率494)
)
beep_inst
(
    .sys_clk     (sys_clk   ),   //系统时钟,频率50MHz
    .sys_rst_n   (sys_rst_n ),   //系统复位,低有效

    .beep        (beep      )    //输出蜂鸣器控制信号
);

endmodule

以上是关于FPGA的学习:无源蜂鸣器的实现的主要内容,如果未能解决你的问题,请参考以下文章

FPGA开拓者学习 蜂鸣器实验 难度易

FPGA实验蜂鸣器

FPGA/数字IC手撕代码11——基于PWM驱动的蜂鸣器verilog开发

Arduino播放歌曲应该用有源蜂鸣器还是无源蜂鸣器

有源蜂鸣器 和无源蜂鸣器 是啥意思

有源蜂鸣器和无源蜂鸣器