基于nexys4 ddr开发板在vivado 2019.2环境下编写verilog语言实现。具有自动演奏和手动演奏两种功能。实物演示视频->>>简易电子琴_哔哩哔哩_bilibili
我自己也是把现成的代码缝合而成的,想要代码的话,链接在这里,不过得动手拼接一下。这里就只讲下原理了。
大体框架-》》FPGA电子琴_哔哩哔哩_bilibili
键盘扩展-》》数字逻辑大作业: 7k下落式音游_哔哩哔哩_bilibili
电子琴主要解决两个问题
1.如何发出声音
在板子的右上角有个“MONO audio output”,如果里面有信号的话插上耳机就能听到声音。
这是音频输出的约束,把信号接到A11就行,D12是左右声道的选择。
也可以用PMOD口外接发声装置。
2.如何产生音乐信号
这个需要一点音乐知识。其实音乐中的do re mi fa就是一些单一频率的信号,只要知道他们的频率,我们就能产生这些音乐信号,可以看下面的回答
(81 条消息) 音乐和频率的关系,某个音的频率固定的吗,比如一个音100赫兹,那102、105的音很不一样还是差不多? - 知乎 (zhihu.com)
既然知道了每个音是多少赫兹,那么现在我们的目标是:每按下一个键,就产生特定频率的信号。比如:a对应中央c音(261hz),怎么实现呢?这也要分两步走:请看3,4两个小标题
3.怎么产生特定频率的信号?
我们首先用Verilog写一个定时器。如果要产生261hz的信号,那就一秒翻转522次,也就是说,定时器要产生522次中断。
我用的是一个加技术的定时器(代码来源FPGA电子琴_哔哩哔哩_bilibili),也就是每计数到1048575就产生翻转,并重新从预置数oringin开始计数。当然也可以用减计数的定时器,而且那样更方便。
而这个预置数origin跟信号的频率有关:已知板上时钟的频率是100mhz,要产生的信号是261hz,那么聪明的你能否算出origin的值呢?我们可以这样思考,要反转522次,那么每翻转一次就要计数100m%522=19.15万次,那么origin=2^20-191500=857075. (链接里的代码里第一个origin是95w,这是由板子的时钟频率的差异导致的,有疑问的读者可以将50m时钟频率代入验算。)
这里给出origin的计算公式:
所以,要产生不同频率的信号,只要给定不同的origin值就可以了。
4.信号如何与键盘对应?
按下按键后,键盘会发出一个十位数据,其中前八位有效,怎么让这几位数据与信号对应呢?而且USB口只能传输串行数据,这意味着我们还需要进行从并行到串行的转换,这通过锁存器来实现,读取数据后还要转为并行来便于判断
这段代码完成从串行到并行的转换。 (代码来源数字逻辑大作业: 7k下落式音游_哔哩哔哩_bilibili)
这样我们就可以很方便的进行键盘映射了。只要按照下面这张图写一段switch-case语句即可
(然后Z键那里打错了,Z对应的键码是1A。)
下面给出键盘的约束(USB口)
时钟F4由键盘内部产生,B2接受键值。
注意不要用可编程键盘,就用学校机房里的老式键盘就行,当时因为这个原因耽误了我大半天的时间。
祝大家都能顺利完成大作业!!