本文最后更新于:2022年12月22日 凌晨
[fpga4fun] Music box
还没整完。
UPDATE1 AT: 2022-12-22 继续完成了Music box 2 这一部分
因为在学校收了一块野火征途mini FPGA开发板,在看的是配套的视频教程。群里学长推荐我做一做 fpga4fun 上的东西,那就整一整 ~
简介
这个项目是用 FPGA 驱动喇叭发出声音和音乐。
硬件连接为 FPGA 开发板,一个喇叭,一个 1kΩ 电阻。
Music box 1 -Simple beep
计数与频率
一个16位的计数器,范围位 0 ~ 65535 共65536个值,如果板子的主频为 25M ,如果在上升沿计数(时钟是个方波),那么这个16位计数器最高位对应的频率便为 $25\times10^6\div65536=381Hz$ (就是加到对应那一位变化之后算一次)
以此类推第15位为 $25\times10^6\div32768=762Hz$ , 第14位为 $25\times10^6\div16384=1525Hz$ …… 第2位为$25\times10^6\div4=6.25\times10^6Hz$ , 第1位为$25\times10^6\div2=15.5\times10^6Hz$
产生 A 的声音
A 的频率为 440Hz
以 25M 主频为例,产生440Hz可以先使用16位计数器,将 25M 分为 65536 份,此时计算出产生 440Hz 只需要计数到 56818 即可。
但是这样的话,占空比就不是 50% 了,$b’1000\ 0000\ 0000\ 0000=d’32768$ ,所以低电平为 032767,高电平为 3276856818,占空比为42%
所以可以折中一下,然后每次翻转 speaker
的电平值 ,而且折中之后可以省一位计数器的值~
实践
因为征途mini的主频为50M,所以用17位可以产生的时钟为 $(2\times25\times10^6)\div(2\times65536)=381Hz$
要产生440Hz,计数到 $56818\times2=113636$ 即可。
使用翻转的方式,使用16位计数器,折中计数至 56818,同时加上了复位信号
主程序代码:
仿真验证,Testbench
代码
仿真结果
占空比 $4545450-3409090=1136360$ $3409090-2272730=1136360$ ,可以看出占空比确实为50%
频率 $\frac{1}{4545450-2272730}\times10^9=440Hz$
)因为我莫得喇叭,就先不上板子了……
剩下的等我学完…… 下面的再更新一下
添加参数
添加了一个名字叫 clkdivider
的参数,方便之后的修改。
Music box 2 - Ambulance siren
这次在两种音调之间交替。首先使用24位计数器 tone
来产生一个缓慢的方波,其最高位(MSB)以1.5Hz的频率进行切换。然后我们在这两个频率之间切换另一个计数器。这样就发出了类似救护车警报一类的声音。
先产生一个1.5Hz的信号 tone
,此时计数器 counter
为向下计数,当 counter
为0时,如果 tone
为1,继续产生440Hz的信号,当 tone
为0时,产生220Hz。这两个频率的信号以1.5Hz的频率交替出现。
Police siren
接下来是生成一个听起来像警笛的声音。这个声音听着是又小逐渐变大的这种,之前声音像跳楼梯,这次的像上坡。
我们将音调计数器 tone
的速度提高一倍,变为3Hz。
然后,就开始升频操作。我们提取音调计数器的16位到第22位:tone[22:16]
。这样我们得到了7bit,并且以一个中等速度从0~127,到达127后,再从127~0。
为了得到一个向下的斜坡,将其进行翻转(~tone[22:16]
),此时从127~0。
为了切换上下这两个通道,同上面一样,我们根据 MSB tone[23]
的值进行选择,3Hz切换一次。
wire表示直通,即只要输入有变化,输出马上无条件地反映;reg表示一定要有触发,输出才会反映输入。(【Verilog HDL】Verilog中wire与reg类型学习 - 知乎 (zhihu.com))
这样做的意义:fpga4fun.com - Music box siren ramp 。
这个 ramp
的值从 7'b0000000
到 7'b1111111
。为了得到一个可用的值产生声音,我们在他前面补2位 2'b01
后面补7位 7'b0000000
进行填充。
这样, clkdivider
的值从 16'b0100000000000000
到16'b01111110000000
,在50MHz的时钟下,相当于产生从765Hz到1525Hz的高音调警报器。
High-speed pursuit
要进行高速追击,警报声音有快有慢。
所以 tone[22:16]
给我们一个快速的斜坡,而 tone[25:19]
给我们一个缓慢的斜坡。
最终代码
仿真
可以看出间隔确实是变化的,仿真波形图里第一个频率经过计算为912Hz,符合要求。
待续……