📄 vs1003.h
字号:
#define VS_XDCS_H GPIOA->BSRR=1<<4
#define VS_XDCS_L GPIOA->BRR=1<<4
#define VS_XCS_H GPIOA->BSRR=1<<8
#define VS_XCS_L GPIOA->BRR=1<<8
#define VS_RST_H GPIOA->BSRR=1<<11
#define VS_RST_L GPIOA->BRR=1<<11
#define VS_DQ (GPIOA->IDR&(1<<12))
#define VS_WRITE_COMMAND 0x02 //写命令
#define VS_READ_COMMAND 0x03 //读命令
//VS10XX寄存器定义
#define SPI_MODE 0x00 //模式控制
#define SPI_STATUS 0x01 //VS10XX的状态寄存器
#define SPI_BASS 0x02 //高低音控制
#define SPI_CLOCKF 0x03 //时钟频率倍乘寄存器
#define SPI_DECODE_TIME 0x04 //解码时间长度
#define SPI_AUDATA 0x05 //各种音频数据
#define SPI_WRAM 0x06 //RAM 写/读
#define SPI_WRAMADDR 0x07 //RAM 写/读的起始地址
#define SPI_HDAT0 0x08 //流数据标头0
#define SPI_HDAT1 0x09 //流数据标头1
#define SPI_AIADDR 0x0a //应用程序的起始地址
#define SPI_VOL 0x0b //音量控制
#define SPI_AICTRL0 0x0c //应用程序控制寄存器0
#define SPI_AICTRL1 0x0d //应用程序控制寄存器1
#define SPI_AICTRL2 0x0e //应用程序控制寄存器2
#define SPI_AICTRL3 0x0f //应用程序控制寄存器3
//SPI_MODE的各位功能,下表根据VS1053的手册标注
#define SM_DIFF 0x01 //差分
#define SM_LAYER12 0x02 //允许MPEG 1,2解码 FOR vs1053
#define SM_RESET 0x04 //软件复位
#define SM_CANCEL 0x08 //取消当前解码
#define SM_EARSPEAKER_LO 0x10 //EarSpeaker低设定
#define SM_TESTS 0x20 //允许SDI测试
#define SM_STREAM 0x40 //流模式
#define SM_EARSPEAKER_HI 0x80 //EarSpeaker高设定
#define SM_DACT 0x100 //DCLK的有效边沿
#define SM_SDIORD 0x200 //SDI位顺序
#define SM_SDISHARE 0x400 //共享SPI片选
#define SM_SDINEW 0x800 //VS1002 本地SPI模式
#define SM_ADPCM 0x1000//ADPCM录音激活
#define SM_LINE1 0x4000//咪/线路1 选择
#define SM_CLK_RANGE 0x8000//输入时钟范围
u8 VS10XXram[5]={0,0,0,0,230};
//向VS10XX写命令
//address:命令地址
//data:命令数据
void VS_WR_Cmd(u8 address,u16 data)
{
u16 retry=0;
while(VS_DQ==0&&(retry++)<0xfffe)retry++; //等待空闲
SPIx_SetSpeed(SPI_SPEED_64); //64分频速度
VS_XDCS_H;
VS_XCS_L;
SPIx_ReadWriteByte(VS_WRITE_COMMAND);//发送VS10XX的写命令
SPIx_ReadWriteByte(address); //地址
SPIx_ReadWriteByte(data>>8); //发送高八位
SPIx_ReadWriteByte(data); //第八位
VS_XCS_H;
SPIx_SetSpeed(SPI_SPEED_8); //8分频速度
}
//软复位VS10XX
//注意,在这里设置完后,系统SPI时钟被修改成9M左右
void VS_Soft_Reset(void)
{
u8 retry;
SPIx_SetSpeed(SPI_SPEED_256); //256分频 超低速 281.25Khz
while(VS_DQ==0); //等待空闲
SPIx_ReadWriteByte(0X00); //启动传输
retry=0;
VS_WR_Cmd(SPI_MODE,0x0804); //软件复位,新模式
while(VS_DQ==0&&retry<200) //等待DREQ为高
{
retry++;
delay_us(50);
};
retry=0;
VS_WR_Cmd(SPI_CLOCKF,0X9800); //设置VS10XX的时钟,3.5倍频 ,2xADD
//向VS10XX发送4个字节无效数据,用以启动SPI发送
SPIx_SetSpeed(SPI_SPEED_8); //8分频速度
VS_XDCS_L; //选中数据传输 记得,这里一定要传送0X00
SPIx_ReadWriteByte(0X0);
SPIx_ReadWriteByte(0X0);
SPIx_ReadWriteByte(0X0);
SPIx_ReadWriteByte(0X0);
VS_XDCS_H; //取消数据传输
}
//硬复位MP3
//返回1:复位失败
//返回0:复位成功
u8 VS_HD_Reset(void)
{
u8 retry=0;
VS_XDCS_H; //取消数据传输
VS_XCS_H; //取消指令传输
VS_RST_L;
delay_ms(100);
VS_RST_H;
while(VS_DQ==0&&retry<200)//等待DREQ为高
{
retry++;
delay_us(50);
};
delay_ms(20);
if(retry>=200)return 1;
else return 0;
}
//向VS10XX写数据
void VS_WR_Data(u8 data)
{
VS_XDCS_L;
SPIx_ReadWriteByte(data);
VS_XDCS_H;
}
//读VS10XX的寄存器
//注意不要用倍速读取,会出错
u16 VS_RD_Reg(u8 address)
{
u16 temp=0;
u8 retry=0;
while(VS_DQ==0&&(retry++)<0XFE); //等待空闲
if(retry>=0XFE)return 0;
SPIx_SetSpeed(SPI_SPEED_64); //64分频速度
VS_XDCS_H;
VS_XCS_L;
SPIx_ReadWriteByte(VS_READ_COMMAND);//发送VS10XX的读命令
SPIx_ReadWriteByte(address); //地址
temp=SPIx_ReadWriteByte(0xff); //读取高字节
temp=temp<<8;
temp+=SPIx_ReadWriteByte(0xff); //读取低字节
VS_XCS_H;
SPIx_SetSpeed(SPI_SPEED_8); //8分频速度
return temp;
}
//读取VS10XX的RAM
u16 VS_RD_Wram(u16 addr)
{
VS_WR_Cmd(SPI_WRAMADDR, addr);
return VS_RD_Reg(SPI_WRAM);
}
//FOR WAV HEAD0 :0X7761 HEAD1:0X7665
//FOR MIDI HEAD0 :other info HEAD1:0X4D54
//FOR WMA HEAD0 :data speed HEAD1:0X574D
//FOR MP3 HEAD0 :data speed HEAD1:ID
//比特率预定值
const u16 bitrate[2][16]=
{
{0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,0},
{0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}
};
//返回Kbps的大小
//得到mp3&wma的波特率
u16 VS_Get_HeadInfo(void)
{
unsigned int HEAD0;
unsigned int HEAD1;
HEAD0=VS_RD_Reg(SPI_HDAT0);
HEAD1=VS_RD_Reg(SPI_HDAT1);
switch(HEAD1)
{
case 0x7665:return 0; //WAV格式
case 0X4D54: //MIDI格式
case 0X4154: //AAC_ADTS
case 0X4144: //AAC_ADIF
case 0X4D34: //AAC_MP4/M4A
case 0X4F67: //OGG
case 0X574D: //WMA格式
{
////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格式
{
HEAD1>>=3;
HEAD1=HEAD1&0x03;
if(HEAD1==3)HEAD1=1;
else HEAD1=0;
return bitrate[HEAD1][HEAD0>>12];
}
}
}
//重设解码时间
void VS_Rst_DecodeTime(void)
{
VS_WR_Cmd(SPI_DECODE_TIME,0x0000);
VS_WR_Cmd(SPI_DECODE_TIME,0x0000);//操作两次
}
//得到mp3的播放时间n sec
u16 VS_Get_DecodeTime(void)
{
return VS_RD_Reg(SPI_DECODE_TIME);
}
//设定VS10XX播放的音量和高低音
void set10XX(void)
{
u8 t;
u16 bass=0; //暂存音调寄存器值
u16 volt=0; //暂存音量值
u8 vset=0; //暂存音量值
vset=255-VS10XXram[4];//取反一下,得到最大值,表示最大的表示
volt=vset;
volt<<=8;
volt+=vset;//得到音量设置后大小
//0,henh.1,hfreq.2,lenh.3,lfreq
for(t=0;t<4;t++)
{
bass<<=4;
bass+=VS10XXram[t];
}
VS_WR_Cmd(SPI_BASS,bass);//BASS
VS_WR_Cmd(SPI_VOL,volt); //设音量
}
//初始化VS10XX的IO口
void VS_Init(void)
{
RCC->APB2ENR|=1<<2; //PORTA时钟使能
GPIOA->CRL&=0XFFF0FFFF; //PA4 XDCS
GPIOA->CRL|=0X00030000;
GPIOA->CRH&=0XFFF00FF0; //PA8 XCS;PA11 DQ;PA12 RST
GPIOA->CRH|=0X00083003;
GPIOA->ODR|=(1<<4)|(1<<8)|(1<<11)|(1<<12); //PA4,8,11,12上拉
SPIx_Init(); //初始化SPI
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -