切换到宽版
  • 15922阅读
  • 71回复

[ARM]可能是电路最简单的MP3播放器(STM32F103RC最小系统) [复制链接]

上一主题 下一主题
离线wangyz1997
 

发帖
17
M币
4091
专家
9
粉丝
4
— 本帖被 青柠 设置为精华,作者+3000M币+5专家(2018-03-29) —
最近在使用STM32F4调试一个MP3播放器,使用STM32F411+WM8978,支持WAV、FLAC和MP3格式,因此积累了好多音频方面的代码。有一天突然突发奇想,STM32F411的时钟频率有100MHz,那么能流畅播放MP3的最低频率能到多少呢?经过实测,30M!这个数据可真是震撼到我了,居然这么低的时钟频率即可流畅解码FLAC和MP3,突然觉得用F4做这个MP3有点浪费……(当然还是要做的,毕竟音质好)

于是脑洞大开……能不能用F1完成这个播放器呢?并且脑子中诞生了一个大胆的想法——这个播放器最好能做到最简化,让所有有最小系统的人都可以体验到音乐的乐趣。

个人使用的音乐播放器是网易云音乐,它上面下载的FLAC文件都是LV8的,解码需要90k左右的内存,F1自然是全系列都不能满足,但是LV2需要的内存和MP3差不多,需要30k多的内存,这样大部分大容量的F103就能满足了。由于懒得每首歌都转换,就没有移植FLAC的解码,其实是很好实现的,并且解码FLAC所需要的MIPS是比MP3小的。

由于使用F4芯片里面有独立的音频PLL和全功能的IIS,F1里面的IIS是残废的(除非使用外置时钟,否则时钟误差极大),因此就排除了用外置DAC的想法。突然,我想到大容量的芯片里面有内置的DAC!那么我们能不能就用这个DAC就输出音频呢!

首先查看选型表,我们常见的STM32F103RCT6就能满足我们的需求,看图。


STM32F103RC大容量系列,有48k的内存(据说是和ZET6一样的晶元,说不定能用上64K,但是这里48K已经足够),还有双路DAC,正好两个声道,用它做播放器,岂不是美滋滋。

等等…这个DAC是12位的。我们常见的音频文件都是16位的,这个DAC并不能接受我们常见的音频文件,需要进行一个转换,这也成了浪费我时间最多的步骤。有人可能会问,12位音质会不会很差啊?我可以负责的告诉你,音质绝对说的过去,至少木耳是听不出来和手机明显的差别的。

说完了DAC的位数,好多人可能还会怀疑这个内置DAC的性能问题。经过手册查询,这个DAC输出值从最低到最高需要4us,也就是250KHz,对于音频完全没问题,而且音频也不会出现幅度这么大的数据。并且带一个可配置的输出缓冲器,可以省掉外部的运放,直接驱动一定的负载,真的离极简设计越来越近了。

说干就干。首先将以前移植好的SD卡驱动简单移植,实现了文件的读取以后,就开始移植WAV播放程序。先移植它是因为WAV不需要解码,直接读文件送进去就好。这里需要提一下我程序框架的问题。由于以前已经有成熟的MP3,因此程序都是有一套框架的。基本的就是设置IIS等参数,然后读文件,等待当前缓冲区播放完再继续读取然后解码。因此我的程序中出现一些IIS字眼不要担心……只是直接移植,懒得改了。

音频播放是定时器+DAC+DMA,这个例程ST官方就有提供,我只是简单移植就让DAC双通道输出了正弦波。

定时器部分就是产生一个和音频文件采样率相同的时钟给DAC,让DAC按照这个速度去找DMA取数据,DMA有两个缓冲区,播放一个缓冲区的时候读取和解码另一个缓冲区,这样纯硬件的播放可以保证恒定并且正确的播放速度,并且不需要使用CPU进行数据的搬运。当一个缓冲区播放完以后,产生中断,切换缓冲区,继续读取。下面是DMA和定时器的初始化代码。



接下来就是把缓冲区改成文件了。一到这儿我傻眼了,F4的DMA有双缓冲模式,F1没有…正在我一筹莫展的时候,我发现F1的DMA中断有一个半传输中断,这玩意儿不就和双缓冲一样的东西嘛……只需要取两倍的缓冲区大小,然后使能半传输和传输完成中断,就能实现类似双缓冲的无缝播放的效果。




注意这里的DataRequestFlag一定要加__IO也就是volatile修饰,要不会被优化掉,卡死在while里。
这里的DualSine12Bit就是缓冲区了,根据中断类型返回是缓冲区起始地址还是加上一个缓冲区(也就是后一半)的地址。

有了数据,声音是出来的。但是杂音非常非常大,只能听到一点点音乐。我想起来我是直接把立体声16位的数据送给DAC的双通道左对齐寄存器(DAC->DHR12LD),我原以为这样就能一次传输两个通道的数据并且舍弃掉低4位,但是我错了。查阅资料发现,IIS的16位数据是signed short,也就是有符号位的,并且负数是用补码保存的,然而我们这里的DAC应该工作在中值为2048(一半参考电压,加耦合电容),因此音频数据我们需要稍微处理一下,如下面程序所示,除以16再加2048转换成无符号数。


