文章目录

  • 前言
  • 一、回顾蜂鸣器
  • 二、乐谱知识
    • 2.1 音符音频
    • 2.2 两只老虎乐谱
  • 三、系统框图
  • 四、模块调用
  • 五、模块原理图
  • 六、工程源码
    • 6.1 音符选择模块代码
    • 6.2 pwm产生模块代码
    • 6.3 顶层模块代码
  • 七、仿真测试
    • 7.1 测试代码
    • 7.2 仿真结果
  • 八、管脚信息
  • 九、运行效果
  • 总结

前言

  通过往期的按键控制蜂鸣器课程,我们了解了蜂鸣器器件,本次课程将使用蜂鸣器,播放我小时候经常听的《两只老虎》音乐,来勾起我童年的回忆。


一、回顾蜂鸣器

  我们回顾一下蜂鸣器的知识:

  1. 按照工作原理可分为:压电式蜂鸣器和电磁式蜂鸣器。
  2. 按照音源可分为:有源蜂鸣器和无源蜂鸣器。
  3. 有源蜂鸣器:内部有振荡源,直接通以直流电即可发出声音。
  4. 无源蜂鸣器:内部无振荡源,需要通以方波、PWM信号才能发出声音。

图1. 蜂鸣器原理图

  无源蜂鸣器需要输入一定频率的方波或者脉冲宽度调制(Pulse Width Modulation,PWM)信号,蜂鸣器就可以发出声音。输入不同频率的信号,蜂鸣器可以发出不同音色的声音。《红楼梦》中“未见其人先闻其声”指的是王熙凤,就是因为每个人发出的声音频率不同,所以音色也会不同,我们可以通过音色就知道谁是谁。


二、乐谱知识

2.1 音符音频

  音频(Audio),指人耳可以听到的声音频率在20HZ~20kHz之间的声波。乐普是由音符组成的,不同的音符拥有不同的频率。音频和周期的关系如下公式所示。
T(周期)=1f(频率)(1)T(周期) = \frac{1}{f(频率)}\tag1T()=f()1(1)

表1. 音频表

  我们可以根据表中音符频率用公式(1)计算出音符振动的周期,单位微秒。Cyclone IV开发板的晶振是50MHz,振动一次是20纳秒,使用周期时间除以20纳秒得出音符振动的次数。比如高音的DO计算方式如下公式(2)所示。

DO(高)=955×10320=47750(2)DO(高) = \frac{955\times10^3}{20}\tag2=47750DO()=20955×103=47750(2)

2.2 两只老虎乐谱

  两只老虎乐谱一共有34个音符,1对应DO,2对应RE,3对应MI…。一个音符持续的时间很短,需要设置一个持续时间,重复播放该音符,这样我们才能听得出来。本实验中设置音符持续时间(节拍)300毫秒,要想使两只老虎听起来更完美,同学们下去得学习乐谱中节拍知识,根据乐谱中节拍设置音符的持续时间。

图2. 两只老虎乐谱

三、系统框图

图3. 系统框图

四、模块调用

图4. 模块关系示意图

五、模块原理图

图5. 模块原理图

六、工程源码

6.1 音符选择模块代码

