【FPGA】五、蜂鸣器播放音乐
文章目录
前言
一、蜂鸣器简介
二、音频音符简介
三、任务要求
四、程序设计
1、设计思路
2、程序代码
总结
前言
蜂鸣器(Buzzer)是现代常用的一种电子发声器,主要用于产生声音信号。它是一种一体化结构的电子讯响器,采用直流电压供电,被广泛用于计算机、报警器、电子玩具、定时器等一些列电子产品中。
一、蜂鸣器简介
蜂鸣器按照其驱动方式不同主要分为有源蜂鸣器和无源蜂鸣器,两者的主要区别为蜂鸣器内部是否还有振荡源。一般有源蜂鸣器内部自带振荡源,通电就会发声,而无源蜂鸣器内部不含振荡源,需要外接振荡信号才能发声。
相较于有源蜂鸣器,无源蜂鸣器的成本较低,而我们FPGA开发板上的蜂鸣器一般都是无源蜂鸣器,需要我们对其进行编程配置,我们利用不同的频率变化,控制蜂鸣器发出不同音调的声音。
二、音频音符简介
我们是通过不同的频率去控制蜂鸣器的音调变化的,所以我们想要使蜂鸣器播放音乐,首先我们要直到不同音符所对应的频率,下面是低、中、高音下不同音符的频率对应表:
根据上图可以计算出不同音符振动的周期,我所采用的Cyclong IV开发板上的晶振时钟为50MHZ,每一个周期就是20ns。那么每个音调的分频系数为:50 000 000 / 音调频率(可四舍五入)。
三、任务要求
本次设计的要求就是利用FPGA开发板上的无源蜂鸣器,通过不同振动频率播放歌曲两只老虎。
四、程序设计
1、设计思路
① 首先我们需要计算出每个不同的音符对应的分频系数,由此产生不同的音调,我们需要设计一个分频计数器,来计数当前发出音调的分频系数。
② 然后我们需要一个节拍计数器,我们定义为半拍300ms,一拍500ms。
③ 利用组合逻辑case语句进行设计,将需要的节拍和要发出的音调写入case语句中。
2、程序代码
/*========================================*filename : beep_music.vdescription : 无源蜂鸣器播放音乐实验time : 2022-11-010 author : 卡夫卡与海
*========================================*/module beep_music(input clk ,//系统时钟 50MHZinput 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)beginif(!rst_n)begincnt_delay <= 25'd0;endelse if(cnt_delay == cnt_delay_r)begincnt_delay <= 25'd0;endelse begincnt_delay <= cnt_delay + 1'b1;end
end//音符计数器 cnt_note
always @(posedge clk or negedge rst_n)beginif(!rst_n)begincnt_note <= 6'd0;endelse if(end_flag)begincnt_note <= 6'd0;endelse if(cnt_delay == cnt_delay_r)begincnt_note <= cnt_note + 1'b1;endelse begincnt_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)beginif(!rst_n)begincnt_freq <= 19'd1;endelse if(end_note)begincnt_freq <= 19'd1;endelse begincnt_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)beginif(!rst_n)beginfreq_data <= MAX_DO;endelse begincase(cnt_note)6'd0:beginfreq_data <= MID_DO;cnt_delay_r <= TIME_300ms;end6'd1:beginfreq_data <= MID_RE;cnt_delay_r <= TIME_300ms;end6'd2:beginfreq_data <= MID_MI;cnt_delay_r <= TIME_300ms;end6'd3:beginfreq_data <= MID_DO;cnt_delay_r <= TIME_300ms;end6'd4:beginfreq_data <= MID_DO;cnt_delay_r <= TIME_300ms;end6'd5:beginfreq_data <= MID_RE;cnt_delay_r <= TIME_300ms;end6'd6:beginfreq_data <= MID_MI;cnt_delay_r <= TIME_300ms;end6'd7:beginfreq_data <= MID_DO;cnt_delay_r <= TIME_300ms;end6'd8:beginfreq_data <= MID_MI;cnt_delay_r <= TIME_300ms;end6'd9:beginfreq_data <= MID_FA;cnt_delay_r <= TIME_300ms;end6'd10:beginfreq_data <= MID_SO;cnt_delay_r <= TIME_500ms;end6'd11:beginfreq_data <= MID_MI;cnt_delay_r <= TIME_300ms;end6'd12:beginfreq_data <= MID_FA;cnt_delay_r <= TIME_300ms;end6'd13:beginfreq_data <= MID_SO;cnt_delay_r <= TIME_500ms;end6'd14:beginfreq_data <= MID_SO;cnt_delay_r <= TIME_300ms;end6'd15:beginfreq_data <= MID_LA;cnt_delay_r <= TIME_300ms;end6'd16:beginfreq_data <= MID_SO;cnt_delay_r <= TIME_300ms;end6'd17:beginfreq_data <= MID_FA;cnt_delay_r <= TIME_500ms;end6'd18:beginfreq_data <= MID_MI;cnt_delay_r <= TIME_500ms;end6'd19:beginfreq_data <= MID_DO;cnt_delay_r <= TIME_300ms;end6'd20:beginfreq_data <= MID_SO;cnt_delay_r <= TIME_300ms;end6'd21:beginfreq_data <= MID_LA;cnt_delay_r <= TIME_300ms;end6'd22:beginfreq_data <= MID_SO;cnt_delay_r <= TIME_300ms;end6'd23:beginfreq_data <= MID_FA;cnt_delay_r <= TIME_500ms;end6'd24:beginfreq_data <= MID_MI;cnt_delay_r <= TIME_500ms;end6'd25:beginfreq_data <= MID_DO;cnt_delay_r <= TIME_300ms;end6'd26:beginfreq_data <= MID_RE;cnt_delay_r <= TIME_500ms;end6'd27:beginfreq_data <= MID_SO;cnt_delay_r <= TIME_500ms;end6'd28:beginfreq_data <= MID_DO;cnt_delay_r <= TIME_500ms;end6'd29:beginfreq_data <= 1'b0;cnt_delay_r <= TIME_500ms;end6'd30:beginfreq_data <= MID_RE;cnt_delay_r <= TIME_500ms;end6'd31:beginfreq_data <= MID_SO;cnt_delay_r <= TIME_500ms;end6'd32:beginfreq_data <= MID_DO;cnt_delay_r <= TIME_500ms;end6'd33:beginfreq_data <= 1'b0;cnt_delay_r <= TIME_500ms;enddefault:beginfreq_data <= MID_DO;cnt_delay_r <= TIME_300ms;endendcaseend
end//占空比 duty_data
assign duty_data = freq_data >> 3;//移位越多,占空比越高// flag
always @(posedge clk or negedge rst_n)beginif(!rst_n)beginflag <= 1'b0;endelse beginflag <= (cnt_freq >= duty_data) ? 1'b1 : 1'b0;end
end//输出 beep
always @(posedge clk or negedge rst_n)beginif(!rst_n)beginbeep <= 1'b0;endelse if(flag)beginbeep <= 1'b1;endelse beginbeep <= 1'b0;end
endendmodule
总结
这个原理还是挺简单的,如果感兴趣的话还可以尝试这去写更复杂的音乐,但是这个蜂鸣器的声音真正不是很友好,如果能加一个音频转换器效果应该会好很多。
【FPGA】五、蜂鸣器播放音乐相关推荐
- FPGA实现蜂鸣器播放音乐实验,以儿歌《两只老虎》为例
** FPGA实现蜂鸣器播放音乐 ** 实现功能: 开发板上电后,通过蜂鸣器播放<两只老虎>. 设计思路 原理:想要让蜂鸣器播放音乐,就需要知道每个音符的频率,再通过换算将频率转换为周期, ...
- FPGA之蜂鸣器播放音乐《花海》
文章目录 前言 一.蜂鸣器 1.蜂鸣器简介: 2.有源蜂鸣器: 3.无源蜂鸣器: 二.简谱常识 1.音符时值: 2.简谱名: 3.简谱名频率: 三.程序设计 1.调用ROM IP核储存每个简谱名所播放 ...
- FPGA蜂鸣器播放音乐
最近做EDA课设,看到自己的买的板子上有蜂鸣器,所以就打算做一个FPGA控制蜂鸣器播放音乐. 这里我使用的板子是睿智助学的FPGA开发板,板子上的芯片是EP4CE6E22C8,如果是你使用的是 ...
- 蜂鸣器播放音乐 fpga实现
目录 原理 实现 原理 蜂鸣器分为有源蜂鸣器和无源蜂鸣器,即以有无震荡源分类, 有震荡源直接通直流电就可发生,无震荡源则需要通震荡波才能发声. 这里介绍无源蜂鸣器播放音乐的方法. 思路: 利用计数器产 ...
- 鸿蒙开发板HI3861 利用蜂鸣器播放音乐 open Harmony1.0.0(附cmsis_os2.h源码)
本文利用鸿蒙开发板HI3861在鸿蒙1.0.0源码下利用蜂鸣器播放音乐. pwm_buz.c #include <stdio.h> #include "ohos_init.h&q ...
- 单片机并行口控制蜂鸣器播放音乐
要用单片机并行口控制蜂鸣器播放音乐,需要完成以下步骤: 设计音乐:需要先确定音乐的节拍和音符,并将其转换为代码中的数值. 设置并行口:需要将单片机的并行口配置为输出模式,以便控制蜂鸣器. 编写代码:需 ...
- MCU-51:单片机蜂鸣器播放音乐和提示音
目录 一.蜂鸣器介绍 二.驱动电路 2.1 三极管驱动 2.2 集成电路驱动 三.蜂鸣器播放音乐 3.1 键盘与音符对照 3.2 音符与频率对照 3.3 简谱 四.代码演示 4.1 按键蜂鸣器播放提示 ...
- 51单片机_11-2 蜂鸣器播放音乐
文章目录 要求 资源 main函数 要求 控制蜂鸣器播放音乐 资源 工程文件压缩包 链接:https://pan.baidu.com/s/1hA-aa0JRP33IlOYFNzKf7A 提取码:0id ...
- Arduino 蜂鸣器播放音乐LED灯闪烁
一.实验所需组件: led灯 三脚蜂鸣器 面包板 Arduino开发板 杜邦线 二.实验原理 蜂鸣器实现音乐播放: 控制好频率和节拍,就能演奏出好听的音乐.因此,在实验之前要先弄清楚各音调的频率.可参 ...
最新文章
- data lab 1(暂时只放题目)
- 随机访问类(RandomAccessFile)
- Luogu P1967 NOIP2013 货车运输
- Algorithm之EM:Expectation Maximization简介、代码实现
- python post form data_python实现发送form-data数据的方法详解
- Python爬虫项目--批量下载联合国粮食数据
- 免堆期由谁申请_谈谈离婚冷静期
- shrio初体验(1)
- ajax前端取消用户发送重复请求
- 紫书 例题 10-14 UVa 12034(组合数+递推)
- jmter测试jmeter参数化(必须掌握)
- Android移动应用基础教程 【程序活动单元Activity】
- java jxls导出excel
- 职等你来 | UE/UX交互设计师(15k);时钟AE工程师;数字IC验证工程师(薪资开放)
- MySQL之数据库基字符集,中文乱码,大小写敏感,Packet for query is too large
- 希沃白板如何解决手机端播放课件内视频出现黑屏闪退
- 【备忘】Mongodb/Redis/HBase NoSql视频教程2017数据库自学教程
- 轨道六根数的含义汇总
- 性能分析到底是不是性能测试工程师的能力?
- 为什么要清除浮动?清除浮动的方式?
热门文章
- 【历史上的今天】7 月 8 日:PostgreSQL 发布;SUSE 收购 K8s 最大服务商;动视暴雪合并
- hdu 5594 ZYB's Prime 最大流
- MATLAB中常用到的符号汇总(持续更新)
- 鸿蒙渊主线任务,天下3易信公众平台
- 并行计算系列-阿姆达尔定律(Amdahl‘s Law)
- 什么是 FOUC(无样式内容闪烁)?你如何来避免 FOUC?
- java csv文件tozip后损坏_java上传并下载以及解压zip文件有时会报文件被损坏错误分析以及解决...
- 牛客寒假算法基础训练营3 G.糖果
- 32位系统的X86到底能支持多大内存
- ASCII码对照表: