蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计算机、打印机、复印机、报警器、电子玩具、汽车电子设备、电话机、定时器等电子产品中作发声器件。

图1 :蜂鸣器实物图

蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。

压电式蜂鸣器 压电式蜂鸣器主要由多谐振荡器、压电蜂鸣片、阻抗匹配器及共鸣箱、外壳等组成。有的压电式蜂鸣器外壳上还装有发光二极管。多谐振荡器由晶体管或集成电路构成。当接通电源后(1.5~15V直流工作电压),多谐振荡器起振,输出1.5~2.5kHZ的音频信号,阻抗匹配器推动压电蜂鸣片发声。

电磁式蜂鸣器电磁式蜂鸣器由振荡器、电磁线圈、磁铁、振动膜片及外壳等组成。接通电源后,振荡器产生的音频信号电流通过电磁线圈,使电磁线圈产生磁场。振动膜片在电磁线圈和磁铁的相互作用下,周期性地振动发声。

按照内部有无震荡源可以分为有源蜂鸣器和无源蜂鸣器。有源蜂鸣器内部带震荡源,所以只要一通电就会发出声音;而无源内部不带震荡源,所以如果用直流信号无法令其鸣叫。必须用一定频率的方波去驱动它。

首先设计分频器,设计一个1KHz的方波,驱动蜂鸣器,观测蜂鸣器是否会有声音产生。

本小节研究如何利用蜂鸣器演唱一首曲子《世上只有妈妈好》。

下图为《世上只有妈妈好》的简谱。

图2:世上只有妈妈好的简谱

简谱是一种比较简单易学的音乐记谱法。据说简谱是由法国思想家卢梭于1742年发明的。而最早把简谱引进我国的是我国近代音乐教育家沈心工。简谱应该说是一种比较简单易学的音乐记谱法。它的最大好处是仅用7个阿拉伯数字----1234567,就能将万千变化的音乐曲子记录并表示出来.

在简谱中,用以表示音的高低及相互关系的基本符号为七个阿拉伯数字,即1、2、3、4、5、6、7,唱作do、re、mi、fa、sol、la、si,称为唱名。

音符:1234567

唱名:do re mi fa sol la si

汉字:哆来米发梭拉西

显然,单用以上七个音是无法表现众多的音乐形象的。在实际作品中,还有一些更高或更低的音,如在基本音符上方加记一个"·",表示该音升高一个八度,称为高音;加记两个" :",则表示该音升高两个八度,称为倍高音。在基本音符下方加记一个"·",表示该音降低一个八度,称为低音;加记两个" :",则表示该音降低两个八度,称为倍低音。

在一般歌曲中,无论是在基本音符上方或下方加记两个以上的"·"的音符都是很少见的。

在简谱中,1、2、3、4、5、6、7这七个基本音符,不仅表示音的高低,而且还是表示时值长短的基本单位,称为四分音符,其他音符均是在四分音符的基础上,用加记短横线"-"和附点"·"表示。

在基本音符右侧加记一条短横线,表示增长一个四分音符的时值。这类加记在音符右侧、使音符时值增长的短横线,称为增时线。增时线越多,音符的时值越长。

在基本音符下方加记一条短横线,表示缩短原音符时值的一半。这类加记在音符下方、使音符时值缩短的短横线,称为减时线。减时线越多,音符的时值越短。

在简谱中,加记在单纯音符的右侧的、使音符时值增长的小圆点"·",称为附点。加记附点的音符称为附点音符。附点本身并无一定的长短,其长短由前面的单纯音符来决定。附点的意义在于增长原音符时值的一半,常用于四分音符和小于四分音符的各种音符之后。

在《世上只有妈妈好》的简谱中,每两个竖线之间为2秒钟的时长。每两个竖线之间有4个音符时长,但是其中有较多半个音符的长,本设计采用1/4秒为基本单位。

蜂鸣器给予不同的频率是可以发出近似1、2、3、4、5、6、7这七个基本音符。