module freq_select
(input  wire     clk  ,//时钟信号input  wire   rst_n,//复位信号output reg        flag//pwm标志);
parameter   CNT_MAX = 24'd14_999_999;//300ms
parameter   NUM_FRE = 6'd33           ;//34个音符
parameter   DO      = 16'd47750       ;//1
parameter   RE      = 16'd42250       ;//2
parameter   MI      = 16'd37900       ;//3
parameter   FA      = 16'd37550       ;//4
parameter   SO      = 16'd31850       ;//5
parameter   LA      = 16'd28400       ;//6
parameter   XI      = 16'd25400       ;//7
reg  [23:0]  cnt_delay   ;//300ms计数器
reg  [5:0]     lut_data    ;//乐谱数据寄存器
reg  [15:0]    cnt_freq    ;//音符音频计数器
reg  [15:0]    freq_data   ;//音符数据寄存器
wire [14:0]  duty_data   ;//占空比数据
wire         end_note    ;//音符结束标志
wire         end_spectrum;//音谱结束标志
//单个音符持续时间计时模块
always@(posedge clk or negedge rst_n)beginif(!rst_n)begincnt_delay <= 24'd0;end else if(cnt_delay == CNT_MAX)begincnt_delay <= 24'd0;end else begincnt_delay <= cnt_delay + 1'd1;end
end //音符计时模块
always@(posedge clk or negedge rst_n)beginif(!rst_n)begincnt_freq <= 16'd0;end else if(end_note)begincnt_freq <= 16'd0;end else begincnt_freq <= cnt_freq + 1'd1;end
end //音谱计时模块
always@(posedge clk or negedge rst_n)beginif(!rst_n)beginlut_data <= 6'd0;end else if(end_spectrum)beginlut_data <= 6'd0;end else if(cnt_delay == CNT_MAX)beginlut_data <= lut_data + 1'd1;end else beginlut_data <= lut_data;end
end //音符查找表模块
always@(posedge clk or negedge rst_n)beginif(!rst_n)beginfreq_data <= DO;end else begincase(lut_data)6'd0:   freq_data <= DO;6'd1:   freq_data <= RE;6'd2:   freq_data <= MI;                      6'd3: freq_data <= DO;                  6'd4: freq_data <= DO;                  6'd5: freq_data <= RE;                  6'd6: freq_data <= MI;                  6'd7: freq_data <= DO;                  6'd8: freq_data <= MI;                  6'd9: freq_data <= FA;                  6'd10:    freq_data <= SO;6'd11:  freq_data <= MI;6'd12:  freq_data <= FA;6'd13:  freq_data <= SO;6'd14:  freq_data <= SO;6'd15:  freq_data <= LA;6'd16:  freq_data <= SO;6'd17:  freq_data <= FA;6'd18:  freq_data <= MI;6'd19:  freq_data <= DO;6'd20:  freq_data <= SO;6'd21:  freq_data <= LA;6'd22:  freq_data <= SO;6'd23:  freq_data <= FA;6'd24:  freq_data <= MI;6'd25:  freq_data <= DO;6'd26:  freq_data <= RE;6'd27:  freq_data <= SO;6'd28:  freq_data <= DO;6'd29:  freq_data <= DO;6'd30:  freq_data <= RE;6'd31:  freq_data <= SO;6'd32:  freq_data <= DO;6'd33:  freq_data <= DO;default:freq_data <= DO;endcase  end
end  assign duty_data = freq_data >> 1;//占空比50%assign end_note = cnt_freq == freq_data;
assign end_spectrum = lut_data == NUM_FRE && cnt_delay == CNT_MAX;
//pwm信号产生模块
always@(posedge clk or negedge rst_n)beginif(!rst_n)beginflag <= 1'b0;end else beginflag <= (cnt_freq >= duty_data) ? 1'b1 : 1'b0; end
end
endmodule

6.2 pwm产生模块代码

module gen_pwm
(input  wire     clk  ,//时钟input  wire     rst_n,//复位信号input  wire   flag ,//pwm标志信号output reg         beep//蜂鸣器信号
);//pwm控制蜂鸣器模块
always@(posedge clk or negedge rst_n)beginif(!rst_n)beginbeep <= 1'b1;end else if(flag)beginbeep <= 1'b0;end     else beginbeep <= 1'b1;end
end
endmodule

6.3 顶层模块代码

module pwm_beep(input  wire clk  ,input  wire rst_n,output wire beep
);parameter   CNT_MAX = 24'd14_999_999;//300ms
parameter   DO      = 16'd47750       ;//1
parameter   RE      = 16'd42250       ;//2
parameter   MI      = 16'd37900       ;//3
parameter   FA      = 16'd37550       ;//4
parameter   SO      = 16'd31850       ;//5
parameter   LA      = 16'd28400       ;//6
parameter   XI      = 16'd25400       ;//7
wire flag;//实例化音频选择模块
freq_select#(
.CNT_MAX     (CNT_MAX),
.DO          (DO)     ,
.RE          (RE)     ,
.MI          (MI)     ,
.FA          (FA)     ,
.SO          (SO)     ,
.LA      (LA)     ,
.XI          (XI)
) u_freq_select(.clk       (clk)  ,
.rst_n       (rst_n),.flag       (flag)
);
//实例化pwm产生模块
gen_pwm u_gen_pwm
(
.clk     (clk)  ,
.rst_n       (rst_n),
.flag        (flag) ,.beep       (beep)
);
endmodule

七、仿真测试

7.1 测试代码

