定义:
VS1053是荷兰VLSI公司推出的一款高性能编解码芯片。
该芯片可以实现对MP3/OGG/WMA/FLAC/WAV/AAC/MIDI等音频格式的解码。
同时还可以支持ADPCM/OGG等格式的编码。
特点:
VS1053芯片内部还带了一个可变采样率的立体声ADC(支持咪头或线路输入)、一个高性能立体声DAC及音频耳机放大器。
●支持音量调节、高低音控制和EarSpeaker空间效果。
●低功耗 。
接口:
VS1053通过SPI接口来接受输入的音频数据流,它可以是一个系统的从机,也可以作为独立的主机。本例程,我们把它当成从机使用。我们通过SPI口向VS1053不停的输入音频数据,它就会自动帮我们解码了,然后从输出通道输出音乐,这时我们接上耳机就能听到所播放的歌曲了。
VS1053的SPI数据传送,分为SDI和SCI,分别用来传输数据/命令。SDI采用SPI协议,不过,数据传输受DREQ控制,主机在判断DREQ有效(高电平)之后,直接发送数据即可(一次可以发送32个字节)。
SCI 寄存器,重点研究 MODE 等七个寄存器。
基本设置:
-
- MODE寄存器(0X00)
SM_RESET:软件复位,建议在每播放一首歌曲之后,软复位一次。
SM_SDINEW:模式设置位,设置为1,选择VS1002新模式(本地模式)。
-
- BASS寄存器(0X02)
声音设置:
高低音设置用BASS寄存器。
EarSpeaker 用MODE来设置。
-
- CLOCKF寄存器(0X03)
CLOCKF,一般设置此寄存器的值为0X9800,表示外部时钟是12.288M,内部时钟频率为输入时钟频率的3倍,倍频增量为1.5倍。
-
- DECODE_TIME寄存器(0X04)
它是一个累计时间,在每首歌播放之前,需要把它清空一下(给寄存器写0),以得到这首歌的准确解码时间。
-
- HDAT0&HDAT1寄存器(0X08&0X09)
这两个寄存器,是数据流头寄存器,不同的音频文件,读出来的值意义不一样,我们可以通过这两个寄存器来获取音频文件的码率,从而可以计算音频文件的总长度。
-
- VOL寄存器(0X0B)
该寄存器用于控制VS1053的输出音量,该寄存器可以分别控制左右声道的音量,每个声道的控制范围为0~254,每个增量代表0.5db的衰减,所以该值越小,代表音量越大。比如设置为0X0000则音量最大,而设置为0XFEFE则音量最小。
注意:如果设置VOL的值为0XFFFF,将使芯片进入掉电模式!
VS1053初始化步骤
①复位VS1053
包括硬复位和软复位,让VS1053恢复初始状态,准备解码下一首歌曲。在每首歌曲播放之前都可以执行一次硬件复位和软件复位(推荐每首歌播放之前,只进行软件复位,硬件复位一次,会呲呲呲的响,出现大的问题,可以进行硬件复位。),以便更好的播放音乐。
②配置VS1053的相关寄存器
这里我们配置的寄存器包括VS1053的模式寄存器(MODE)、时钟寄存器(CLOCKF)、音调寄存器(BASS)、音量寄存器(VOL)等。
③发送音频数据
经过以上①、②配置以后,我们剩下来要做的事情,就是往VS1053里面发送音频数据,只要是VS1053支持的音频格式,直接往里面丢就可以了,VS1053会自动识别,并进行播放。不过,发送数据要在DREQ信号的控制下有序的进行,不能乱发。这个规则很简单:只要DREQ变高,就向VS1053发送32个字节。然后继续等待DREQ变高,直到音频数据发送完。
暂停: | 就算DREQ来了,也不传输数据。 |
快进/后退: 偏移之后,再传输数据。
SPI速率的确认:
SCI 读取的时候,SPI 不能超过4M.
SCI 和 SDI 写入的时候,SPI 不能超过9M.
CLK的值 12.28 *3 约等于 36M. (外部时钟是12.28M,内部时钟频率为输入时钟频率的3倍,所以clk = 12 * 3)
获取码率:
根据HDAT0&HDAT1的值,可以获取码率值,从而知道音频的播放时长。
对于WAV , MIDI等格式。因为HDAT0的位长是16位,所以表示的最大值是 65535,那速率65535 * 8 = 524280 = 524K,速率超过524Kbps的就码率就准确了,算的时长就不正确了。
对于mp3,因为它的速率是根据查表法得到的,不是根据 HDAT0 得到的,所以它的时长计算,比较准确。
装载patch:
VLSI 的 VS10XX 系列芯片都会有一些 patch(插件),用于修复芯片存在的 bug,或者
用于增加新的功能。 VS10XX 的 patch 其实就是一段可以在 VS10XX 芯片上面执行的代码,
由 VLSI 官方提供, 可以在: http://www.vlsi.fi/en/support/software/vs10xxpatches.html 这个地
址下载到。
patch 一般有 2 种格式:一种是采用 16 位无符号数组存储的, 是采用了游程编码(RLE)
压缩算法,进行过压缩的格式。另外一种,是直接采用 2 个 8 位数组存储的, 没有进行压缩
的格式。
推荐采用 16 位无符号存储格式的 patch,更省空间。 VS1053 采用的 16 位 RLE 压缩编
码规则如下:
1, 首先读寄存器地址 addr(第 1 个数据)和重复数 n(第 2 个数据)。
2, 如果 n&0X8000 为真,那么将下一个数据(第 3 个数据)重复写 n 次到寄存器 addr。
3, 如果 n&0X8000 为假,则写接下来的(第 3 个数据开始) n 个数据到寄存器 addr。
4, 重复以上 3 步,直到数组结束。
如 VS1053, WAV 录音无数据输出的 bug,修正 patch 如下:
//VS1053 的 WAV 录音有 bug,这个 plugin 可以修正这个问题
const u16 wav_plugin[40]=/* Compressed plugin */
{
0x0007, 0x0001, 0x8010, 0x0006, 0x001c, 0x3e12, 0xb817, 0x3e14, /* 0 */
0xf812, 0x3e01, 0xb811, 0x0007, 0x9717, 0x0020, 0xffd2, 0x0030, /* 8 */
0x11d1, 0x3111, 0x8024, 0x3704, 0xc024, 0x3b81, 0x8024, 0x3101, /* 10 */
0x8024, 0x3b81, 0x8024, 0x3f04, 0xc024, 0x2808, 0x4800, 0x36f1, /* 18 */
0x9811, 0x0007, 0x0001, 0x8028, 0x0006, 0x0002, 0x2a00, 0x040e,
};
根据前面提到的原则,得到: addr=0X0007, n=0X0001,即将接下来的 0X8010 写入寄
存器 0X0007 即可,之后: addr=0X0006, n=0X001C,即将接下来的 28 个数据,写入寄存
器 0X0006。后续的以此类推。
因此,我们可以得出 patch 加载函数(即 RLE 解压):
//vs10xx 装载 patch.
//patch: patch 首地址
//len: patch 长度
void VS_Load_Patch(u16 *patch,u16 len)
{
u16 i; u16 addr, n, val;
for(i=0;i<len;)
{
addr = patch[i++];
n = patch[i++];
if(n & 0x8000U) //RLE run, replicate n samples
{
n &= 0x7FFF;
val = patch[i++];
while(n--)VS_WR_Cmd(addr, val);//重复写入 N 次
}else //copy run, copy n sample
{
while(n--) //写入接下来的 N 个数据
{
val = patch[i++];
VS_WR_Cmd(addr, val);
}
}
}
}
我们只需要将 patch 存储在程序里面,然后调用 VS_Load_Patch,就可以将 patch 加载
到 VS1053 里面,这样便可以修复 VS1053 的 bug(如: WAV 录音的时候,不输出数据流的
bug),或者添加新的功能(如:支持播放 flach、支持频谱显示等)。
得到MP3的播放时间 n sec:
u16 n = VS_RD_Reg(SPI_DECODE_TIME);
n是个累加值
可以通过写0,重设解码时间:
void VS_Reset_DecodeTime(void)
{
VS_WR_Cmd(SPI_DECODE_TIME,0x0000);
VS_WR_Cmd(SPI_DECODE_TIME,0x0000);//操作两次
}
我们需要在每首歌播放之前把它清空一下,以得到这首歌的准确
解码时间 。
读取VS1053B ram 值的方法:
-
- 先把地址写到 SPI_WRAMADDR里,
- 再从SPI_WRAM读取数据。即是从ram 的 addr 出读取数据。
VS_WR_Cmd(SPI_WRAMADDR, addr);
res=VS_RD_Reg(SPI_WRAM);
设置音频的播放速度:
//设置播放速度
//t:0,1,正常速度;2,2倍速度;3,3倍速度;4,4倍速
void VS_Set_Speed(u8 t)
{
VS_WR_Cmd(SPI_WRAMADDR,0X1E04); //速度控制地址
while(VS_DQ==0); //等待空闲
VS_WR_Cmd(SPI_WRAM,t); //写入播放速度
}
正弦测试:
-
- 硬件复位
- 设置音量
- 设置测试模式
- 发送测试指令 0x53 0xef 0x6e n 0x00 0x00 0x00 0x00
- 发送退出测试指令 0x45 0x78 0x69 0x74 0x00 0x00 0x00 0x00
Ram 测试:
-
- 硬件复位
- 设置音量
- 设置测试模式
- 发送测试指令 0x4d 0xea 0x6d 0x54 0x00 0x00 0x00 0x00
- 读取 SPI_HDAT0的值, 如果值为0x83FF,则表明RAM完好。
VS1053B要实现的功能:
获取码率,获取歌曲的时长。
切换歌曲(datasheet 取消播放)
设置功能:设置音量,设置高低频率,高低增益,空间效果等等。
装载patch
总结:VS1053是一款高性能编解码芯片。可解码,也可编码。
通过SPI 传输音频数据 和 命令。
传输数据的时候,使用的是SDI协议格式,
传输命令的时候,使用的是SCI传输格式。
通过SCI传输一些命令,能更改SCI的7个寄存器的值,从而修改这颗芯片的工作模式,工作时钟,功能模式(高低音,音效,音量等等。),读取ram的值,获取音频速率等等。
通过SDI模式,发送音频数据。
VS1053B工作的流程:
1.复位VS1053B
2.配置SCI的寄存器。比如音量,音效,时钟,模式等等。
3. 打需要的补丁。
4. 在DREQ为高有效的时候,进行ram ,正弦的测试。测试通过后,开始发送音频数据。
只要通过SPI接口给VS1053B传输音频数据,它就可以自动的完成解码功能。具体细节查看datasheet.
使用解码芯片需要注意的点:
-
驱动音频接口,去传输音频。
-
驱动控制接口去,配置解码芯片。(音频和控制接口,有可能硬件口是一个。有可能是分开的。)
-
配置解码芯片的项目:音量,音效等等。
-
获取信息:获取一首歌的总时间 和 播放时间等等
-
测试:通过一些测试项,去测试硬件。