图3 :各个音符所对应的频率

此模块命名为music_beep,clk为50MHz的时钟,rst_n为低电平有效的复位,beep为蜂鸣器的驱动信号。

图4 :music_beep的模型

在设计时,首先将简谱中的音符存起来;利用计数器产生1/4秒为周期的脉冲,在此脉冲驱动下,将事先存好的音符一个个输出;根据音符的值,计算出分频比;根据分频比,产生对应频率的波形。将此波形输出即可。

图5 :架构图

在进行多模块设计时,可以对每个模块只设计端口,将架构完成后。再分别设计每个模块。

《世上只有妈妈好》的简谱中共有8个四拍,每个四拍我们用8个音符来表示,合计共64个音符。在speed_ctrl中,输出的cnt为6位,正好可以表示64个状态。

在speed_ctrl中,每1/8秒让cnt增加1即可。

module
speed_ctrl (

input  
wire            clk,

input  
wire            rst_n,

output 
reg   [5:0]     cnt

);

parameter T_250ms   =   12_500_000;

reg           [25:0]    count;

wire                    flag_250ms;

always @ (posedge clk, negedge rst_n) begin

if (rst_n == 1'b0)

count <= 26'd0;

else

if (count < T_250ms - 1'b1)

count <= count + 1'b1;

else

count <= 26'd0;

end

assign flag_250ms = (count == T_250ms -
1'b1) ? 1'b1 : 1'b0;

always @ (posedge clk, negedge rst_n) begin

if (rst_n == 1'b0)

cnt <= 6'd0;

else

if (flag_250ms == 1'b1)

cnt <= cnt + 1'b1;

else

cnt <= cnt;

end

endmodule

图6:speed_ctrl的设计代码

在music_mem中存储音符,存储方式为低音用1到7表示,中音用8到14表示,高音用15到21表示,music为5bit位宽。

module
music_mem (

input  
wire            clk,

input  
wire            rst_n,

input  
wire    [5:0]   cnt,

output 
reg     [4:0]   music

);

// 1  2 
3  4  5 
6  7

// 8  9  10
11 12 13 14

// 15 16 17 18
19 20 21

always @ (posedge clk, negedge rst_n) begin

if (rst_n == 1'b0)

music <= 5'd0;

else

case (cnt)

6'd0    :  
music <= 5'd13;

6'd1    :  
music <= 5'd13;

6'd2    :  
music <= 5'd13;

6'd3    :  
music <= 5'd12;

6'd4    :  
music <= 5'd10;

6'd5    :  
music <= 5'd10;

6'd6    :  
music <= 5'd12;

6'd7    :  
music <= 5'd12;

6'd8    :  
music <= 5'd15;

6'd9    :  
music <= 5'd15;

6'd10   :  
music <= 5'd13;

6'd11   :  
music <= 5'd12;

6'd12   :  
music <= 5'd13;

6'd13   :  
music <= 5'd13;

6'd14   :  
music <= 5'd13;

6'd15   :  
music <= 5'd13;

6'd16   :  
music <= 5'd10;

6'd17   :  
music <= 5'd10;

6'd18   :  
music <= 5'd12;

6'd19   :  
music <= 5'd13;

6'd20   :  
music <= 5'd12;

6'd21   :  
music <= 5'd12;

6'd22   :  
music <= 5'd10;

6'd23   :  
music <= 5'd10;

6'd24   :  
music <= 5'd8;

6'd25   :  
music <= 5'd6;

6'd26   :  
music <= 5'd12;

6'd27   :  
music <= 5'd10;

6'd28   :  
music <= 5'd9;

6'd29   :  
music <= 5'd9;

6'd30   :  
music <= 5'd9;

6'd31   :  
music <= 5'd9;

6'd32   :  
music <= 5'd9;

6'd33   :  
music <= 5'd9;

6'd34   :  
music <= 5'd9;

6'd35   :  
music <= 5'd10;

6'd36   :  
music <= 5'd12;

6'd37   :  
music <= 5'd12;

6'd38   :  
music <= 5'd13;

6'd39   :  
music <= 5'd13;

6'd40   :  
music <= 5'd10;

6'd41   :  
music <= 5'd10;

6'd42   :  
music <= 5'd10;

6'd43   :  
music <= 5'd9;

6'd44   :  
music <= 5'd8;

6'd45   :  
music <= 5'd8;

6'd46   :  
music <= 5'd8;

6'd47  
:   music <= 5'd8;

6'd48   :  
music <= 5'd12;

6'd49   :  
music <= 5'd12;

6'd50   :  
music <= 5'd12;

6'd51   :  
music <= 5'd10;

6'd52   :  
music <= 5'd9;

6'd53   :  
music <= 5'd8;

6'd54   :  
music <= 5'd6;

6'd55   :  
music <= 5'd8;

6'd56   :  
music <= 5'd5;

6'd57   :  
music <= 5'd5;

6'd58   :  
music <= 5'd5;

6'd59   :  
music <= 5'd5;

6'd60   :  
music <= 5'd5;

6'd61  
:   music <= 5'd5;

6'd62   :  
music <= 5'd5;

6'd63   :  
music <= 5'd5;

default  :  
music <= 5'd0;

endcase

end

endmodule

图7 :music_mem的设计代码

根据频率和音符的关系,将音符对应的频率值取出来,根据频率值算出分频比。驱动时钟为50MHz,所以分频比为50M除以频率。

module
cal_divnum (

input  
wire              clk,

input  
wire              rst_n,

input  
wire    [4:0]     music,

output 
reg     [31:0]    divnum

);

reg             [31:0]    freq;

always @ * begin

case (music)

5'd1   
: freq =    32'd262;

5'd2   
: freq =    32'd294;

5'd3   
: freq =    32'd330;

5'd4   
: freq =    32'd349;

5'd5   
: freq =    32'd392;

5'd6   
: freq =    32'd440;

5'd7   
: freq =    32'd494;

5'd8   
: freq =    32'd523;

5'd9   
: freq =    32'd587;

5'd10  
: freq =    32'd659;

5'd11  
: freq =    32'd699;

5'd12  
: freq =    32'd784;

5'd13  
: freq =    32'd880;

5'd14  
: freq =    32'd988;

5'd15  
: freq =    32'd1050;

5'd16  
: freq =    32'd1175;

5'd17  
: freq =    32'd1319;

5'd18  
: freq =    32'd1397;

5'd19  
: freq =    32'd1568;

5'd20  
: freq =    32'd1760;

5'd21  
: freq =    32'd1976;

default : freq =    32'd1;

endcase

end

always @ (posedge clk, negedge rst_n) begin

if (rst_n == 1'b0)

divnum <= 32'd50_000_000;

else

divnum <= 50_000_000/freq;

end

endmodule

图8 :cal_divmum的设计代码

知道分频数后,利用任意分频的方式,产生对的波形即可。

module
wave_gen (

input  
wire            clk,

input  
wire            rst_n,

input  
wire  [31:0]    divnum,

output 
reg             beep

);

reg           [31:0]    cnt;

always @ (posedge clk, negedge rst_n) begin

if (rst_n == 1'b0)

cnt <= 32'd0;

else

if (cnt < divnum - 1'b1)

cnt <= cnt + 1'b1;

else

cnt <= 32'd0;

end

always @ (posedge clk, negedge rst_n) begin

if (rst_n == 1'b0)

beep <= 1'b0;

else

if (cnt < divnum[31:1])

beep <= 1'b0;

else

beep <= 1'b1;

end

endmodule

图9 :wave_gen的设计代码

设计好上述四个模块后,将它们之前设计架构的连接方式,连接起来。

module
music_beep (

input  
wire              clk,

input  
wire              rst_n,

output 
wire              beep

);

wire          [5:0]       cnt;

wire          [4:0]       music;

wire          [31:0]      divnum;

speed_ctrl speed_ctrl_inst(

.clk                  (clk),

.rst_n                (rst_n),

.cnt                  (cnt)

);

music_mem music_mem_inst(

.clk                  (clk),

.rst_n                (rst_n),

.cnt                  (cnt),

.music                (music)

);

cal_divnum cal_divnum_inst(

.clk                  (clk),

.rst_n                (rst_n),

.music                (music),

.divnum               (divnum)

);

wave_gen wave_gen_inst(

.clk                  (clk),

.rst_n                (rst_n),

.divnum               (divnum),

.beep                 (beep)

);

endmodule

图10 :music_beep的设计代码

RTL视图如下,和所设计架构相同。

图11 :RTL视图

在testbench中,将speed_ctrl_inst模块中的T_250ms改成10。

defparam可以重新定义参数。

`timescale
1ns/1ps

module
music_beep_tb;

reg           clk;

reg           rst_n;

wire          beep;

defparam music_beep_inst.speed_ctrl_inst.T_250ms
= 10;

music_beep music_beep_inst(

.clk        (clk),

.rst_n      (rst_n),

.beep       (beep)

);

initial clk = 1'b0;

always # 10 clk = ~clk;

initial begin

rst_n = 1'b0;

# 200

@ (posedge clk);

# 2;

rst_n = 1'b1;

# 20000;

$stop;

end

endmodule

图12 :testbench代码

由于输出的频率都较低,所以仿真时间都很长。

将参数改小,也只是加快切换输出音符的频率。由于wave_gen模块和分频模块相同,故而不在验证。只看RTL视图中,分频数是不是正确即可。

图13 :RTL视图

在RTL视图中,也看到cnt每10个周期增长1,然后对应输出音符。音符得出频率,根据频率得出分频数。经过验证,数据都是正确的。

分配管脚,全编译形成下载文件,下板后就可以听到《世上只有妈妈好》的歌曲了。

通过更改speed_crtl中的控制音符前进的速度,可以控制播放的速度。如果将速度控制到1/2秒的话,那么听到的歌曲将会变慢。如果将速度控制到1/8秒的话,那么听到的歌曲将会变快。

设计者:郝旭帅         QQ:746833924     QQ交流群: 173560979

基于FPGA的音乐蜂鸣器设计的更多相关文章

  1. 基于FPGA的HDMI显示设计(三)

    上一篇:基于FPGA的VGA显示设计(二) 10月10日 ~ 20日期间实习,令我万万没想到的是实习题目是 “便携式高清电视显示屏测试系统原型设计” 也就是 “基于FPGA的视频显示”. 实习要求用 ...

  2. 基于FPGA的VGA显示设计(二)

    上一篇:基于FPGA的VGA显示设计(一)     参照 CrazyBingo 的 基于FPGA的VGA可移植模块终极设计代码  的工程代码风格,模块化处理了上一篇的代码,并增加了一点其它图形. 顶层 ...

  3. 基于FPGA的异步FIFO设计

    今天要介绍的异步FIFO,可以有不同的读写时钟,即不同的时钟域.由于异步FIFO没有外部地址端口,因此内部采用读写指针并顺序读写,即先写进FIFO的数据先读取(简称先进先出).这里的读写指针是异步的, ...

  4. 基于FPGA的VGA显示设计(一)

    前言 FPGA主要运用于芯片验证.通信.图像处理.显示VGA接口的显示器是最基本的要求了. 原理 首先需要了解 : (1)VGA接口协议:VGA端子_维基百科 .VGA视频传输标准_百度 引脚1 RE ...

  5. 优化基于FPGA的深度卷积神经网络的加速器设计

    英文论文链接:http://cadlab.cs.ucla.edu/~cong/slides/fpga2015_chen.pdf 翻译:卜居 转载请注明出处:http://blog.csdn.net/k ...

  6. 基于FPGA的图像去噪

    目录 结构图 其中FPGA 控制模块为核心,通过它实现视频图像数据的获取.缓存.处理和控制各模块间通讯[1].由CCD 相机对目标成像,高速图像数据由camera link 实时传输[2],经信号转换 ...

  7. 基于FPGA的DDS设计(一)

    最近在学习基于FPGA的DDS设计,借此机会把学习过程记录下来,当作自己的学习笔记也希望能够帮助到学习DDS的小伙伴. DDS(Direct Digital Synthesizer)直接数字合成器,这 ...

  8. 基于FPGA的XPT2046触摸控制器设计

    基于FPGA的XPT2046触摸控制器设计 小梅哥编写,未经许可,文章内容和所涉及代码不得用于其他商业销售的板卡 本实例所涉及代码均可通过向 xiaomeige_fpga@foxmail.com  发 ...

  9. 基于FPGA的VGA可移植模块终极设计【转】

    本文转载自:http://www.cnblogs.com/lueguo/p/3373643.html 略过天涯   基于FPGA的VGA可移植模块终极设计 一.VGA的诱惑 首先,VGA的驱动,这事, ...

  10. 基于FPGA的SPI FLASH控制器设计

    1.SPI FLASH的基本特征 本文实现用FPGA来设计SPI FLASH,FLASH型号为W25Q128BV.支持3种通信方式,SPI.Dual SPI和Quad SPI.FLASH的存储单元无法 ...

随机推荐

  1. 优化Mysql配置调整内存

    1.查看Mysql版本 # mysql -V 示例: [root@root /]# mysql -V mysql Ver 14.14 Distrib 5.7.44, for Linux (x86_64 ...

  2. 大模型落地实战指南:从选择到训练,深度解析显卡选型、模型训练技、模型选择巧及AI未来展望—打造AI应用新篇章

    大模型落地实战指南:从选择到训练,深度解析显卡选型.模型训练技.模型选择巧及AI未来展望---打造AI应用新篇章 0.前言大模型发展史 早期阶段(1950s~1980s) 在1950年代初期,人们开始 ...

  3. 正则表达式 vs. 字符串处理:解析优势与劣势

    1. 正则表达式起源与演变 正则表达式(Regular Expression)最早由美国数学家斯蒂芬·科尔内基(Stephen Kleene)于1956年提出,用于描述字符串的模式匹配规则.随后在计算 ...

  4. 在ubuntu安装QT

    在ubuntu安装 安装motrix motrix下载 下载对应版本的QT QT下载 授权run文件 sudo chmod +x xxx.run 运行run文件 ./ xxx.run 运行界面 安装完 ...

  5. 基于rk3588----i2c驱动框架学习(2)-总线驱动 algorithm 分析

    rk3588 i2c algorithm 分析 来了来了,上次分析完i2c的驱动框架 今天我们就看看i2c的algorithm是如何实现的 static const struct i2c_algori ...

  6. CentOS 7 上搭建nginx来部署静态网页

    目录 0. Nginx简介 1. 安装以及使用 1.1 安装和启动 1.2 配置服务器的访问地址 1.3 重启nginx,打开浏览器访问 0. Nginx简介 Nginx (engine x) 是一个 ...

  7. 2022福州大学MEM复试英语口语准备

    一.自我介绍 Dear professors, it's my honor to be here for my interview. My name is ,I finished my undergr ...

  8. #树链剖分,线段树#洛谷 2486 [SDOI2011]染色

    题目 分析 就是把维护颜色段和树结合起来, 注意拼接的时候要减去中间相同的部分 代码 #include <cstdio> #include <cctype> #include ...

  9. 4. Orthogonality

    4.1 Orthogonal Vectors and Suspaces Orthogonal vectors have \(v^Tw=0\),and \(||v||^2 + ||w||^2 = ||v ...

  10. windows创建bat文件进行截图

    1.创建 bat 文件 2.编辑文件内容 start snippingtool