【FPGA】五、蜂鸣器播放音乐

这篇具有很好参考价值的文章主要介绍了【FPGA】五、蜂鸣器播放音乐。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

文章目录

前言

一、蜂鸣器简介

二、音频音符简介

三、任务要求

四、程序设计

1、设计思路

 2、程序代码   

总结


前言

        蜂鸣器(Buzzer)是现代常用的一种电子发声器,主要用于产生声音信号。它是一种一体化结构的电子讯响器,采用直流电压供电,被广泛用于计算机、报警器、电子玩具、定时器等一些列电子产品中。


一、蜂鸣器简介

        蜂鸣器按照其驱动方式不同主要分为有源蜂鸣器和无源蜂鸣器,两者的主要区别为蜂鸣器内部是否还有振荡源。一般有源蜂鸣器内部自带振荡源,通电就会发声,而无源蜂鸣器内部不含振荡源,需要外接振荡信号才能发声。

        相较于有源蜂鸣器,无源蜂鸣器的成本较低,而我们FPGA开发板上的蜂鸣器一般都是无源蜂鸣器,需要我们对其进行编程配置,我们利用不同的频率变化,控制蜂鸣器发出不同音调的声音。


二、音频音符简介

        我们是通过不同的频率去控制蜂鸣器的音调变化的,所以我们想要使蜂鸣器播放音乐,首先我们要直到不同音符所对应的频率,下面是低、中、高音下不同音符的频率对应表:

【FPGA】五、蜂鸣器播放音乐

         根据上图可以计算出不同音符振动的周期,我所采用的Cyclong IV开发板上的晶振时钟为50MHZ,每一个周期就是20ns。那么每个音调的分频系数为:50 000 000 / 音调频率(可四舍五入)。


三、任务要求

        本次设计的要求就是利用FPGA开发板上的无源蜂鸣器,通过不同振动频率播放歌曲两只老虎。

【FPGA】五、蜂鸣器播放音乐

 


四、程序设计

1、设计思路

        ① 首先我们需要计算出每个不同的音符对应的分频系数,由此产生不同的音调,我们需要设计一个分频计数器,来计数当前发出音调的分频系数。

        ② 然后我们需要一个节拍计数器,我们定义为半拍300ms,一拍500ms。

        ③ 利用组合逻辑case语句进行设计,将需要的节拍和要发出的音调写入case语句中。

 2、程序代码   

/*========================================*
    filename    : beep_music.v
    description : 无源蜂鸣器播放音乐实验
    time        : 2022-11-010 
    author      : 卡夫卡与海
*========================================*/

module beep_music(
    input          clk     ,//系统时钟 50MHZ
    input          rst_n   ,//系统复位

    output  reg    beep     //蜂鸣器控制信号
);
//参数定义
//每个音符震动一次所占用的时钟周期
//低音
parameter   MIN_DO = 18'd190800,//(50_000_000/262)
            MIN_RE = 18'd170050,//(50_000_000/294)
            MIN_MI = 18'd151500,//(50_000_000/330)
            MIN_FA = 18'd143250,//(50_000_000/349)
            MIN_SO = 18'd127550,//(50_000_000/392)
            MIN_LA = 18'd113600,//(50_000_000/440)
            MIN_XI = 18'd101200;//(50_000_000/494)
//中音
parameter   MID_DO = 17'd95600,//(50_000_000/523)
            MID_RE = 17'd85150,//(50_000_000/587)
            MID_MI = 17'd75850,//(50_000_000/659)
            MID_FA = 17'd71600,//(50_000_000/698)
            MID_SO = 17'd63750,//(50_000_000/784)
            MID_LA = 17'd56800,//(50_000_000/880)
            MID_XI = 17'd50600;//(50_000_000/988)
//高音
parameter   MAX_DO = 16'd47755,//(50_000_000/1047)
            MAX_RE = 16'd42553,//(50_000_000/1175)
            MAX_MI = 16'd37907,//(50_000_000/1319)
            MAX_FA = 16'd35790,//(50_000_000/1397)
            MAX_SO = 16'd31887,//(50_000_000/1568)
            MAX_LA = 16'd28409,//(50_000_000/1760)
            MAX_XI = 16'd25419;//(50_000_000/1967)

parameter   TIME_300ms = 24'd14_999_999,//300ms,半拍
            TIME_500ms = 25'd24_999_999;//500ms,一拍

parameter   NOTE_NUM = 6'd33;//音符个数  34个

//信号定义
reg    [24:0]    cnt_delay   ;//300ms或500ms计数器
reg    [5:0]     cnt_note    ;//音符计数器
reg    [18:0]    cnt_freq    ;//音符播放计数器
reg    [18:0]    freq_data   ;//音符数据寄存器

wire   [17:0]    duty_data   ;//占空比
wire             end_note    ;//单个音符播放结束标志
wire             end_flag    ;//所有音符结束标志

reg    [24:0]    cnt_delay_r ;

reg              flag        ;//蜂鸣器输出标志

