|
换药不换汤,基于STM32平台软件的DDS演奏程序,音质轻松秒杀传统蜂鸣器:
https://www.mydigit.cn/forum.php?mod=viewthread&tid=135199
用MCU加发生元件比如蜂鸣器播放音乐很多人都做过吧,我也做了一个,不过原理有点不同:
普通做法是用软件输出方波或者PWM硬件输出方波驱动蜂鸣器的,而我使用DAC输出经过放大后再驱动喇叭。而我在MCU内部定义了一个25Ksp的正弦表,还定义了几个幅度表,每一次中断就查一次正弦表和幅度表,查的结果相乘就使得输出正弦波受幅度调制,随后还受额外的幅度乘子调制。幅度表的调制决定正弦波包络时变特性,幅度乘子决定该音调响度。
正弦表查表动作不是查找一次基波结果再输出而是查找8次并按照音色表的加权输出结果。对应基波和7次谐波混合成分输出。此外音色表还定义个谐波的初始相位偏移。改变音色表的个谐波强度和初始相移就可以改变音色。
这是实物:平淡无奇啊,就一个STM32F103ZGT6核心板,连接到扩音器上,实际上STM32F103RCT6就可以做这个实验,代码量不超过200KBytes,而且有DAC。视频如下:
测试视频
这是工程图示:Main函数初始化外设后就开始调用相关函数查找歌曲和播放了。其中硬件只有DAC和SysTick用到了,其它的跟这个工程毫无关系。核心代码在ToneGenerator文件夹中。文件夹有6个文件,4个文件都是查找表,一个文件负责音调发生,一个负责歌曲查找播放。
这里只提供关键的源码,反正没完善也没人看:
调用方式很简单,先设置RCC,使用外部10MHz晶振给PLL提供时钟,进行10倍频。
然后,调用SysTickInitialize初始化SysTick计时器,调用DACInitialize初始化DAC;
调用SongSegBaseAddrSeek寻找全部的歌曲,第一个参数必须是第一首歌曲的基地址,第二个参数是查找范围,设定大一些就行;
调用PlaySongs播放歌曲,第一个参数表示播放第几首歌曲。注意如果你只固化了两首歌曲就不能设置播放第3首歌曲,否则出错返回。
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
打赏
-
查看全部打赏
|