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

📄 vs1003b.c

📁 mp3量不要让站长把时间都花费在为您修正说明上。压缩包解压时不能有密码。系统会自动删除debug和release目录
💻 C
字号:
/*******************************************************************/
/*          VS1003 diriver for  Mega8 MP3 Player                   */
/*                                                                 */
/* Platform   : AVRStudio4.13 b528 + WinAVR20070122                */
/*              optimize -0s                                       */
/* Author     : bozai(Zhang Qibo)                                  */
/* E-mail     : sudazqb@163.com                                    */
/* MSN        : zhangqibo_1985@hotmail.com                         */
/* Date       : 2006-05-09                                         */
/*******************************************************************/
/*  20080928: modify codes for ARM platform (NXP LPC2132)  */
/*  20071208: modify codes for ARM platform (AT91SAM7S256)  */
/*2007-11-22: add bass tremble control                             */
/*2007-10-21: add new functions,                                   */
/*2007-10-19: use new delay function                               */
/*2007-05-04: add slow start up code, and add enough delay         */
/*2007-04-21:                                                      */

#include "VS1003B.h"

#define uchar unsigned char
#define uint  unsigned short

void VS1003B_SPI_Low(void);//low spi clk
void VS1003B_SPI_High(void);//high spi clk
unsigned char VS1003B_WriteByte(unsigned char CH);//spi write a byte
void VS1003B_WriteCMD(unsigned char addr, unsigned short dat);//write register 
unsigned short VS1003B_ReadCMD(unsigned char addr);//read register 



/* Run at the loweset spi speed, clk should below 12.288M/6 */
void VS1003B_SPI_Low(void)
{
	S0PCCR = 100;										/* 设置SPI0时钟分频值为8  Set the value of dividing frequency to 8 */
	
	S0PCR  = (0 << 3) |									// CPHA = 0, 数据 在SCK 的第一个时钟沿采样
 	(1 << 4) |											// CPOL = 1, SCK 为低有效
 	(1 << 5) |											// MSTR = 1, SPI 处于主模式
 	(0 << 6) |											// LSBF = 0, SPI 数据传输MSB (位7)在先
 	(0 << 7);											// SPIE = 0, SPI 中断被禁止

#if 0
	AT91PS_SPI pSPI      = AT91C_BASE_SPI;
	unsigned long reg;
	unsigned char speed = MCK/200000;	/* 200KHz, below 400KHz */

	reg = pSPI->SPI_CSR[0];	/* we control the CS but not SPI , so just use default SPI_CSR0 */
	reg = ( reg & ~(AT91C_SPI_SCBR) ) | ( (unsigned long)speed << 8 );	/* recaulate */
	pSPI->SPI_CSR[0] = reg;	/* set the value */
#endif
}

/* High speed, should not exceed 49.512MHz/6 */
void VS1003B_SPI_High(void)
{
	S0PCCR = 6;										/* 设置SPI0时钟分频值为8  Set the value of dividing frequency to 8 */
	
	S0PCR  = (0 << 3) |									// CPHA = 0, 数据 在SCK 的第一个时钟沿采样
 	(1 << 4) |											// CPOL = 1, SCK 为低有效
 	(1 << 5) |											// MSTR = 1, SPI 处于主模式
 	(0 << 6) |											// LSBF = 0, SPI 数据传输MSB (位7)在先
 	(0 << 7);											// SPIE = 0, SPI 中断被禁止

#if 0
	AT91PS_SPI pSPI      = AT91C_BASE_SPI;
	unsigned long reg;
	unsigned char speed = MCK/12000000;	/* 8MHz */

	reg = pSPI->SPI_CSR[0];	/* we control the CS but not SPI , so just use default SPI_CSR0 */
	reg = ( reg & ~(AT91C_SPI_SCBR) ) | ( (unsigned long)speed << 8 );	/* recaulate */
	pSPI->SPI_CSR[0] = reg;	/* set the value */
#endif
}