//300ms计数器  cnt_delay 
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        cnt_delay <= 25'd0;
    end
    else if(cnt_delay == cnt_delay_r)begin
        cnt_delay <= 25'd0;
    end
    else begin
        cnt_delay <= cnt_delay + 1'b1;
    end
end

//音符计数器  cnt_note
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        cnt_note <= 6'd0;
    end
    else if(end_flag)begin
        cnt_note <= 6'd0;
    end
    else if(cnt_delay == cnt_delay_r)begin
        cnt_note <= cnt_note + 1'b1;
    end
    else begin
        cnt_note <= cnt_note;
    end
end

//所有音符结束标志 end_flag
assign end_flag = cnt_note == NOTE_NUM && cnt_delay == cnt_delay_r;

//单个音符振动周期 cnt_freq
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        cnt_freq <= 19'd1;
    end
    else if(end_note)begin
        cnt_freq <= 19'd1;
    end
    else begin
        cnt_freq <= cnt_freq + 1'b1;
    end
end

//单个音符结束标志 end_note
assign end_note = (cnt_freq == freq_data);

//音符数据选择 freq_data 
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        freq_data <= MAX_DO;
    end
    else begin
        case(cnt_note)
            6'd0:begin
                freq_data <= MID_DO;
                cnt_delay_r <= TIME_300ms;
            end
            6'd1:begin
                freq_data <= MID_RE;
                cnt_delay_r <= TIME_300ms;
            end
            6'd2:begin
                freq_data <= MID_MI;
                cnt_delay_r <= TIME_300ms;
            end
            6'd3:begin
                freq_data <= MID_DO;
                cnt_delay_r <= TIME_300ms;
            end
            6'd4:begin
                freq_data <= MID_DO;
                cnt_delay_r <= TIME_300ms;
            end
            6'd5:begin
                freq_data <= MID_RE;
                cnt_delay_r <= TIME_300ms;
            end
            6'd6:begin
                freq_data <= MID_MI;
                cnt_delay_r <= TIME_300ms;
            end
            6'd7:begin
                freq_data <= MID_DO;
                cnt_delay_r <= TIME_300ms;
            end
            6'd8:begin
                freq_data <= MID_MI;
                cnt_delay_r <= TIME_300ms;
            end
            6'd9:begin
                freq_data <= MID_FA;
                cnt_delay_r <= TIME_300ms;
            end
            6'd10:begin
                freq_data <= MID_SO;
                cnt_delay_r <= TIME_500ms;
            end
            6'd11:begin
                freq_data <= MID_MI;
                cnt_delay_r <= TIME_300ms;
            end
            6'd12:begin
                freq_data <= MID_FA;
                cnt_delay_r <= TIME_300ms;
            end
            6'd13:begin
                freq_data <= MID_SO;
                cnt_delay_r <= TIME_500ms;
            end
            6'd14:begin
                freq_data <= MID_SO;
                cnt_delay_r <= TIME_300ms;
            end
            6'd15:begin
                freq_data <= MID_LA;
                cnt_delay_r <= TIME_300ms;
            end
            6'd16:begin
                freq_data <= MID_SO;
                cnt_delay_r <= TIME_300ms;
            end
            6'd17:begin
                freq_data <= MID_FA;
                cnt_delay_r <= TIME_500ms;
            end
            6'd18:begin
                freq_data <= MID_MI;
                cnt_delay_r <= TIME_500ms;
            end
            6'd19:begin
                freq_data <= MID_DO;
                cnt_delay_r <= TIME_300ms;
            end
            6'd20:begin
                freq_data <= MID_SO;
                cnt_delay_r <= TIME_300ms;
            end
            6'd21:begin
                freq_data <= MID_LA;
                cnt_delay_r <= TIME_300ms;
            end
            6'd22:begin
                freq_data <= MID_SO;
                cnt_delay_r <= TIME_300ms;
            end
            6'd23:begin
                freq_data <= MID_FA;
                cnt_delay_r <= TIME_500ms;
            end
            6'd24:begin
                freq_data <= MID_MI;
                cnt_delay_r <= TIME_500ms;
            end
            6'd25:begin
                freq_data <= MID_DO;
                cnt_delay_r <= TIME_300ms;
            end
            6'd26:begin
                freq_data <= MID_RE;
                cnt_delay_r <= TIME_500ms;
            end
            6'd27:begin
                freq_data <= MID_SO;
                cnt_delay_r <= TIME_500ms;
            end
            6'd28:begin
                freq_data <= MID_DO;
                cnt_delay_r <= TIME_500ms;
            end
            6'd29:begin
                freq_data <= 1'b0;
                cnt_delay_r <= TIME_500ms;
            end
            6'd30:begin
                freq_data <= MID_RE;
                cnt_delay_r <= TIME_500ms;
            end
            6'd31:begin
                freq_data <= MID_SO;
                cnt_delay_r <= TIME_500ms;
            end
            6'd32:begin
                freq_data <= MID_DO;
                cnt_delay_r <= TIME_500ms;
            end
            6'd33:begin
                freq_data <= 1'b0;
                cnt_delay_r <= TIME_500ms;
            end
            default:begin
                freq_data <= MID_DO;
                cnt_delay_r <= TIME_300ms;
            end
        endcase
    end
