搜索
bottom↓
回复: 18

跟马老师PK,M051 WAVE播放器初级阶段完成

[复制链接]

出0入0汤圆

发表于 2011-2-8 03:30:49 | 显示全部楼层 |阅读模式
从打通SD卡到今天初步完成,一共花了约五天时间。

除夕:能够播放8位单声道WAVE音乐
初一:代码结构整理
初二:玩~~=。=
初三:能够播放8位双声道和16位单声道音乐,16位双声道音乐播放起来有点卡
初四:扩大音频数据缓冲区,从原先设计的256扩大到512,进一步调整代码,目前已能流畅播放16位双声道CD音质WAVE文件。

初稿已经完成,但代码结构还是比较凌乱。
没有采用马老师的思路——利用M051强大的PLL功能精确设计系统时钟以使其产生的中断与CD音质44100Hz的采样率相吻合。
我使M051工作在48MHz,使用外部12晶振经过PLL倍频获得。使用了一个内部定时器TIM1工作在CTC模式产生44100Hz的中断。
SystemClock = 48MHz
则TCMPR1 = (48000000/44100) - 1 ≈ 1087
于是TIM1的中断频率为44117.64705882Hz,与44100Hz相比对,误差约为0.040016%,即为万分之四,这样的误差,人耳已经很难分辨。

如果将缓冲区大小设为256,则播放16位双声道音乐会很卡,而播放16位单声道则没任何问题,故而将缓冲区设为512字节。
文件系统上层可以不用作任何改动。

由于手头只有一个内磁式喇叭,测试16位双声道播放性能时,无奈使用了板载的无源蜂鸣器来尝试,效果居然还不错,啊哈……

^_^

期间遇到了不少问题,比如系统时钟的配置与选取,接口初始化等,马老师都给予了细心的解答,在此感谢马老师。
初七上班后若有时间必定发帖讨论此次制作中遇到的一些问题。

祝大家兔年快乐!!^_^

注:照相机未带,手机数据线也没带,本想拍个视频,等到明天回来后再说吧!:)

出0入0汤圆

发表于 2011-2-8 03:57:28 | 显示全部楼层
期待

出0入0汤圆

发表于 2011-2-8 08:00:27 | 显示全部楼层
mk

出0入0汤圆

发表于 2011-2-8 08:59:24 | 显示全部楼层
前排等待

出0入168汤圆

发表于 2011-2-8 09:33:21 | 显示全部楼层

出0入168汤圆

发表于 2011-2-8 09:37:54 | 显示全部楼层
不知楼主输出滤波是怎么解决的

出0入0汤圆

发表于 2011-2-8 09:45:31 | 显示全部楼层
good

出0入0汤圆

发表于 2011-2-8 10:48:58 | 显示全部楼层
LZ公布出来吧,让大家也玩玩,我用STM32已经做到 44.1KHz 16位单声道播放了。。。

出0入0汤圆

发表于 2011-2-8 12:46:19 | 显示全部楼层
为何不用11M2896晶振呢?

出0入0汤圆

 楼主| 发表于 2011-2-8 12:56:06 | 显示全部楼层
回复【5楼】eiglxl
-----------------------------------------------------------------------

这块目前还没考虑,PWM输出直接接到喇叭上……呵呵~

出0入0汤圆

 楼主| 发表于 2011-2-8 12:56:57 | 显示全部楼层
回复【8楼】90999 张耀扬
-----------------------------------------------------------------------

一是我手头没这样型号的晶振,二是即使用12M晶振来做,误差也十分小,基本可以忽略~

出0入0汤圆

发表于 2011-2-8 13:20:34 | 显示全部楼层
pwm?1087?16位?o
只能达到10位的精度吧

出0入0汤圆

发表于 2011-2-8 14:05:09 | 显示全部楼层
回复【楼主位】tearsman520 消逝的岁月

我使M051工作在48MHz,使用外部12晶振经过PLL倍频获得。使用了一个内部定时器TIM1工作在CTC模式产生44100Hz的中断。
SystemClock = 48MHz
则TCMPR1 = (48000000/44100) - 1 ≈ 1087
于是TIM1的中断频率为44117.64705882Hz,与44100Hz相比对,误差约为0.040016%,即为万分之四,这样的误差,人耳已经很难分辨。

如果将缓冲区大小设为256,则播放16位双声道音乐会很卡,而播放16位单声道则没任何问题,故而将缓冲区设为512字节。
文件系统上层可以不用作任何改动。

-----------------------------------------------------------------------
以上的计算和设计不太理想,可能你为了提高SPI接口的速度吧,但可能影响到音质效果。

1。放双声道16位的音频采用的4个8位PWM完成的。那么系统的时钟应该是44100*256 = 11.2896M的倍数最好。
   你使用48M,那么48000000/256 = 187500,187500 / 44100 = 4.2517。由于PWM是完成一次整个波形后才自动更新比较匹配值的,所以尽管你中断按44117更新数据,但实际上的结果是:
音频数据顺序:    1       2       3      4      5
PWM产生次数:     4       4       4      4      5
实际的效果是前4个数据是按46875hz播放,最后一个数据按37500Hz播放的,并不是每个都严格按44117播放,只是平均为44117播放。

   实际上M051内部RC的标称频率为22.1184,采用PLL可以得到45.1584M,这个频率45158400/256/44100 = 4,理论上没有误差的。

   我使用12M外部,PLL到56.4M。56400000/256/5 = 44062.5hz。 与44100Hz相比对,误差约为0.085%,即为万分之八点五。

   如果采用外部11.2896M的晶体(这个是标称晶体值),那么最好使用PLL到5倍(56.448M)或以上的整倍数(对于使用STM32,可以到6倍)。这样理论误差为零。

