基于小脚丫FPGA设计电子琴
基于2022暑假一起练活动平台,使用小脚丫FPGA核心板,与piano kit扩展板设计了一款能够进行音乐演奏和扬声器播放音乐的电子琴。
标签
FPGA
数字逻辑
DDS
2022暑假在家练
doctor雷
更新2022-09-02
湖北理工学院
961

1.电子琴工作原理与框图

电子琴上有两个发声装置,一个为蜂鸣器,一个为扬声器,其中蜂鸣器发声靠的是引脚产生一个方波信号驱动,改变方波的频率,就能实现蜂鸣器发对应频率的音符。 而扬声器的驱动是由DDS产生的模拟信号,经PWM调制,再经过rc滤波,最后通过运放电路输出到扬声器上。同理改变DDS产生的模拟信号频率,来实现不同的音符播放。可以通过FPGA上按键来实现电子琴的演奏和音乐播放模式。 音乐播放模式工作原理,通过对乐曲简谱进行转化,存储相应的代码,输出乐曲对应的音符,音符输入到例化好的模块。同时可以通过上下音程按键进行上下曲切换。在演奏模式,可以通过电子琴地板上的两个上下音程调节按键实现对音程的调节,其中在数码管上会显示对应的音程挡位,其中“0”为不发声,“1”档对应的频率范围为130.81~261.63即C3到C4这13个音符,“2”档对应C4到C5这13个音符,“4”档对应C5到C6这13个音符。目前就添加了扬声器演奏模式下,这3档音程。同时通过板子上的拨钮开关可以在任何时刻改变声音的输出方式(扬声器与蜂鸣器)。

FvoQETHleN0UEqggV5CROq_zt30x

test为顶层文件,输入小脚丫开发板的系统时钟C1(12MHz),系统复位引脚定义为L14,加电子琴的13个按键,以及切换拨钮N4,加上两个“上下”按键以及演奏模式与音乐播放模式切换按键。

输出有电子琴蜂鸣器buzzer:P8,电子琴扬声器speaker:N8,以及小脚丫fpga板上8个led与两个rgbLED,两个数码管

以下是部分子模块:

FtncDJUZ_7Svlkw4wPzNobPhOewz

Buzzer为蜂鸣器发声文件,输入小脚丫开发板的系统时钟C1,系统复位引脚定义为L14,通过电子琴的按键产生对应的pwm波驱动蜂鸣器发声。

输出有电子琴蜂鸣器buzzer:P8,以及通过按键状态输出buzzer。

FnirrY_d9Qroayl5RenY38kYd-Ys

dds为扬声器发声文件,输入小脚丫开发板的系统时钟C1,系统复位引脚定义为L14,以及输入对应音符的参数,则通过电子琴的按键产生对应的正弦波驱动扬声器发声。

输出有电子琴蜂鸣器speaker:N8,输出是通过pwm调制输出,

FpL0U2yKZvyX3p6C4PtnRxd1XSvt

从图可以看出,改变占空比就可以改变电压值,一个占空比对应为一个模拟电压值,用PWM的方式实现数字到模拟变换的功能。

这个为DDS的仿真图,频率在130HZ,根据输出的PWM占空比不同,如两个图,

FtWReV8SjL-D9nhdGkwCWL6jelqh

Fk848LNzObaytjUgrovnR8h7D61o

播放音乐模式存放了如下歌曲,通过对应的简谱,然后编码存放在rom中。

FhnT-gRk2-g0Ku7BS-fTWQVMIxie

test为顶层文件,输入小脚丫开发板的系统时钟C1(12MHz),系统复位引脚定义为L14,加电子琴的13个按键,以及切换拨钮N4,加上两个“上下”按键以及演奏模式与音乐播放模式切换按键。

输出有电子琴蜂鸣器buzzer:P8,电子琴扬声器speaker:N8,以及小脚丫fpga板上8个led与两个rgbLED,两个数码管

以下是部分子模块:

Buzzer为蜂鸣器发声文件,输入小脚丫开发板的系统时钟C1,系统复位引脚定义为L14,通过电子琴的按键产生对应的pwm波驱动蜂鸣器发声。

输出有电子琴蜂鸣器buzzer:P8,以及通过按键状态输出buzzer。

dds为扬声器发声文件,输入小脚丫开发板的系统时钟C1,系统复位引脚定义为L14,以及输入对应音符的参数,则通过电子琴的按键产生对应的正弦波驱动扬声器发声。

输出有电子琴蜂鸣器speaker:N8,输出是通过pwm调制输出,

从图可以看出,改变占空比就可以改变电压值,一个占空比对应为一个模拟电压值,用PWM的方式实现数字到模拟变换的功能。

这个为DDS的仿真图,频率在130HZ,根据输出的PWM占空比不同,如下图,

播放音乐模式存放了如下歌曲,通过对应的简谱,然后编码存放在rom中。

2.蜂鸣器和模拟喇叭的差别

模拟喇叭又称为扬声器,是电声转换器件,它可以把模拟的电信号转换为声音信号,它属于宽频率发声器件。蜂鸣器是一体化的电子讯响器,可以在不同驱动波形下发出单调的声音,属于窄频率发声器件。所以只要有合适的模拟信号,喇叭就可以播放对应的音乐。

用蜂鸣器和模拟喇叭的实现方法差别以及音效差别分析