/* write one byte to vs1003 */
unsigned char VS1003B_WriteByte(unsigned char val)
{  
	
	S0PDR = val;

	while(0 == (S0PSR & 0x80));						    /* wait for SPI0F being set, that is, wait for finishing of data being send */
	

	return(S0PDR);

#if 0
	AT91PS_SPI pSPI      = AT91C_BASE_SPI;	

	while( !( pSPI->SPI_SR & AT91C_SPI_TDRE ) );	/* transfer compl. wait */
	pSPI->SPI_TDR = val;

	while( !( pSPI->SPI_SR & AT91C_SPI_RDRF ) );	/* wait for char */
	return (unsigned char)( pSPI->SPI_RDR );			/* it's important to read RDR here! */
#endif	
}

/* read one byte from vs1003 */
unsigned char VS1003B_ReadByte()
{
	
	S0PDR = 0xff;

	while(0 == (S0PSR & 0x80));						    /* wait for SPI0F being set, that is, wait for finishing of data being send */
	

	return(S0PDR);

#if 0
	AT91PS_SPI pSPI      = AT91C_BASE_SPI;	

	while( !( pSPI->SPI_SR & AT91C_SPI_TDRE ) );	/* transfer compl. wait */
	pSPI->SPI_TDR = 0xff;

	while( !( pSPI->SPI_SR & AT91C_SPI_RDRF ) );	/* wait for char */
	return (unsigned char)( pSPI->SPI_RDR );			/* it's important to read RDR here! */
#endif	
}

/*写寄存器,参数,地址和数据   config register */
void VS1003B_WriteCMD(unsigned char addr, unsigned short dat)
{
	VS1003B_XDCS_H();
	VS1003B_XCS_L();
	VS1003B_WriteByte(0x02);
	VS1003B_WriteByte(addr);
	VS1003B_WriteByte(dat>>8);
	VS1003B_WriteByte(dat);
	VS1003B_XCS_H();
}

/* 读寄存器,参数 地址 返回内容  read register */
unsigned short VS1003B_ReadCMD(unsigned char addr)
{
	unsigned short temp;
	VS1003B_XDCS_H();
	VS1003B_XCS_L();
	VS1003B_WriteByte(0x03);
	VS1003B_WriteByte(addr);
	temp = VS1003B_ReadByte();
	temp <<= 8;
	temp += VS1003B_ReadByte();
	VS1003B_XCS_H();
	return temp;
}

/* fill 2048 zero */
void VS1003B_Fill2048Zero()
{
	unsigned char i,j;
	VS1003B_SPI_High();
	for(i=0;i<64;i++)
	{
		VS1003B_XDCS_L();
		while(VS1003B_NeedData()==0);
		for(j=0;j<32;j++)
		{
			VS1003B_WriteByte(0x00);
		}
		VS1003B_XDCS_H();
	}
}

/* Write 32bytes data */
void VS1003B_Write32B(unsigned char * buf)
{
	unsigned char n = 32;
	VS1003B_SPI_High();
	VS1003B_XDCS_L();
	while(n--)
	{
		VS1003B_WriteByte(*buf++);
	}
	VS1003B_XDCS_H();
}

