音频解码芯片VS1503音频解码芯片的应用
Posted 喜暖知寒
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了音频解码芯片VS1503音频解码芯片的应用相关的知识,希望对你有一定的参考价值。
😃 因为学习播放 mp3 用到了 VS1503,故对其命令、寄存器以及编程代码进行分析。
那种杂七杂八的就不介绍了,又没啥用,介绍一堆以后连看都不看!
我真的累了啊 ~ 为了学音乐播放器居然要看这么老多东西!!!!!
啊啊啊啊啊!都搞懂了吗?????
VS1503
支持的音频解码:Ogg Vorbis, MP3, AAC, WMA and WAV PCM + ADPCM
拥有一个高性能的DSP处理器核VS_DSP,16K的指令RAM,0.5K的数据RAM,通过SPI控制,具有8个可用的通用IO口和一个串口,芯片内部还带了一个可变采样率的立体声ADC(支持咪头或线路输入)、一个高性能立体声DAC及音频耳机放大器。
- 支持音量调节、高低音控制和EarSpeaker空间效果。
- 自带耳机驱动器,可驱动30 欧负载的耳机。
- 自带8个GPIO,可用于控制外设/作为I2S接口(外接DAC )。
- 可通过加载patch,实现新功能添加。
VS1053通过SPI接口来接受输入的音频数据流,它可以是一个从机,也可以作为独立的机。
通过SPI口向VS1053不停的输入音频数据,它就会自动解码(硬解)
采用VS1002本地模式(新模式)进行控制!
VS1053的SPI数据传送,分为SDI和SCI,分别用来传输数据/命令。SDI采用SPI协议,不过,数据传输受DREQ控制,主机在判断DREQ有效(高电平)之后,直接发送数据即可(一次可以发送32个字节)。
要接的线:(就是通过SPI协议控制的)
名称 | 说明 | 解释 |
---|---|---|
XCS | 片选输入(低电平有效) | 命令片选(低电平有效) |
XDCS | 数据片选/字节同步 | 数据片选(低电平有效) |
SCK | SPI时钟总线 | SPI信号线 |
SI | SPI数据输入线 | SPI信号线 |
SO | SPI数据输出线 | SPI信号线 |
DREQ | 数据请求 | 数据请求信号(高电平有效),通知单片机VS1053是否可以接收数据 |
RST | 复位(低电平有效) | 复位信号线,低电平有效 |
SCI串行总线
SCI串行总线命令接口包含了一个指令字节、一个地址字节和一个16位的数据字。读写操作可以读写单个寄存器,在SCK的上升沿读出数据位,所以主机必须在下降沿刷新数据。SCI的字节数据总是高位在前低位在后的。第一个字节指令字节,只有2个指令,也就是读和写,读为0X03,写为0X02。
写指令为:0X02,数据通过SI写入VS1053, SO则一直维持低电平。
注意:在读和写时序图中,DREQ信号上都产生了一个短暂的低脉冲,也就是执行时间,在写入和读出VS1053的数据之后,它需要一些时间来处理内部的事情,这段时间,是不允许外部打断的。所以,在SCI操作之前,最好判断一下DREQ是否为高电平,如果不是,则等待DREQ变为高。
VS1053寄存器
😶 VS1053有16个寄存器,啊 ~ 挺多!
写入每个寄存器的值就可以执行特定的操作!具体功能可参照数据手册
1、MODE寄存器(0X00)
SM_RESET(0000 0000 0000 0010):软件复位,建议在每播放一首歌曲之后,软复位一次。
SM_SDINEW(0000 1000 0000 0000):模式设置位,设置为1,选择VS1002新模式(本地模式)。
2、BASS寄存器(0X02)
该寄存器可以用于设置VS1053的高低音效,通过这个寄存器以上位的一些设置,我们可以随意配置自己喜欢的音效(其实就是高低音的调节)。
注意:EarSpeaker效果由MODE寄存器控制。
3、CLOCKF寄存器(0X03)
该寄存器用来设置时钟频率、倍频等相关信息。其中:SC_FREQ是以4Khz为步进的一个时钟寄存器,当外部时钟是12.288M的时候,设置为0即可。
XTALI是外部晶振的时钟频率(单位为:Hz )。CLKI是内部时钟频率。由于我们使用的是12.288M的晶振,在这里设置此寄存器的值为0X9800,也就是设置内部时钟频率为输入时钟频率的3倍,倍频增量为1.5倍。
4、DECODE_TIME寄存器(0X04)
该寄存器是一个存放解码时间的寄存器,以秒钟为单位,我们通过读取该寄存器的值,就可以得到解码时间。不过,它是一个累计时间,在每首歌播放之前,需要把它清空一下,以得到这首歌的准确解码时间。
5、HDAT0&HDAT1寄存器(0X08&0X09)
这两个寄存器,是数据流头寄存器,不同的音频文件,读出来的值意义不一样,我们可以通过这两个寄存器来获取音频文件的码率,从而可以计算音频文件的总长度。
6、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变高,直到音频数据发送完
寄存器定义
//写命令
#define VS_WRITE_COMMAND 0x02
//读命令
#define VS_READ_COMMAND 0x03
//SPI寄存器的定义
#define SPI_MODE 0x00
#define SPI_STATUS 0x01
#define SPI_BASS 0x02
#define SPI_CLOCKF 0x03
#define SPI_DECODE_TIME 0x04
#define SPI_AUDATA 0x05
#define SPI_WRAM 0x06
#define SPI_WRAMADDR 0x07
#define SPI_HDAT0 0x08
#define SPI_HDAT1 0x09
#define SPI_AIADDR 0x0a
#define SPI_VOL 0x0b
#define SPI_AICTRL0 0x0c
#define SPI_AICTRL1 0x0d
#define SPI_AICTRL2 0x0e
#define SPI_AICTRL3 0x0f
//关于SCI_MODE每位功能的定义
#define SM_DIFF 0x01
#define SM_JUMP 0x02
#define SM_RESET 0x04
#define SM_OUTOFWAV 0x08
#define SM_PDOWN 0x10
#define SM_TESTS 0x20
#define SM_STREAM 0x40
#define SM_PLUSV 0x80
#define SM_DACT 0x100
#define SM_SDIORD 0x200
#define SM_SDISHARE 0x400
#define SM_SDINEW 0x800
#define SM_ADPCM 0x1000
#define SM_ADPCM_HP 0x2000
//这几个没弄明白
#define I2S_CONFIG 0XC040
#define GPIO_DDR 0XC017
#define GPIO_IDATA 0XC018
#define GPIO_ODATA 0XC019
配置结构体定义
其中,__packed 起到字节对齐的作用。因为正点原子的开发板还带有喇叭,故还有个喇叭控制。
__packed typedef struct
u8 mvol; //主音量,范围:0~254
u8 bflimit; //低音频率限定,范围:2~15(单位:10Hz)
u8 bass; //低音,范围:0~15.0表示关闭.(单位:1dB)
u8 tflimit; //高音频率限定,范围:1~15(单位:Khz)
u8 treble; //高音,范围:0~15(单位:1.5dB)(原本范围是:-8~7,通过函数修改了);
u8 effect; //空间效果设置.0,关闭;1,最小;2,中等;3,最大.
u8 speakersw; //板载喇叭开关,0,关闭;1,打开
u8 saveflag; //保存标志,0X0A,保存过了;其他,还从未保存
_vs10xx_obj;
两家的代码出奇的一致!是官方例程吗?还是互相抄袭??
接口的定义
#define VS_DREQ_IN GPIO_ReadInputDataBit(VS_GPIO_DREQ_PORT,VS_DREQ)
#define VS_XDCS_SET GPIO_SetBits(VS_GPIO_XDCS_PORT,VS_XDCS)
#define VS_XDCS_CLR GPIO_ResetBits(VS_GPIO_XDCS_PORT,VS_XDCS)
#define VS_XCS_SET GPIO_SetBits(VS_SPIGPIO_PORT,VS_XCS)
#define VS_XCS_CLR GPIO_ResetBits(VS_SPIGPIO_PORT,VS_XCS)
#define VS_RST_SET GPIO_SetBits(VS_GPIO_RST_PORT,VS_RST)
#define VS_RST_CLR GPIO_ResetBits(VS_GPIO_RST_PORT,VS_RST)
控制VS1053的函数
其中,需要说明:SPI用的是STM32硬件SPI。
1、读寄存器:VS_RD_Reg(u8 address)
//读VS10XX的寄存器
//address:寄存器地址
//返回值:读到的值
//注意不要用倍速读取,会出错
u16 VS_RD_Reg(u8 address)
u16 temp=0;
while(VS_DREQ_IN==0); //非等待空闲状态
/*
* DREQ为高电平的时候,VS1053B可接受最少32字节的数据。
* DREQ为低电平,不能向VS1053B发送数据。
*/
VS_SPI_SpeedLow(); //SPI低速模式
VS_XDCS_SET; //置XDCS为1
VS_XCS_CLR; //置XCS为0
VS_SPI_ReadWriteByte(VS_READ_COMMAND); //发送VS10XX的读命令
VS_SPI_ReadWriteByte(address); //地址
temp=VS_SPI_ReadWriteByte(0xff); //读取高字节
temp=temp<<8;
temp+=VS_SPI_ReadWriteByte(0xff); //读取低字节
VS_XCS_SET; //置XCS为1
VS_SPI_SpeedHigh(); //SPI低速模式
return temp;
2、读RAM:VS_WRAM_Read(u16 addr)
//读取VS10xx的RAM
//addr:RAM地址
//返回值:读到的值
u16 VS_WRAM_Read(u16 addr)
u16 res;
VS_WR_Cmd(SPI_WRAMADDR, addr); //写命令,SPI_WRAMADDR为RAM读写基地址寄存器
res=VS_RD_Reg(SPI_WRAM); //SPI_WRAM,RAM读写
return res;
3、写RAM:VS_WRAM_Write(u16 addr,u16 val)
//写VS10xx的RAM
//addr:RAM地址
//val:要写入的值
void VS_WRAM_Write(u16 addr,u16 val)
VS_WR_Cmd(SPI_WRAMADDR,addr); //写RAM地址
while(VS_DREQ_IN==0); //低电平不能写入
VS_WR_Cmd(SPI_WRAM,val); //写RAM值
4、写数据:VS_WR_Data(u8 data)
//向VS10XX写数据
//data:要写入的数据
void VS_WR_Data(u8 data)
VS_SPI_SpeedHigh(); //高速,对VS1003B,最大值不能超过36.864/4Mhz,这里设置为9M
VS_XDCS_CLR; //置XDCS为0
VS_SPI_ReadWriteByte(data); //SPI写数据接口
VS_XDCS_SET; //置XDCS为0
5、写命令:VS_WR_Cmd(u8 address,u16 data)
//向VS1053写命令
//address:命令地址
//data:命令数据
void VS_WR_Cmd(u8 address,u16 data)
while(VS_DREQ_IN==0); //等待空闲
VS_SPI_SpeedLow(); //低速
VS_XDCS_SET; //置XDCS为1
VS_XCS_CLR; //置XCS为0,片选
VS_SPI_ReadWriteByte(VS_WRITE_COMMAND); //发送VS10XX的写命令
VS_SPI_ReadWriteByte(address); //地址
VS_SPI_ReadWriteByte(data>>8); //发送高八位
VS_SPI_ReadWriteByte(data); //低八位
VS_XCS_SET; //置XCS为1,取消片选
VS_SPI_SpeedHigh(); //高速
6、硬复位:VS_HD_Reset(void)
//硬复位MP3
//返回1:复位失败;0:复位成功
u8 VS_HD_Reset(void)
u8 retry=0;
VS_RST_CLR; //复位置0
Delay_ms(20);
VS_XDCS_SET; //取消数据传输
VS_XCS_SET; //取消数据传输
VS_RST_SET; //复位置1
while(VS_DREQ_IN==0 && retry<200) //等待DREQ为高
retry++;
Delay_us(50);
;
Delay_ms(20);
if(retry>=200)return 1; //复位超过200*50us,复位失败
else return 0; //复位成功
7、软复位:VS_Soft_Reset(void)
//软复位VS10XX
void VS_Soft_Reset(void)
u8 retry=0;
while(VS_DREQ_IN==0); //等待软件复位结束
VS_SPI_ReadWriteByte(0Xff); //启动传输
retry=0;
while(VS_RD_Reg(SPI_MODE)!=0x0800) //读寄存器,软件复位,新模式,0x0800缺省值
VS_WR_Cmd(SPI_MODE,0x0804); //写寄存器MODE,软件复位,新模式
Delay_ms(2); //等待至少1.35ms
if(retry++>100)break;
while(VS_DREQ_IN==0); //等待软件复位结束
retry=0;
while(VS_RD_Reg(SPI_CLOCKF)!=0X9800) //设置VS1053的时钟,3倍频 ,1.5xADD
/*
* 0x8000:1000 0000 0000 0000 是3.5倍频啊
* 0x1800:0001 1000 0000 0000 是2.0乘数啊
* 也就是说,这个注释不对,可能原来的函数被修改了!!
*/
VS_WR_Cmd(SPI_CLOCKF,0X9800); //设置VS1053的时钟,3倍频 ,1.5xADD
if(retry++>100)break;
Delay_ms(20);
7、RAM测试函数:VS_Ram_Test(void)
用来确定VS1053是否正常工作
//ram 测试
//返回值:RAM测试结果
// VS1003如果得到的值为0x807F,则表明完好;VS1053为0X83FF
u16 VS_Ram_Test(void)
VS_HD_Reset(); //硬复位
VS_WR_Cmd(SPI_MODE,0x0820); //进入VS10XX的测试模式
while (VS_DREQ_IN==0); // 等待DREQ为高
VS_SPI_SpeedLow(); //低速
VS_XDCS_CLR; // XDCS = 0
VS_SPI_ReadWriteByte(0x4d);
VS_SPI_ReadWriteByte(0xea);
VS_SPI_ReadWriteByte(0x6d);
VS_SPI_ReadWriteByte(0x54);
VS_SPI_ReadWriteByte(0x00);
VS_SPI_ReadWriteByte(0x00);
VS_SPI_ReadWriteByte(0x00);
VS_SPI_ReadWriteByte(0x00);
Delay_ms(150);
VS_XDCS_SET; //XDCS = 1
return VS_RD_Reg(SPI_HDAT0);// VS1053如果得到的值为0x83FF,则表明完好;
8、正弦测试:VS_Sine_Test(void)
//正弦测试
void VS_Sine_Test(void)
VS_HD_Reset(); //硬复位
VS_WR_Cmd(0x0b,0X2020); //设置音量
VS_WR_Cmd(SPI_MODE,0x0820); //进入VS10XX的测试模式
while(VS_DREQ_IN==0); //等待DREQ为高
//printf("mode sin:%x\\n",VS_RD_Reg(SPI_MODE));
//向VS1053发送正弦测试命令:0x53 0xef 0x6e n 0x00 0x00 0x00 0x00
//其中n = 0x24, 设定VS1053所产生的正弦波的频率值,具体计算方法见VS1053的datasheet
VS_SPI_SpeedLow(); //低速
VS_XDCS_CLR; //选中数据传输
VS_SPI_ReadWriteByte(0x53);
VS_SPI_ReadWriteByte(0xef);
VS_SPI_ReadWriteByte(0x6e);
VS_SPI_ReadWriteByte(0x24);
VS_SPI_ReadWriteByte(0x00);
VS_SPI_ReadWriteByte(0x00);
VS_SPI_ReadWriteByte(0x00);
VS_SPI_ReadWriteByte(0x00);
Delay_ms(100);
VS_XDCS_SET;
//退出正弦测试
VS_XDCS_CLR;//选中数据传输
VS_SPI_ReadWriteByte(0x45);
VS_SPI_ReadWriteByte(0x78);
VS_SPI_ReadWriteByte(0x69);
VS_SPI_ReadWriteByte(0x74);
VS_SPI_ReadWriteByte(0x00);
VS_SPI_ReadWriteByte(0x00);
VS_SPI_ReadWriteByte(0x00);
VS_SPI_ReadWriteByte(0x00);
Delay_ms(100);
VS_XDCS_SET;
//再次进入正弦测试并设置n值为0x44,即将正弦波的频率设置为另外的值
VS_XDCS_CLR;//选中数据传输
VS_SPI_ReadWriteByte(0x53);
VS_SPI_ReadWriteByte(0xef);
VS_SPI_ReadWriteByte(0x6e);
VS_SPI_ReadWriteByte(0x44);
VS_SPI_ReadWriteByte(0x00);
VS_SPI_ReadWriteByte(0x00);
VS_SPI_ReadWriteByte(0x00);
VS_SPI_ReadWriteByte(0x00);
Delay_ms(100);
VS_XDCS_SET;
//退出正弦测试
VS_XDCS_CLR;//选中数据传输
VS_SPI_ReadWriteByte(0x45);
VS_SPI_ReadWriteByte(0x78);
VS_SPI_ReadWriteByte(0x69);
VS_SPI_ReadWriteByte(0x74);
VS_SPI_ReadWriteByte(0x00);
VS_SPI_ReadWriteByte(0x00);
VS_SPI_ReadWriteByte(0x00);
VS_SPI_ReadWriteByte(0x00);
Delay_ms(100);
VS_XDCS_SET;
9、设置SPI为高速模式:VS_SPI_SpeedHigh(void)
//设置到高速模式
//SPI设置接口函数
void VS_SPI_SpeedHigh(void)
SPI_SetSpeed(SPI_BaudRatePrescaler_8);
10、设置SPI为低速模式:VS_SPI_SpeedLow(void)
//设置到低速模式
//SPI设置接口函数
void VS_SPI_SpeedLow(void)
SPI_SetSpeed(SPI_BaudRatePrescaler_32); //SPI_SetSpeed可设置到SPI文件中
SPI1_SetSpeed(u8 SpeedSet)
void SPI1_SetSpeed(u8 SpeedSet)
assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));
SPI1->CR1&=0XFFC7;
SPI1->CR1|=SpeedSet;
SPI_Cmd(SPI1,ENABLE); //这是SPI1\\2之类的需要设置!!
11、SPI读写函数:VS_SPI_ReadWriteByte(u8 data)
//移植时候的接口
//data:要写入的数据
//返回值:读到的数据
u8 VS_SPI_ReadWriteByte(u8 data)
return SPI1_ReadWriteByte(data);
SPI1_ReadWriteByte(u8 TxData)
//SPIx 读写一个字节
//TxData:要写入的字节
//返回值:读取到的字节
u8 SPI1_ReadWriteByte(u8 TxData)
/* Loop while DR register in not emplty */
//检查指定的SPI标志位设置与否:发送缓存空标志位
while(SPI_I2S_GetFlagStatus(VS_SPI,SPI_I2S_FLAG_TXE) == RESET);
/* Send byte through the SPI1 peripheral */
//通过外设SPIx发送一个数据
SPI_I2S_SendData(VS_SPI, writedat);
/* Wait to receive a byte */
//检查指定的SPI标志位设置与否:接受缓存非空标志位
while(SPI_I2S_GetFlagStatus(VS_SPI, SPI_I2S_FLAG_RXNE) == RESET);
/* Return the byte read from the SPI bus */
//返回通过SPIx最近接收的数据
return SPI_I2S_ReceiveData(VS_SPI);数据
12、初始化VS10xx:VS_Init(void)
配置GPIO接口,配置SPI初始化。函数就不附了。
13、设置播放速度:VS_Set_Speed(u8 t)
//设置播放速度(仅VS1053有效)
//t:0,1,正常速度;2,2倍速度;3,3倍速度;4,4倍速;以此类推
void VS_Set_Speed(u8 t)
VS_WRAM_Write(0X1E04,t); //写入播放速度
14、得到码率(bps):VS_Get_HeadInfo(void)
码率在VS1053数据手册中解释了。MP3的码率是准的!!
//返回Kbps的大小
//返回值:得到的码率
u16 VS_Get_HeadInfo(void)
unsigned int HEAD0;
unsigned int HEAD1;
HEAD0=VS_RD_Reg(SPI_HDAT0);
HEAD1=VS_RD_Reg(SPI_HDAT1);
//printf("(H0,H1):%x,%x\\n",HEAD0,HEAD1);
switch(HEAD1)
case 0x7665://WAV格式
case 0X4D54://MIDI格式
case 0X4154://AAC_ADTS
case 0X4144://AAC_ADIF
case 0X4D34://AAC_MP4/M4A
case 0X4F67://OGG
case 0X574D://WMA格式
case 0X664C://FLAC格式
//printf("HEAD0:%d\\n",HEAD0);
HEAD1=HEAD0*2/25;//相当于*8/100
if((HEAD1%10)>5)return HEAD1/10+1;//对小数点第一位四舍五入
else return HEAD1/10;
default://MP3格式,仅做了阶层III的表
HEAD1>>=3;
HEAD1=HEAD1&0x03;
if(HEAD1==3)HEAD1=1;
else HEAD1=0;
return bitrate[HEAD1][HEAD0>>12];
15、得到字节速率:VS_Get_ByteRate(void)
//得到平均字节数
//返回值:平均字节数速度
u32 VS_Get_ByteRate(void)
return VS_WRAM_Read(0X1E05); //读RAM,平均位速
16、得到填充字节:VS_Get_EndFillByte(void)
//得到需要填充的数字
//返回值:需要填充的数字
u16 VS_Get_EndFillByte(void)
return VS_WRAM_Read(0X1E06);//填充字节
17、向VS10xx发送32字节:VS_Send_MusicData(u8* buf)
//发送一次音频数据
//固定为32字节
//返回值:0,发送成功
// 1,VS10xx不缺数据,本次数据未成功发送
u8 VS_Send_MusicData(u8* buf)
u8 n;
if(VS_DREQ_IN!=0) //送数据给VS10XX
VS_XDCS_CLR;
for(n=0;n<32;n++)
VS_SPI_ReadWriteByte(buf[n]);
VS_XDCS_SET;
else return 1;
return 0;//成功发送了
18、重新开始下一首歌播放:VS_Restart_Play(void)
VS1053数据手册中也有提到!
这些定义之类的东西别问为什么!都是手册规定的!
//切歌
//通过此函数切歌,不会出现切换“噪声”
void VS_Restart_Play(void)
u16 temp;
u16 i;
u8 n;
u8 vsbuf[32];
for(n=0;n<32;n++)vsbuf[n]=0;//清零
temp=VS_RD_Reg(SPI_MODE); //读取SPI_MODE的内容
temp|=1<<3; //设置SM_CANCEL位
temp|=1<<2; //设置SM_LAYER12位,允许播放MP1,MP2
VS_WR_Cmd(SPI_MODE,temp); //设置取消当前解码指令
for(i=0;i<2048;) //发送2048个0,期间读取SM_CANCEL位.如果为0,则表示已经取消了当前解码
if(VS_Send_MusicData(vsbuf)==0)//每发送32个字节后检测一次
i+=32; //发送了32个字节
temp=VS_RD_Reg(SPI_MODE); //读取SPI_MODE的内容
if((temp&(1<<3))==0)break; //成功取消了
if(i<2048)//SM_CANCEL正常
temp=VS_Get_EndFillByte()&0xff;//读取填充字节
for(n=0;n<32;n++)vsbuf[n]=temp;//填充字节放入数组
for(i=0;i<2052;)
if(VS_Send_MusicData(vsbuf)==0)i+=32;//填充
else VS_Soft_Reset(); //SM_CANCEL不成功,坏情况,需要软复位
temp=VS_RD_Reg(SPI_HDAT0);
temp+=VS_RD_Reg(SPI_HDAT1);
if(temp) //软复位,还是没有成功取消,放杀手锏,硬复位
VS_HD_Reset(); //硬复位
VS_Soft_Reset(); //软复位
19、重设解码时间:VS_Reset_DecodeTime(void)
是累计计时的,每次切歌需要重置。
//重设解码时间
void VS_Reset_DecodeTime(void)
VS_WR_Cmd(SPI_DECODE_TIME,0x0000);
VS_WR_Cmd(SPI_DECODE_TIME,0x0000);//操作两次
20、得到解码时间:VS_Get_DecodeTime(void)
//得到mp3的播放时间n sec
//返回值:解码时长
u16 VS_Get_DecodeTime(void)
u16 dt=0;
dt=VS_RD_Reg(SPI_DECODE_TIME);
return dt;
21、加载用户patch:VS_Load_Patch(u16 *patch,u16 len)
说实话,没看懂。
//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);
else //copy run, copy n sample
while(n--)
val = patch[i++];
VS_WR_Cmd(addr, val);
22、设置主音量:VS_Set_Vol(u8 volx)
VS1053寄存器是值越小声音越大,但是习惯上是值越大声音越大,故取反一下!
//设定VS10XX播放的音量和高低音
//volx:音量大小(0~254)
void VS_Set_Vol(u8 volx)
u16 volt=0; //暂存音量值
volt=254-volx; //取反一下,得到最大值,表示最大的表示
volt<<=8;
volt+=254-volx; //得到音量设置后大小
VS_WR_Cmd(SPI_VOL,volt);//设音量
23、设置高低音:VS_Set_Bass(u8 bfreq,u8 bass,u8 tfreq,u8 treble)
//设定高低音控制
//bfreq:低频上限频率 2~15(单位:10Hz)
//bass:低频增益 0~15(单位:1dB)
//tfreq:高频下限频率 1~15(单位:Khz)
//treble:高频增益 0~15(单位:1.5dB,小于9的时候为负数)
void VS_Set_Bass(u8 bfreq,u8 bass,u8 tfreq,u8 treble)
u16 bass_set=0; //暂存音调寄存器值
signed char temp=0;
if(treble==0)temp=0; //变换
else if(treble>8)temp=treble-8;
else temp=treble-9;
bass_set=temp&0X0F; //高音设定
bass_set<<=4;
bass_set+=tfreq&0xf; //高音下限频率
bass_set<<=4;
bass_set+=bass&0xf; //低音设定
bass_set<<=4;
bass_set+=bfreq&0xf; //低音上限
VS_WR_Cmd(SPI_BASS,bass_set); //BASS
24、设置音效:VS_Set_Effect(u8 eft)
//设定音效
//eft:0,关闭;1,最小;2,中等;3,最大.
void VS_Set_Effect(u8 eft)
u16 temp;
temp=VS_RD_Reg(SPI_MODE); //读取SPI_MODE的内容
if(eft&0X01)temp|=1<<4; //设定LO
else temp&=~(1<<5); //取消LO
if(eft&0X02)temp|=1<<7; //设定HO
else temp&=~(1<<7); //取消HO
VS_WR_Cmd(SPI_MODE,temp); //设定模式
25、全部设置:VS_Set_All(void)
//设置音量,音效等.
void VS_Set_All(void)
VS_Set_Vol(vsset.mvol); //设置音量
VS_Set_Bass(vsset.bflimit,vsset.bass,vsset.tflimit,vsset.treble);
VS_Set_Effect(vsset.effect); //设置空间效果
就这些东西,只不过看手册也能写出来!
到这里就结束了,晚安啦各位!!
ES9023音频解码芯片原理及应用简介
一般来说,音频解码器分为两类,一类是用于Hi-Fi听音的纯音频解码器,即指把CD机等数字音源器材一分为二后,去掉转盘(驱动光碟旋转读盘)的部分。
纯音频解码器的主要作用是把读取的数字音频信息转换成模拟音频信号输出,供功率放大重放;因此严格说纯音频解码器应称作D/A(数字/模拟)转换器。另一类即AV影音解码器,即平常所说的在“家庭影院”设备中使用的解码器,主要作用是把录音时经过编码的多声道音频信息作解码还原,经D/A转换后供功率 放大重放。
解码芯片,它是解码器的心脏。目前为止深受国内发烧友及厂家喜好的莫过于由美国ESS公司生产的ES解码芯片系列;
由工采网代理的ES9023是美国ESS公司推出的一款24bit立体声音频数模转换芯片(DAC);该芯片采用了业界先进的SABRE数-模转换技术,集高音质、高性价比于一身;
(1)芯片内集成了电荷泵可以产生负电压;可以在单电源供电下参考地线直接输出2Vrms,免除了直流电压隔离的耦合电容。
(2)输出幅度可以根据实际需要,通过电阻来设置小于2Vrms水平;开关机噪声也得以全面抑制。
(3)专用的控制/状态引脚可以允许在没有单片机控制的情况下容易集成到系统中。
(4)内部使用专利技术的超线流(Hyperstream)架构和时域抖动消除技术,使之可以实现无抖动录音级别的音质,动态范围达到了112dB。
(5)采用单独的解码器在搭配上更选择灵活方式更多,而解码功能整合在其它器材中则在连接、操作的使用上更方便简捷。
ES9023是ESS公司推出的单端输出DAC芯片,也是他们的SABRE DAC系列里很独特、简洁的一款,公认为是最容易出好声的解码芯片。
可以应用在:蓝光播放器、CD/DVD、高清机顶盒、数字电视或音频接收设备等产品。
美国ESS DAC芯片 - ES9023特性:
1)Sabre DAC和2Vrms运算放大器驱动器
2)获得专利的HyperStreamTM和JitterElimination架构
3)可调输出电平;地面参考输出
4)专用控制/状态引脚:I2S或左对齐选择;软静音启用;零检测输出
5)提供负极电源的充电泵;16-SOP低功耗
6)允许设计人员自定义输出级别(最多2Vrms)
7)易于使用-不需要编程;单个AVCC简化了供电
8)无popfree开机/关机,静音和复位
以上是关于音频解码芯片VS1503音频解码芯片的应用的主要内容,如果未能解决你的问题,请参考以下文章