简单音调生成

该模块通过使用一个计数器生成一个1 kHz的信号,该计数器在CLK的每个刻度上都递增。 当计数器达到32,000时,将切换输出BUZZER,并将计数器重置为0。

https://embed.notionlytics.com/wt/ZXlKd1lXZGxTV1FpT2lJMk56bGpNakZrTVRFMU16VTBNV1ppT0ROa05UZzFaV1JpWWpkbFlUSTRNeUlzSW5kdmNtdHpjR0ZqWlZSeVlXTnJaWEpKWkNJNklsZHNTR2hsVEZSUFdXeHpaVmRhUW1ZNU1YQmxJbjA9

音频输出

使用一个1-kΩ电阻器和一小段实心线将GPIO引脚P97和GND连接到与有源扬声器相连的音频引线。 导线和电阻器引线仅缠绕在音频插孔的接地和插孔插头的尖端部分周围。

您可能想使用一些排针和一个3.5mm直插式插座来做一些实质性的事情。

通用音/频率发生器

我们制作一个通用的音调发生器模块,该模块将针对您的电路板的时钟频率进行参数设置,并且还允许您指定要产生的音调作为其输入之一。

该模块的测试程序不会通过音频插孔播放生成的频率,而是会在FPGA板的三个不同引脚上生成三个不同的频率。 如果您的示波器或万用表具有频率设置,那么您将能够验证所产生的信号。 如果您不这样做,则按照“警报”项目,将其中一个“音调” NET的位置(LOC)更改为音频插孔,并通过放大器收听音调,尽管您可能很难听到12.5- kHz音调。

音调模块具有系统时钟(CLK)的输入以及要生成的音调周期(以微秒为单位)和tone_out的单个输出。 参数CLK_F用于配置模块的预分频器以适合您电路板的时钟频率。 使用周期而不是频率的原因是将频率转换为要在Verilog中计数的多个时钟周期将需要除法。 在不使用除法模块的情况下,无法在Verilog中除2的幂(1、2、4、8、16等)以外的任何东西,否则将需要除以一个时钟周期来执行。

时钟的频率是每秒的完整周期数(从0到1再回到0)。 时钟周期是一个周期所花费的时间。 因此,对于非常慢的1 Hz时钟(每秒1个周期),周期为1秒。 对于1 MHz时钟,周期为1 / 1,000,000秒或1微秒。

对于特定频率f,周期为1 / f。下表中列出的周期代表您可能希望与音频模块一起使用的一些值得注意的频率。

使用两个计数器。 预分频器计数器将时钟频率降低到2 MHz,并且计数器用于计数预分频的时钟。 预分频器生成2MHz时钟而不是1MHz时钟,因为每次到达正确的周期时,输出将被切换(0至1或1至0),从而有效地将频率减半。 这种切换可确保生成的信号具有50%的占空比。 即,方波的大小相等且高低。

tone_tester模块会创建音频模块的三个实例,每个实例都在不同的引脚上,并且以不同的频率。 实际上,period_12khz实例将产生12.5 kHz而不是12 kHz的频率。

FPGA微型板端口示意图

播放音频文件

该项目使用FPGA通过放大器播放录制的音频数据。 它介绍了一些有用的新技术,包括使用随机存取存储器(RAM)以及如何在合成期间将其与一组数据一起加载。

音频文件

音频文件的类型很多,大多数使用聪明的压缩算法来尽可能地减小文件的大小,而质量的损失则尽可能小。 简单来说,一个音频文件将只包含一系列数字,每个数字代表一个瞬间的振幅(思考电压)。 这种格式称为原始格式,因为没有花哨的数字。 下图显示了一个我说“一”字的样本数据。“一个”音频样本的波形。

每个采样点的数值都保存在一个字节(8位)中,范围为0到255之间的数字。声音是以8 kHz采样的,因此大约3,800个采样代表不到半秒的音频。