2。对于流畅播放16位双声道,要考虑到几个方面:缓冲区的大小,SPI的速度,和代码的优化(最快的处理),那么关键的问题是在什么地方?下面分析一下。

   保证“流畅”,也就是音频数据必须按44100Hz的速度保证提供到位。我们看以下数据:

系 统 时 钟 (Mz)               11.2896       22.5892    33.8688    45.1584     56.448
44.1K中断间隔(CLK)               256            512        768       1024        1280

读一个16位双声道数据为4个字节,每个字节大约需要20个CLK(读8CLK,加上启动、读取、调用和返回)。这样就减掉了仅80-100个clk。在剩余的时间里还要处理其它的事情,如BUFF的填充、指针的调整、按键的检测等。如果碰到一个扇区读完,还要进行FAT表的查找,定位下个扇区的位置(这个花费更多),那么就要“卡”了。

以上只是一个分析,实际上缓冲区大些,SPI速度快一点,也是可以把时间合理调配和补充的,但要看你代码如何实现了。

我采用的实际设计为:
1。采用56.4M时钟,中断间隔为1280,播放频率44062.5Hz,PWM频率为5倍。
2。中断间隔1280CLK,之间可以做更多的事情
3。BUFF采用256*4,使用一组指针。使用256,不用进行比较判别,只要加就可以了,节省语句,减少了指令消耗。
4。整个系统只有一个中断,TIMER0,用于更新播放数据
5。系统代码优化:包括按键的检测等,都使用最少的语句。
6。我使用的SPI的时钟是9.4M(56.4/6),这个也是不太满意的地方。按MO51手册,SPI最高可以达到16M。但我设置成56.4/4=14.1M,读SD卡就出现了问题。

如果使用11.2896晶体,可以PLL到45.1584M作为系统时钟,此时SPI的速度可以提高到11M,但中断间隔减少为1024。

===========================================
我已经准备了80几首APE转的WAV文件,全部是无损的,开学后PK一下。

出0入0汤圆

发表于 2011-2-8 14:11:03 | 显示全部楼层
6。我使用的SPI的时钟是9.4M(56.4/6),这个也是不太满意的地方。按MO51手册,SPI最高可以达到16M。但我设置成56.4/4=14.1M,读SD卡就出现了问题。


同感~~~

出0入0汤圆

发表于 2011-2-8 14:16:37 | 显示全部楼层
回复【8楼】90999 张耀扬
为何不用11m2896晶振呢?
-----------------------------------------------------------------------

如果真的做播放器,当然使用11.2896的晶体。由于我们做的MO51转换板上用的12M,所以就使用12M的。实际上使用M051内部的RC 22.1184M,采用PLL可以得到45.1584M,这个频率45158400/256/44100 = 4,理论上没有误差的,但我测试过内部RC也是有误差的,手册给出的指标:使用矫正后也只能达到3%的精度。

其实,这个DD重要的代码和系统设计,达到效果后,换一个晶体就可以了。现在只是练手学习

出0入0汤圆

发表于 2011-2-8 14:29:35 | 显示全部楼层
回复【13楼】90999 张耀扬
6。我使用的spi的时钟是9.4m(56.4/6),这个也是不太满意的地方。按mo51手册,spi最高可以达到16m。但我设置成56.4/4=14.1m,读sd卡就出现了问题。
同感~~~
-----------------------------------------------------------------------

这个我做过多次的简单测试,在我们目前的硬件条件下,SPI的时钟在12M以下能正确操作SD卡,问题可能是:

1。接线太长等因素。我们是使用10cm长的连线接SD卡座的,M051为5V,SD卡3.6v,当中数据线只是采用电阻分压的方式连接,当SPI频率高的话,会影响波形的。

2。尽管高速SD卡的协议上说SD卡支持25M的时钟,但不是所有的DS卡都达标,一些老卡,或非品牌的卡的速度肯定是有折扣的。

出0入0汤圆

发表于 2011-3-9 01:57:40 | 显示全部楼层
回复【13楼】90999 张耀扬
6。我使用的spi的时钟是9.4m(56.4/6),这个也是不太满意的地方。按mo51手册,spi最高可以达到16m。但我设置成56.4/4=14.1m,读sd卡就出现了问题。
同感~~~
-----------------------------------------------------------------------
用过STM32F103RBT6做过一个WAV播放器,也是使用的SPI接的卡,记得当时SPI时钟频率达到32M,(已经大大超过手册上的数据18M),一样跑得欢畅。(源代码可见我另一帖,带CRC校验).

出5入8汤圆

发表于 2011-3-9 10:39:31 | 显示全部楼层
期待

出0入0汤圆

发表于 2011-6-14 17:02:02 | 显示全部楼层
马老师,你好,最近我一直在玩SD卡。SD卡的底层驱动已经没问题,可是FAT文件系统一直没搞定,好烦。马老师能否提供基于AVR单片机CVAVR写的FAT文件系统参考一下?先谢了!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-19 07:20

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表