/**********  Initialization, 1 means fail, 0 OK ***************/
unsigned char VS1003B_Init(void)
{
	unsigned char retry;
#if 0
	AT91PS_SPI pSPI      = AT91C_BASE_SPI;
	AT91PS_PMC pPMC      = AT91C_BASE_PMC;
#endif	
	PORT_INI();			/* Prot Initialize */

#if 0
	/* disable PIO from controlling MOSI, MISO, SCK (=hand over to SPI) */
	pPIO->PIO_PDR = AT91C_PA12_MISO | AT91C_PA13_MOSI | AT91C_PA14_SPCK;
	/* set pin-functions in PIO Controller */
	pPIO->PIO_ASR = AT91C_PA12_MISO | AT91C_PA13_MOSI | AT91C_PA14_SPCK;

	/* enable peripheral clock for SPI ( PID Bit 5 ) */
	pPMC->PMC_PCER = ( 1 << AT91C_ID_SPI ); /* n.b. IDs are just bit-numbers */

	/* SPI enable and reset */
	pSPI->SPI_CR = AT91C_SPI_SPIEN | AT91C_SPI_SWRST;

	/* SPI mode: master, fixed periph. sel., FDIV=0, fault detection disabled */
	pSPI->SPI_MR  = AT91C_SPI_MSTR | AT91C_SPI_PS_FIXED | AT91C_SPI_MODFDIS;

	/* set PCS for fixed select, in this program we do not use select of the SPI */
	/* We control the select ourself, so the default cs is 0, but we never use it */
	pSPI->SPI_MR &= 0xFFF0FFFF; /* clear old PCS - redundant (AT91lib) */
	pSPI->SPI_MR |= ( (0<<16) & AT91C_SPI_PCS ); /* set PCS */
	pSPI->SPI_CSR[0] = AT91C_SPI_NCPHA | AT91C_SPI_BITS_8;
#endif
	/* set SPI clock speed */
	VS1003B_SPI_Low();	/* Low initialize spi clock */
#if 0
	/* Enable SPI interface */
	pSPI->SPI_CR = AT91C_SPI_SPIEN;
#endif
	VS1003B_XRESET_L();	/* A hardware reset */
	_delay_ms(20);
	VS1003B_XRESET_H();

	VS1003B_SPI_Low();	/* Low initialize spi clock */
	_delay_ms(20);

	retry=0;

	while(VS1003B_ReadCMD(0x03) != CLOCK_REG)	/* set PLL register */
	{
		VS1003B_WriteCMD(0x03,CLOCK_REG);
		if(retry++ >10 )return 1;
	}

	_delay_ms(20);
	
	VS1003B_WriteCMD(0x05,0x000a);
	
	retry=0;
	while(VS1003B_ReadCMD(0x0b) != 0xfefe)	/* set Volume to minimum */
	{
		VS1003B_WriteCMD(0x0b,0xfefe);
		if(retry++ >10 )return 1;
	}

	VS1003B_WriteCMD(0x05,0xac45);			/* Soft start */

	retry=0;
	while(VS1003B_ReadCMD(0x0b) != DEFAULT_VOLUME)	/* Set volume to default value */
	{
		VS1003B_WriteCMD(0x0b,DEFAULT_VOLUME);
		if(retry++ >10 )return 1;
	}

	retry=0;
	while(VS1003B_ReadCMD(0x00) != 0x0800)	/* set mode register */
	{
		VS1003B_WriteCMD(0x00,0x0800);
		if(retry++ >10 )return 1;
	}

	_delay_ms(1);

	retry=0;
	while(VS1003B_ReadCMD(0x02) != DEFAULT_BASS_TREMBLE)	/* set bass/tremble register */
	{
		VS1003B_WriteCMD(0x02,DEFAULT_BASS_TREMBLE);
		if(retry++ >10 )return 1;
	}
	_delay_ms(20);

	VS1003B_SoftReset();	/* A soft reset */

	_delay_ms(20);

	VS1003B_SPI_High();		/* High SPI clock, for internal pll has been works now */
	return 0;
}

/* VS1003B soft reset */
void VS1003B_SoftReset()
{
	VS1003B_SPI_High();
	VS1003B_WriteCMD(0x00,0x0804);	/* reset */
	_delay_ms(20);
}

/* get total decode time form last reset */
unsigned short VS1003B_ReadDecodeTime()
{
	VS1003B_SPI_High();
	return VS1003B_ReadCMD(0x04);
}

/* check if the chip need data, 1: need  0: don't */
unsigned char VS1003B_NeedData(void)
{
//	unsigned int temp;
	//temp = pPIO->PIO_PDSR;
	if(VS1003_DREQ_STATE()!=0)return 1;
	else return 0;
}

/* Set volume */
void VS1003B_SetVolume(unsigned short vol)
{
	VS1003B_SPI_High();
	VS1003B_WriteCMD(0x0b,vol);	
}

⌨️ 快捷键说明

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