end

//占空比 duty_data 
assign duty_data = freq_data >> 3;//移位越多,占空比越高

// flag
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        flag <= 1'b0;
    end
    else begin
        flag <= (cnt_freq >= duty_data) ? 1'b1 : 1'b0;
    end
end

//输出 beep 
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        beep <= 1'b0;
    end
    else if(flag)begin
        beep <= 1'b1;
    end
    else begin
        beep <= 1'b0;
    end
end


endmodule

总结

        这个原理还是挺简单的,如果感兴趣的话还可以尝试这去写更复杂的音乐,但是这个蜂鸣器的声音真正不是很友好,如果能加一个音频转换器效果应该会好很多。文章来源地址https://www.toymoban.com/news/detail-502444.html

到了这里,关于【FPGA】五、蜂鸣器播放音乐的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 使用单片机控制蜂鸣器播放音乐的代码

    在嵌入式系统中,单片机常常被用于控制各种外设,其中包括蜂鸣器。蜂鸣器是一种能够发出声音的电子元件,可以通过单片机的控制来播放各种音乐或声效。本文将介绍如何使用单片机控制蜂鸣器播放音乐,并提供相应的源代码。 在开始编写代码之前,我们首先需要确定使

    2024年02月01日
    浏览(39)
  • MCU-51:单片机蜂鸣器播放音乐和提示音

    蜂鸣器是一种将电信号转换为声音信号的器件,常用来产生设备的按键音、报警音等提示信号 蜂鸣器按驱动方式可分为有源蜂鸣器和无源蜂鸣器 有源蜂鸣器:内部自带振荡源,将正负极接上直流电压即可持续发声,频率固定 无源蜂鸣器:内部不带振荡源,需要控制器提供振

    2024年02月02日
    浏览(48)
  • 开源小项目 - 基于无源蜂鸣器实现的音乐播放器

    目录 一、音乐简谱相关知识 1、音符 2、音调 3、识读简谱 1. 找到简谱中C调的音符对应的蜂鸣器频率(确定音调对应的频率) 2. 确定蜂鸣器演奏一拍所需的时间(即确定一个音调对应的节拍数) 3.创建结构体确定一个音符所需的两个属性(音调频率、节拍数) 4.将《两只老虎

    2024年03月10日
    浏览(53)
  • 《FPGA学习》->蜂鸣器播放

    🍎 与其担心未来,不如现在好好努力。在这条路上,只有奋斗才能给你安全感。你若努力,全世界都会为你让路。 蜂鸣器的发声原理由振动装置和谐振装置组成,而蜂鸣器又分为无源他激型与有源自激型。本实验采用无源蜂鸣器,蜂鸣器的发声不同是靠频率不同进行控制的

    2024年02月08日
    浏览(46)
  • 音乐播放器蜂鸣器ROM存储歌曲verilog,代码/视频

    名称:音乐播放器蜂鸣器ROM存储歌曲 软件:Quartus 语言:Verilog 代码功能:        设计音乐播放器,要求至少包含2首歌曲,使用按键切换歌曲,使用开发板的蜂鸣器播放音乐,使用Quartus内的ROM IP核存储音乐文件, 简谱存储在ROM中,共2首歌曲。      《茉莉花》的简谱存

    2024年02月04日
    浏览(54)
  • STM32通过PWM输出使蜂鸣器实现播放音乐功能

    源码下载链接[点击跳转] https://download.csdn.net/download/Coin_Collecter/88641632        PWM ,全称 Pulse Width Modulation ,即脉宽调制技术,是一种通过改变信号的占空比来控制电路的技术。在 PWM 信号中,周期是固定的,而占空比则可以根据需要进行调整。通过改变占空比,可以控制电路

    2024年02月02日
    浏览(54)
  • STM32-PWM驱动无源蜂鸣器播放音乐(附网盘代码)

    一、工作原理: 1.利用STM32的定时器PWM输出通道,驱动蜂鸣器以特定频率发声,实现播放音乐的效果。 2.C调音符与频率对照表: 3.以下为常用的七声音阶频率(Hz): #define  MC         262    Do #define  MD         294    Re #define  ME         330     Mi #define  MF   

    2024年02月07日
    浏览(51)
  • 基于STM32制作的音乐播放器,用PWM控制蜂鸣器

    目录 效果展示  前言         一、设计背景         1.1、知识储备          二、系统设计方案         2.1、实现功能          2.2、硬件部分         2.3、软件部分          三、软件设计          3.1、设计流程图          3.2、音乐频率的设置          3.3、编

    2024年02月03日
    浏览(76)
  • 基于RT-Thread+STM32F407的蜂鸣器音乐播放器

    本项目为RT-Thread学习项目,参考于RT-Thread官网Demo示例 硬件基于STM32F407ZGT6正点原子探索者开发板+无源蜂鸣器模块 RTOS软件基于RT-Thread 4.0.5版本 编译器为官方的提供的RT-Thread Studio 会使用到STM32CubeMX 配置产生PWM波 会使用MobaXterm串口终端软件查看串口终端数据 官网Demo示例网址:

    2024年02月02日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包