`timescale 1ns/1ns
module pwd_beep_tb();parameter   CNT_MAX = 24'd21;//一个音符持续时间
parameter   DO      = 16'd7;//1
parameter   RE      = 16'd6;//2
parameter   MI      = 16'd5;//3
parameter   FA      = 16'd4;//4
parameter   SO      = 16'd3;//5
parameter   LA      = 16'd2;//6
parameter   XI      = 16'd1;//7
parameter   CYCLE   = 20;
reg     clk  ;
reg     rst_n;
wire    beep ;always #(CYCLE/2) clk = ~clk;initial beginclk   = 1'b0         ;rst_n = 1'b0      ;#(CYCLE)          ;rst_n = 1'b1      ;#(7*CYCLE*CNT_MAX*34);$stop                ;endpwm_beep#(
.CNT_MAX (CNT_MAX),
.DO       (DO)   ,
.RE       (RE)   ,
.MI       (MI)     ,
.FA       (FA)   ,
.SO       (SO)   ,
.LA       (LA)   ,
.XI       (XI)
)    u_pwm_beep(
.clk     (clk)  ,
.rst_n   (rst_n),.beep       (beep)
);
endmodule

7.2 仿真结果

图6. 仿真结果

八、管脚信息

图7. pin planner
元件 管脚
KEY1 E15
KEY2 E16
KEY3 M16
KEY4 M15
CLOCK(时钟) E1
BUZZER(蜂鸣器) J1
表2. 管脚信息表

九、运行效果

蜂鸣器播放两只老虎


总结

  以上就是本期蜂鸣器播放两只老虎的主要内容,通过本次的学习,同学们下去可以使用蜂鸣器播放其他音乐,只要你手里面有乐谱,原理上是可以编写任何音乐。赶紧行动起来,成为一个会写代码的音乐家吧!谢谢你的观看。

蜂鸣器播放《两只老虎》相关推荐

  1. C51蜂鸣器演奏两只老虎

    /*两只老虎**/ #include<reg52.h> sbit Buzz = P1^6; //声明绑定蜂鸣器 unsigned int code NoteFrequ[]={   523, ...

  2. 89C51单片机蜂鸣器演奏两只老虎-源码

    /* ********************************************************************** * 头文件包含 ****************** ...

  3. 用单片机c语言播放两只老虎,两只老虎的C程序的频率和音符??

    满意答案 barryooxx 2013.11.19 采纳率:55%    等级:12 已帮助:8503人 那个程序刚刚给你找了好久才找到,呵呵 HUAN BIT 20H ORG 0000H JMP M ...

  4. FPGA蜂鸣器实现歌曲《两只老虎》

    1.简谱中的符号含义 2.两只老虎简谱 3.音符与频率的对照表 4.首先在这里解释一个名词→音乐频率--众所周知,声音是由物体的振动产生的,本质是传播媒介的振动,另外声音有两大特性--音量和音色,我们 ...

  5. 计算机打音乐两只老虎,两只老虎(音乐、汇编程序)

    /* 程序效果:蜂鸣器发出两只老虎的音律 */ ORG 0000H AJMP START ORG 000BH AJMP TIM0 ORG 0030H START:     MOV TMOD,#01H ...

  6. 用鸿蒙OS在蜂鸣器上播放一曲《两只老虎》

    本文介绍如何在HiSpark Wi-Fi IoT套件上,使用Harmony OS IoT硬件子系统的PWM接口 驱动蜂鸣器 播放音乐. 用PWM输出方波的API 鸿蒙系统IoT硬件子系统提供了PWM相 ...

  7. FPGA实现蜂鸣器播放音乐实验,以儿歌《两只老虎》为例

    ** FPGA实现蜂鸣器播放音乐 ** 实现功能: 开发板上电后,通过蜂鸣器播放<两只老虎>. 设计思路 原理:想要让蜂鸣器播放音乐,就需要知道每个音符的频率,再通过换算将频率转换为周期, ...

  8. 计算机谭音乐两只老虎,Arduino播放音乐《两只老虎》完整代码-测试有效.docx

    Arduino播放音乐<两只老虎>完整代码 [测试有效才发布的] #define C_0 -1 #define C_1 262 #define C_2 294 #define C_3 33 ...

  9. 51单片机两只老虎c语言程序,51单片机两只老虎仿真加代码

    /*************************************************************************** 程序名称:program4-1.c 程序功能: ...

最新文章

  1. JAVA用最简单的方法来构建一个高可用的服务端,提升系统可用性
  2. 高级SmartGWT教程,第2部分
  3. bitcount java_java-Long.bitCount()如何找到设置的位数?
  4. 城市大轰炸(洛谷P1830题题解,Java语言描述)
  5. poj 2031 BuildingaSpaceStation 最小生成树 Prim、Kruskal
  6. 从学校到现在的一个总结
  7. 用Python根据经纬度计算距离
  8. 零信任架构:下一代网络安全架构?
  9. 超赞~免费生成国庆风格微信头像API接口
  10. HBase-14.1-JMX监控实战-hadoop
  11. pboot 将编码转换为实体html_java转换 HTML字符实体,java特殊字符转义字符串
  12. libjpeg的安装与使用
  13. 制作XPE启动光盘的教程
  14. 嵌入式课程---嵌入式Linux的直流电机驱动开发
  15. 一个动画看懂网络原理之CSMA/CD的工作原理
  16. 会议平板Android和Windows系统区别_哪个好?
  17. 博客园——打造不一样的个人博客
  18. vsan超融合基础架构数据丢失的解决过程
  19. Android Studio 搜索快捷键不起作用
  20. 软件测试方法汇总 - 从不同角度分析软件测试方法有哪些

热门文章

  1. 姚振华,一个想要胜天半子的男人
  2. GAE 博客——B3log Solo 0.2.1 发布了!
  3. FCPX插件:Stupid Raisins Block Pop(视频转场插件)
  4. 中国式IT运维,趟出自己的“长期主义”河流
  5. 图像处理中经常用的一幅图片Lena.jpg
  6. 大数据:数据合集,你想要的或许这里都有
  7. 对话ACE第五期:到底什么才是真正的HTAP?
  8. 【单片机毕业设计】【mcuclub-jj-026】基于单片机的垃圾桶的设计
  9. 谈瓦克生产基地爆炸停产对中国多晶硅市场的影响
  10. 机器学习分类器——案例(opencv sklearn svm ann)