本项目蜂鸣器发声靠的方波提供外部震荡激励,当震荡频率不同时发出不同的音调,对于FPGA来说,方波信号产生方便可靠,成为外部震荡激励的首选,方波信号输入谐振装置转换为声音信号输出。而模拟喇叭靠的是DDS产生的模拟信号,将模拟信号经PWM调制,在经RC滤波,最后接专门的音频放大器最后输出给喇叭。两个发声实现的方法都用到PWM,蜂鸣器是用PWM作为方波信号输入,而模拟喇叭则是把PWM做dac,将数字量转模拟量,最后通过放大器输出给喇叭。在音效方面,蜂鸣器听起来有点滴答滴的音效,而喇叭听起来或许和网上一样,嘈杂而又喧闹的喇叭声。我自己是真的听不出来是什么效果, 喇叭的声音是非常强大的,可以播放许多音效。

关于电路仿真部分,由于自己对电路方面有待提高,以及对RC滤波电路和放大器工作原理的理解,暂时还没有做出来。

3.主要代码片段及说明

reg pwm_out;
reg [31:0] cnt;
always @(posedge clk or negedge rst )
	begin
	if(!rst) cnt<=0;
	else if (cnt>=T/2) cnt<=0;
	else cnt<=cnt+1; 
	end

always @(posedge clk or negedge rst)begin

	if (rst==0) pwm_out<=0;
	else if (cnt==T/2) pwm_out<=~pwm_out;
	else pwm_out<=pwm_out;
end

以上代码为根据一个传入的参数T,再利用计数器来产生一个对应的频率的方波,其对应的公式为f=12000000/T,如440hz时,对应的T为27272。

wire [31:0] T;
reg [23:0] 	phase_acc;
always @(posedge clk_in) phase_acc <= phase_acc + T;  //主时钟为12MHz,寻找波表产生模拟信号
sin_table u_sin_table(.address(phase_acc[23:16]),.sin(date_out));

利用计数器phase_acc 和T来作为地址寻址,继而产生对应的模拟信号,使用24位phase_acc 计数器和12MHz时钟,输出的频率分辨率可以达到0.7Hz,然后根据想要的频率,即可计算出对应的T,如果是从phase_acc[23:16]开始寻址,则当T=2^16=65536时,正好输出phase_acc[7:0]+1时对应的频率46.875KHz,故我们需要的频率与T的关系为f=46875*T/65536,如输出440Hz时,对应的T为615。

还有一些代码则在工程中说明。

4.遇到的主要难题及解决方法

在刚开始,和往常一样通过电子琴的按键去点灯,可是遇到引脚映射的时候,发现点灯失败,后面去分析了小脚丫的原理图,以及电子琴的原理图,还有电子森林提供的小脚丫引脚图,综合分析下,最终确定了电子琴每个按键对应的引脚。这对后续的引脚映射节省的许多时间。

第二个难点是对DDS存的波表数据处理,因为例程给的是正弦波的波表数据,而项目要求需要基波和至少一次谐波,当时群友和网上都提到了许多工具有matlab,mif工具等等,最后为了处理简单,我选择了一次谐波,然后通过比较简单的excel工具去生成波表数据。

第三个难点是对DDS代码的理解,本次项目DDS代码是在电子森林例程上改动的,因为例程上只存了四分之一个波表数据,其他的都是基于对称性实现,而为了代码好理解,而本次项目则是存储了整个波表的数据。在存为波表数据后,下载程序,发现电子琴没有声音。然后就是各种找资料,问群友,最后的解决方法就是做仿真,最后通过仿真观察,发现波形不对,最后仔细查看了代码和仿真,发现问题出现在位数上面,以及寻地址的参数,通过合适的位数,防止溢出,以及寻完地址和频率范围调节参数设置好后,仿真的波形终于对了。

第四个难点,对音乐播放的设计,起初我对这一块是毫无头绪的,最后在网上查找资料,花了两三天去理解和设计自己的音乐播放,一开始音乐播放是正常的,后面发现有的音符播放和节奏不对,在问群友和请教别人,发现空拍子和四分音符持续时间,如最短的音符为四分音符,如果将全音符的持续时间设为1s,则需要提供一个4Hz的时钟频率信号即可产生四分音符的时长。最后用状态机实现两首音乐的播放和切换。

当然项目还存在许多需要改进的地方,由于自己调试的时间太短,只能按要求的去实现比较简单的功能。

5.FPGA使用资源情况

通过lattice Diamond编译出Design Summary结果如下,

FoRoTX-msX3mEmO2uY6J0O5yNqOz

共使用了1031个寄存器,其中Lattice的底层逻辑单元叫PFU(Programmable Function Unin,可编程功能单元),它是由8个LUT和8~9个寄存器构成。片(slices)资源使用率,其中作为逻辑和存储的片使用率为79%。当中最关注的LUT4s利用率为79%,作为逻辑的4输入查找表使用1564个。可以在工程文件夹下在impl1文件夹下,打开arearep文件,可以查看每个子模块用的寄存器资源。

6.改进建议

虽然项目基本完成了,但是还是有许多不足之处,因为自己对音乐这东西一窍不通,听不出来好的音效,所以在喇叭做发声装置的时候,只是简单的加了一个谐波,没有去考虑其他的参数,如幅度与相位组合。模拟喇叭的声音听起来怪怪的,第二个问题就是蜂鸣器没有做到音程调节,而扬声器可以做到音程调节,第三个问题就是没有做到好的和弦,两个按键按下,声音是噪的。由于学校有实习,调试的时间比较少,可能还有其他的bug,暂时可能没有发现,后续则会对以上问题进行优化,争取能做的完美,同时能够实现好的音效。最后感谢硬禾学堂和电子森林平台能够给我这一次学习机会,在这一次的学习中,收获了许多!

附件下载
test0.1.zip
lattice工程文件
test_impl1.jed
可直接下载的文件
sinetable.xlsx
波表数据
团队介绍
一名学习FPGA的菜鸟
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号