⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vs10xx.c

📁 STM32不完全手册 例程源码 29个
💻 C
字号:
#include "vs10XX.h"	
#include "delay.h"
#include "mmc_sd.h"
#include "spi.h"
#include "usart.h"
	
#include "spec_rew.h"
 
//VS10XX的全功能函数
//支持SIN测试和RAM测试
//并加入了VS10XX的频谱显示代码,不过说实话不咋地,还不如自己写的频谱分析,怀疑是不是真实的频谱变换?  
//正点原子@SCUT
//V1.1

//VS10XX设置参数
//0,高音控制;1,最低频限;2,低音控制;3,最低频限
//0,henh.1,hfreq.2,lenh.3,lfreq 5,主音量
u8 VS10XXram[5]={0,0,0,0,250};
 	 	  
//软复位VS10XX
void VS_Soft_Reset(void)
{	 
	u8 retry;  				   
	while(VS_DQ==0);//等待软件复位结束
	SPIx_ReadWriteByte(0Xff);//启动传输
	retry=0;
	while(VS_RD_Reg(SPI_MODE)!=0x0800)// 软件复位,新模式  
	{
		VS_WR_Cmd(SPI_MODE,0x0804);// 软件复位,新模式	    
		delay_ms(2);//等待至少1.35ms 
		if(retry++>100)break; 	    
	}	 				  
	while(VS_DQ==0);//等待软件复位结束	 

	retry=0;
	while(VS_RD_Reg(SPI_CLOCKF)!=0X9800)//设置VS10XX的时钟,3倍频 ,1.5xADD 
	{
		VS_WR_Cmd(SPI_CLOCKF,0X9800);//设置VS10XX的时钟,3倍频 ,1.5xADD
		if(retry++>100)break; 	    
	}		    			
//	while(VS_RD_Reg(SPI_AUDATA)!=0XBB81)//设置VS10XX的时钟,3倍频 ,1.5xADD 
//	{
//		VS_WR_Cmd(SPI_AUDATA,0XBB81);
//		if(retry++>100)break; 
//	}  
	//VS_WR_Cmd(SPI_CLOCKF,0X9800); 	    
	//VS_WR_Cmd(SPI_AUDATA,0XBB81); //采样率48k,立体声	     
    //向VS10XX发送4个字节无效数据,用以启动SPI发送
    VS_XDCS=0;//选中数据传输
	SPIx_ReadWriteByte(0XFF);
	SPIx_ReadWriteByte(0XFF);
	SPIx_ReadWriteByte(0XFF);
	SPIx_ReadWriteByte(0XFF);
	VS_XDCS=1;//取消数据传输
	delay_ms(20);
} 
//硬复位MP3
//返回1:复位失败
//返回0:复位成功
u8 VS_HD_Reset(void)
{
	u8 retry=0;
	VS_RST=0;
	delay_ms(20);
	VS_XDCS=1;//取消数据传输
	VS_XCS=1;//取消数据传输
	VS_RST=1;	   
	while(VS_DQ==0&&retry<200)//等待DREQ为高
	{
		retry++;
		delay_us(50);
	};
	delay_ms(20);	
	if(retry>=200)return 1;
	else return 0;	    		 
}
//正弦测试 
void VS_Sine_Test(void)
{											    
	VS_HD_Reset();	 
	VS_WR_Cmd(0x0b,0X2020);	  //设置音量	 
 	VS_WR_Cmd(SPI_MODE,0x0820);//进入VS10XX的测试模式     
	while(VS_DQ== 0);     //等待DREQ为高
	//printf("mode sin:%x\n",VS_RD_Reg(SPI_MODE));
 	//向VS10XX发送正弦测试命令:0x53 0xef 0x6e n 0x00 0x00 0x00 0x00
 	//其中n = 0x24, 设定VS10XX所产生的正弦波的频率值,具体计算方法见VS10XX的datasheet
  	SPIx_SetSpeed(SPI_SPEED_64);//低速 
	VS_XDCS=0;//选中数据传输
	SPIx_ReadWriteByte(0x53);
	SPIx_ReadWriteByte(0xef);
	SPIx_ReadWriteByte(0x6e);
	SPIx_ReadWriteByte(0x24);
	SPIx_ReadWriteByte(0x00);
	SPIx_ReadWriteByte(0x00);
	SPIx_ReadWriteByte(0x00);
	SPIx_ReadWriteByte(0x00);
	delay_ms(100);
	VS_XDCS=1; 
    //退出正弦测试
    VS_XDCS=0;//选中数据传输
	SPIx_ReadWriteByte(0x45);
	SPIx_ReadWriteByte(0x78);
	SPIx_ReadWriteByte(0x69);
	SPIx_ReadWriteByte(0x74);
	SPIx_ReadWriteByte(0x00);
	SPIx_ReadWriteByte(0x00);
	SPIx_ReadWriteByte(0x00);
	SPIx_ReadWriteByte(0x00);
	delay_ms(100);
	VS_XDCS=1;		 

    //再次进入正弦测试并设置n值为0x44,即将正弦波的频率设置为另外的值
    VS_XDCS=0;//选中数据传输      
	SPIx_ReadWriteByte(0x53);
	SPIx_ReadWriteByte(0xef);
	SPIx_ReadWriteByte(0x6e);
	SPIx_ReadWriteByte(0x44);
	SPIx_ReadWriteByte(0x00);
	SPIx_ReadWriteByte(0x00);
	SPIx_ReadWriteByte(0x00);
	SPIx_ReadWriteByte(0x00);
	delay_ms(100);
	VS_XDCS=1;
    //退出正弦测试
    VS_XDCS=0;//选中数据传输
	SPIx_ReadWriteByte(0x45);
	SPIx_ReadWriteByte(0x78);
	SPIx_ReadWriteByte(0x69);
	SPIx_ReadWriteByte(0x74);
	SPIx_ReadWriteByte(0x00);
	SPIx_ReadWriteByte(0x00);
	SPIx_ReadWriteByte(0x00);
	SPIx_ReadWriteByte(0x00);
	delay_ms(100);
	VS_XDCS=1;	 
}	 
//ram 测试 																				 
void VS_Ram_Test(void)
{
 	u16 regvalue ;	   
	VS_HD_Reset();     
 	VS_WR_Cmd(SPI_MODE,0x0820);// 进入VS10XX的测试模式
	while (VS_DQ==0); // 等待DREQ为高			   
 	SPIx_SetSpeed(SPI_SPEED_64);//低速 
	VS_XDCS=0;	       		    // xDCS = 1,选择VS10XX的数据接口
	SPIx_ReadWriteByte(0x4d);
	SPIx_ReadWriteByte(0xea);
	SPIx_ReadWriteByte(0x6d);
	SPIx_ReadWriteByte(0x54);
	SPIx_ReadWriteByte(0x00);
	SPIx_ReadWriteByte(0x00);
	SPIx_ReadWriteByte(0x00);
	SPIx_ReadWriteByte(0x00);
	delay_ms(50);  
	VS_XDCS=1;
	regvalue=VS_RD_Reg(SPI_HDAT0); // 如果得到的值为0x807F,则表明完好。
	printf("regvalueH:%x\n",regvalue);//输出结果 	   
}     					   
//向VS10XX写命令
//address:命令地址
//data:命令数据
void VS_WR_Cmd(u8 address,u16 data)
{  
    while(VS_DQ==0);//等待空闲
	SPIx_SetSpeed(SPI_SPEED_64);//低速 

	VS_XDCS=1; //MP3_DATA_CS=1;
	VS_XCS=0; //MP3_CMD_CS=0; 
	
	SPIx_ReadWriteByte(VS_WRITE_COMMAND);//发送VS10XX的写命令
	SPIx_ReadWriteByte(address); //地址
	SPIx_ReadWriteByte(data>>8); //发送高八位
	SPIx_ReadWriteByte(data);	 //第八位
	VS_XCS=1;          //MP3_CMD_CS=1; 
	SPIx_SetSpeed(SPI_SPEED_8);//高速	   
} 
//向VS10XX写数据
void VS_WR_Data(u8 data)
{
	SPIx_SetSpeed(SPI_SPEED_8);//高速,对VS1003B,最大值不能超过36.864/4Mhz,这里设置为9M 
	VS_XDCS=0;   //MP3_DATA_CS=0;
	SPIx_ReadWriteByte(data);
	VS_XDCS=1;   //MP3_DATA_CS=1;   
}         
//读VS10XX的寄存器           
//读VS10XX
//注意不要用倍速读取,会出错
u16 VS_RD_Reg(u8 address)
{ 
	u16 temp=0; 
    while(VS_DQ==0);//非等待空闲状态 
	SPIx_SetSpeed(SPI_SPEED_64);//低速 
	VS_XDCS=1;       //MP3_DATA_CS=1;
	VS_XCS=0;        //MP3_CMD_CS=0;
	SPIx_ReadWriteByte(VS_READ_COMMAND);//发送VS10XX的读命令
	SPIx_ReadWriteByte(address);        //地址
	temp=SPIx_ReadWriteByte(0xff);		//读取高字节
	temp=temp<<8;
	temp+=SPIx_ReadWriteByte(0xff); 	//读取低字节
	VS_XCS=1;      //MP3_CMD_CS=1; 
	SPIx_SetSpeed(SPI_SPEED_8);//高速
    return temp; 
}  
//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 GetHeadInfo(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:return 0;//WAV格式
        case 0X4D54:return 1;//MIDI格式 
        case 0X574D://WMA格式
        {
            HEAD1=HEAD0*2/25;
            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 ResetDecodeTime(void)
{
	VS_WR_Cmd(SPI_DECODE_TIME,0x0000);
	VS_WR_Cmd(SPI_DECODE_TIME,0x0000);//操作两次
}
//得到mp3的播放时间n sec
u16 GetDecodeTime(void)
{ 
    return VS_RD_Reg(SPI_DECODE_TIME);   
} 
//加载频谱分析的代码到VS10XX
void LoadPatch(void)
{
	u16 i;
	for (i=0;i<943;i++)VS_WR_Cmd(atab[i],dtab[i]); 
	delay_ms(10);
}
//得到频谱数据
void GetSpec(u8 *p)
{
	u8 byteIndex=0;
	u8 temp;
	VS_WR_Cmd(SPI_WRAMADDR,0x1804);                                                                                             
	for (byteIndex=0;byteIndex<14;byteIndex++) 
	{                                                                               
		temp=VS_RD_Reg(SPI_WRAM)&0x63;//取小于100的数    
		*p++=temp;
	} 
}	   	  
//设定VS10XX播放的音量和高低音 
void set1003(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上拉   				  	 
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -