《FPGA学习》->蜂鸣器播放

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

🍎 与其担心未来,不如现在好好努力。在这条路上,只有奋斗才能给你安全感。你若努力,全世界都会为你让路。

蜂鸣器的发声原理由振动装置和谐振装置组成,而蜂鸣器又分为无源他激型与有源自激型。本实验采用无源蜂鸣器,蜂鸣器的发声不同是靠频率不同进行控制的,音调的大小是靠占空比也决定的。

下面附上蜂鸣器的电路图:

《FPGA学习》->蜂鸣器播放

由蜂鸣器电路图可以看出,蜂鸣器打开需要BEEP端口为高电平,关闭则是让BEEP端口为低电平。

清楚了蜂鸣器控制方式以后,我们再来看一下如何让蜂鸣器发出“哆来咪发索拉西“的声音。

《FPGA学习》->蜂鸣器播放

上图是蜂鸣器发出不同声音的一个频率表。由频率可以得到具体的计数周期,开发板的晶振频率为50MHz,那低音1的计数周期就应该为:《FPGA学习》->蜂鸣器播放,我们可以定义一个音的时间周期为500ms,当计数到190839的一半时,把蜂鸣器打开,当计数到190839时,把蜂鸣器关闭,下一个计数从0重新计数。这样它就能发出低音1的音,也就是"哆"音,同时它的一个占空比就是50%。发出第一个音后,我们可以在第二个500ms让蜂鸣器发出低音2,也就是"来"音,以此类推,我们只定义低音1~低音7总共7个音,定义一个3位宽的数就可以把它们都罗列出来。下面是这次任务的一个波形图。

《FPGA学习》->蜂鸣器播放

参照波形图,我们对任务进行代码编写:

module beep          //模块开始,定义名称为beep
#(
    parameter CNT_MAX  = 25'd24_999_999 ,    //定义全局变量CNT_MAX,时间周期为500ms
    parameter DO       = 18'd190839     ,    //定义全局变量DO,计数值为190839,发“哆”音
    parameter RE       = 18'd170067     ,    //定义全局变量RE,计数值为170067,发“来”音
    parameter MI       = 18'd151514     ,    //定义全局变量MI,计数值为151514,发“咪”音
    parameter FA       = 18'd143265     ,    //定义全局变量FA,计数值为143265,发“发”音
    parameter SO       = 18'd127550     ,    //定义全局变量SO,计数值为127550,发“嗦”音
    parameter LA       = 18'd113635     ,    //定义全局变量LA,计数值为113635,发“拉”音
    parameter XI       = 18'd101214          //定义全局变量XI,计数值为101214,发“西”音
)
(
    input    wire    sys_clk   ,     //定义sys_clk为输入模式   (时钟)
    input    wire    sys_rst_n ,     //定义sys_rst_n为输入模式 (复位)
    
    output    reg        beep_out          //定义beep_out为寄存器类型的输出模式
);

    reg     [24:0]    cnt ;            //定义cnt为25位宽的寄存器类型
    reg     [17:0]    freq_cnt;        //定义freq_cnt为18位宽的寄存器类型
    reg     [2:0]   cnt_500ms;        //定义cnt_500ms为3位宽的寄存器类型
    
    reg     [17:0]    freq_data;        //定义freq_data为18位宽的寄存器类型