经过这样处理,音频已经能很好地播放了,并且音质严重超出了我的预期,真的是很不错,并且DAC的驱动力真的很大,我的耳机串了一个1k的电阻,音量才到人耳舒适的范围,加上两个10uF的耦合电容,要是不算最小系统和SD卡模块总共只需要四个元件。由于电阻很大,因此电容很小也能获得很低的相应频率。

为了换歌曲方便,我加了两个按键,分别是上一曲和下一曲,还加了一个10K的双联音频电位器调整音量,自此一个WAV播放器就搞定了。


硬件连接如上图所示,端口可以在程序里修改。SD卡使用SPI2,CS脚是PB12,CLK=PB13,MISO=PB14,MOSI=PB15。
整个播放器只用了8个IO口!要是只用一个下一曲还可以再省一个,最小系统周围一圈IO口显得空空荡荡的……


整体照,一个最小系统加一个SD卡模块+一个自己焊接的小板子



小板子特写,总共两个电阻两个电容一个电位器两个按键和一个耳机座。


最小系统的IO显得空荡荡的……

SD卡模块,治好颈椎病

接下来的MP3解码也就轻而易举了。移植了HELIX库,声音也很轻松的出来了。
最后,我还将MP3解码器移植了一份直接从ROM读取数据的版本,这样就可以方便的做开机语音和语音提示之类的了。程序只占用了40k,ROM还剩下了200K左右,放44.1KHz,16Bit,64KBps的单声道音频可以放半分钟多,足够了。有兴趣的可以用JLINK烧一个不带任何ID3信息的MP3文件到0x08020000也就是128k的地方感受一下开机语音。

惯例上程序,做这个播放器的初衷很简单,就是希望所有有最小系统的人都可以轻松地享受到音乐的乐趣!
本文内容包含图片或附件,获取更多资讯,请 登录 后查看;或者 注册 成为会员获得更多权限
本帖最近打赏记录:共10条打赏M币+93专家+2
390376626 M币 +1 还是做个性能真的HIFI无损的播放器吧 04-05
troy012 M币 +15 - 04-05
bighuasheng M币 +15 謝謝分享 04-03
szdiy M币 +15 不明觉厉,紫苏布丁。。。 04-02
hongo 专家 +1 優秀文章,加砖家! 04-02
q版虎斑猫 M币 +13 - 03-31
weizaisifang 专家 +1 謝謝分享 03-31
weizaisifang M币 +13 謝謝分享 03-31
girlstorm M币 +13 謝謝分享 03-31
junerjoe M币 +8 原創內容 03-31
关键词: MP3播放器
在线jpdd521

发帖
25581
M币
1167
专家
15
粉丝
335
只看该作者 1楼 发表于: 03-29
如果能加个屏幕,那就更厉害了。
本帖最近打赏记录:共1条打赏M币+9
离线extractio

发帖
619
M币
175
专家
0
粉丝
6
只看该作者 2楼 发表于: 03-29
hit00版主以前也搞了个播放器,只有几个元件:http://bbs.mydigit.cn/read.php?tid=193645
简易无损音乐播放器,软解FLAC/MP3/WAV:http://bbs.mydigit.cn/read.php?tid=1925663
自制MP3播放器,这次用8051核心带液晶屏:http://bbs.mydigit.cn/read.php?tid=188161

楼主留言:

都是很强的前辈,多多少少都参考学习过!

本帖最近打赏记录:共1条打赏M币+20
离线wangyz1997

发帖
17
M币
4091
专家
9
粉丝
4
只看该作者 3楼 发表于: 03-29
回 extractio 的帖子
extractio:hit00版主以前也搞了个播放器,只有几个元件:http://bbs.mydigit.cn/read.php?tid=193645 (2018-03-29 12:10) 回 extractio 的帖子

我这个主要是用了DAC,音质会稍微好一点,并且支持软解MP3~
本帖最近打赏记录:共1条打赏M币+5
离线szb314

发帖
961
M币
1427
专家
1
粉丝
6
只看该作者 4楼 发表于: 03-29
看着很不错的样子
离线wangyz1997

发帖
17
M币
4091
专家
9
粉丝
4
只看该作者 5楼 发表于: 03-29
回 jpdd521 的帖子
jpdd521:如果能加个屏幕,那就更厉害了。 (2018-03-29 12:08) 回 jpdd521 的帖子

好加的!常用的播放数据都有,找到结构体调用直接显示就行
离线wangyz1997

发帖
17
M币
4091
专家
9
粉丝
4
只看该作者 6楼 发表于: 03-29
对了,音乐文件必须要放到SD卡根目录下!
离线cxw0102

发帖
1630
M币
6795
专家
15
粉丝
89
只看该作者 7楼 发表于: 03-29
優秀文章,赞一个
离线cao57508

发帖
2151
M币
3943
专家
9
粉丝
73
只看该作者 8楼 发表于: 03-29
厉害了我的哥,这个真实现了
离线ifus

发帖
341
M币
381
专家
0
粉丝
7
只看该作者 9楼 发表于: 03-29
厉害了,单片机发烧级别呀
快速回复
限80 字节
“新手上路”发帖需审核后才能显示(请认真发帖),达到数码9级后取消此限制
 
上一个 下一个