always@(posedge sys_clk or negedge sys_rst_n)
    begin
        if(sys_rst_n == 1'b0)        //复位信号到来     
            begin
                cnt <= 25'd0;        //使cnt清0    
            end
        else    if(cnt == CNT_MAX)   //判断cnt是否计数到最大值   
            begin
                cnt <= 25'd0;        //使cnt清0         
            end
        else 
            cnt <= cnt+ 25'd1;         //使cnt + 1        
    end
    
always@(posedge sys_clk or negedge sys_rst_n)
    begin
        if(sys_rst_n == 1'b0)        //复位信号到来               
            begin
                cnt_500ms <= 3'd0;        //使cnt_500ms清0          
            end
        else    if(cnt_500ms == 3'd6&&cnt == CNT_MAX)   //判断cnt_500ms是否计数到3'd6   
            begin
                cnt_500ms <= 3'd0;        //使cnt_500ms清0       
            end
        else    if(cnt == CNT_MAX)   //判断cnt是否计数到最大值    
            begin
                cnt_500ms <= cnt_500ms+ 3'd1;   //使cnt_500ms + 1           
            end
        else 
            cnt_500ms <= cnt_500ms;      //使cnt_500ms保持不变  
    end

always@(posedge sys_clk or negedge sys_rst_n)
    begin
        if(sys_rst_n == 1'b0)        //复位信号到来                
            begin
                freq_data <= DO;    //把DO的值赋给freq_data
            end
        else case(cnt_500ms)
            3'd0:freq_data <= DO ;        //把DO的值赋给freq_data
            3'd1:freq_data <= RE ;      //把RE的值赋给freq_data
            3'd2:freq_data <= MI ;      //把MI的值赋给freq_data
            3'd3:freq_data <= FA ;      //把FA的值赋给freq_data
            3'd4:freq_data <= SO ;      //把SO的值赋给freq_data
            3'd5:freq_data <= LA ;      //把LA的值赋给freq_data
            3'd6:freq_data <= XI ;      //把XI的值赋给freq_data
            default:freq_data <= DO ;   //把DO的值赋给freq_data
            endcase    
    end 
        
always@(posedge sys_clk or negedge sys_rst_n)
    begin
        if(sys_rst_n == 1'b0)        //复位信号到来                
            begin
                freq_cnt <= 18'd0;        //使freq_cnt清0          
            end    
        else     if((freq_cnt == freq_data)||(cnt == CNT_MAX))  //判断freq_cnt是否计数到freq_data或者cnt计数到最大值
            begin
                freq_cnt <= 18'd0;        //使freq_cnt清0           
            end
        else 
            freq_cnt <= freq_cnt+ 18'd1;  //使freq_cnt + 1 
    end
    
always@(posedge sys_clk or negedge sys_rst_n)
    begin
        if(sys_rst_n == 1'b0)       //复位信号到来                
            begin
                beep_out <= 1'b0;           //使beep_out清0          
            end
        else     if(freq_cnt >= freq_data/2)  //判断freq_cnt是否计数到freq_data的一半
            begin
                beep_out <= 1'b1;         //使beep_out置1          
            end 
        else 
            begin
                beep_out <= 1'b0;         //使beep_out清0          
            end 
    end
    
endmodule     //模块结束

下面是仿真的波形:

《FPGA学习》->蜂鸣器播放
《FPGA学习》->蜂鸣器播放

从图中可以看出cnt_500ms的值是从0计数到6,再次计数会变为0,刚好对应7个音,符合我们要求。

《FPGA学习》->蜂鸣器播放
《FPGA学习》->蜂鸣器播放

freq_data中的数据对应不同音调的计数周期,因为数值太大,所以在编写仿真文件时,这里把数值改小了,方便查看波形。

《FPGA学习》->蜂鸣器播放
《FPGA学习》->蜂鸣器播放
《FPGA学习》->蜂鸣器播放

cnt的值仿真文件里设置的数为100,这里计数到100会从0开始,与任务波形图符合。

《FPGA学习》->蜂鸣器播放

下面是仿真代码:

`timescale 1ns/1ns        //时间尺度预编译指令      时间单位/时间精度
                          
module tb_beep();         //定义模块名称为tb_beep
                          
reg     sys_clk;          //定义sys_clk为reg型
reg     sys_rst_n;        //定义sys_rst_n为reg型
wire    beep_out;         //定义beep_out为reg型

initial                          //初始化
    begin                        
        sys_clk   = 1'b1  ;      //使sys_clk初始化为高电平状态
        sys_rst_n = 1'b0  ;      //使sys_clk初始化为低电平状态
        #20                      //延时20ns
        sys_rst_n = 1'b1  ;      //使sys_rst_n电平拉高
    end                          
                                 
always #10 sys_clk = ~sys_clk;   //使sys_clk电平10ns电平状态反转一次

beep                             //例化对象名称
#(
    .CNT_MAX(25'd100)    ,       //改变parameter定义的参数
    .DO     (18'd19)     ,
    .RE     (18'd17)     ,
    .MI     (18'd15)     ,
    .FA     (18'd14)     ,
    .SO     (18'd12)     ,
    .LA     (18'd11)     ,
    .XI     (18'd10)    
)
beep_inst                        //实例化名称
(                                
    .sys_clk      (sys_clk  ),      //使sys_clk信号端口例化为sys_clk
    .sys_rst_n    (sys_rst_n),   //使sys_rst_n信号端口例化为sys_rst_n
                                 
    .beep_out     (beep_out )    //使beep_out信号端口例化为beep_out
);

endmodule     //模块结束    

🔥🔥🔥本系列文章持续更新,喜欢的话可以关注收藏~🔥🔥🔥文章来源地址https://www.toymoban.com/news/detail-476008.html

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

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

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

相关文章

  • 蜂鸣器播放《两只老虎》

      通过往期的按键控制蜂鸣器课程,我们了解了蜂鸣器器件,本次课程将使用蜂鸣器,播放我小时候经常听的《两只老虎》音乐,来勾起我童年的回忆。   我们回顾一下蜂鸣器的知识: 按照工作原理可分为:压电式蜂鸣器和电磁式蜂鸣器。 按照音源可分为:有源蜂鸣器

    2023年04月08日
    浏览(58)
  • STM32 蜂鸣器介绍 配置 播放音节

             蜂鸣器一般被分为两类 : 有源蜂鸣器 和 无源蜂鸣器 。 其中源是振荡源 。 有源蜂鸣器内部有振荡电路,可以把直流电源转换为一定频率的脉冲信号。 因为它一直输出一定的频率,我们无法改变频率,所以声音只有一种,我们只能通过电源,控制它发不发声。

    2024年02月04日
    浏览(39)
  • STM32蜂鸣器播放音乐(代码全)

    在STM32F103ZET6板子上使用蜂鸣器播放音乐,我们可以将其分为几个模块:初始化模块、蜂鸣器控制模块、音乐播放模块和主函数模块。以下是一个简单的示例代码,使用STM32 HAL库和定时器来驱动蜂鸣器播放音乐。 首先,确保你已经配置了STM32CubeMX或STM32CubeIDE,并生成了HAL库代码

    2024年04月25日
    浏览(39)
  • fpga开发——蜂鸣器

    有源蜂鸣器和无源蜂鸣器          无源蜂鸣器利用电磁感应现象,为音圈接入交变电流后形成的电磁铁与永磁铁相吸或相斥而推动振膜发声,接入直流电只能持续推动振膜而无法产生声音,只能在接通或断开时产生声音。无源蜂鸣器的工作原理与扬声器相同。在使用方波

    2024年02月14日
    浏览(37)
  • 使用单片机控制蜂鸣器播放音乐的代码

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

    2024年02月01日
    浏览(35)
  • 二、17【FPGA】无源蜂鸣器驱动实验

    学习说明此文档为本人的学习笔记,注重实践,关于理论部分会给出相应的学习链接。 学习视频:是根据野火FPGA视频教程——第二十讲 https://www.bilibili.com/video/BV1nQ4y1Z7zN?p=3      蜂鸣器按其结构可分为电磁式蜂鸣器和压电式蜂鸣器两种类型。 压电式蜂鸣器是以压电陶瓷的压

    2023年04月25日
    浏览(42)
  • 开源小项目 - 基于无源蜂鸣器实现的音乐播放器

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

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

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

    2024年02月02日
    浏览(45)
  • fpga开发--蜂鸣器发出连续不同的音调

    使用fpga蜂鸣器连续发出do,re,mi,fa,so,la,xi七个不同的音调,每个音调的持续时间为0.5s。 采用状态机实现音调的转化,当do状态持续了0.5s之后转移到re状态,以此类推...采用0.5s的时间flag信号控制状态机的转变。因为不同的音调有不同的频率,所以在每个时钟周期内需要

    2024年02月15日
    浏览(37)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包