//古道热肠U盘开发板-VS1003B音乐播放模块驱动<br />//主办单位:www.21ic.com<br />//项目负责人:古道热肠<br />//作者邮箱:xg_2004_sy@126.com<br />//完成日期:2008-02-27<br />//备注:<br /><br />#include <AT91SAM7S64.H> /* AT91SAM7S64 definitions */<br />#include <lib_AT91SAM7s64.h><br /><br />#include "..Board.h"<br /><br />#include "english_6x8_pixel.h"<br />//#include "DriverLCD_Nokia5110.h"<br /><br />#include "VS1003.h"<br />#include "DriverBeep.h"<br /><br />#define uchar unsigned char<br />#define uint unsigned short int<br />#define ulong unsigned long<br /><br />#define Macro_SetVS1003B_SDIN_High() AT91F_PIO_SetOutput( AT91C_BASE_PIOA, VS1003B_SDIN )<br />#define Macro_SetVS1003B_SDIN_Low() AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, VS1003B_SDIN)<br /><br />#define Macro_SetVS1003B_SCLK_High() AT91F_PIO_SetOutput( AT91C_BASE_PIOA, VS1003B_SCLK) <br />#define Macro_SetVS1003B_SCLK_Low() AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, VS1003B_SCLK) <br /><br />#define Macro_SetVS1003B_XCS_High() AT91F_PIO_SetOutput( AT91C_BASE_PIOA, VS1003B_XCS)<br />#define Macro_SetVS1003B_XCS_Low() AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, VS1003B_XCS)<br /><br />#define Macro_SetVS1003B_XDCS_High() AT91F_PIO_SetOutput( AT91C_BASE_PIOA, VS1003B_XDCS) <br />#define Macro_SetVS1003B_XDCS_Low() AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, VS1003B_XDCS) <br /><br />#define Macro_SetVS1003B_XRESET_High() AT91F_PIO_SetOutput( AT91C_BASE_PIOA, VS1003B_XRESET)<br />#define Macro_SetVS1003B_XRESET_Low() AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, VS1003B_XRESET)<br /><br />//#define Macro_SetVS1003B_PC_High() ;//LCD_PC = 1<br />//#define Macro_SetVS1003B_PC_Low() ;//LCD_PC = 0<br /><br />//#define Macro_SetBeep_High() AT91F_PIO_SetOutput( AT91C_BASE_PIOA, Beep_Pin) <br />//#define Macro_SetBeep_Low() AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, Beep_Pin) <br /><br />#define uint8 unsigned char<br /><br /> <br />#define Mp3PutInReset() Macro_SetVS1003B_XRESET_Low()<br /> <br />#define Mp3ReleaseFromReset() Macro_SetVS1003B_XRESET_High() <br /> <br /> <br />#define Mp3SelectControl() Macro_SetVS1003B_XCS_Low()<br /> <br />#define Mp3DeselectControl() Macro_SetVS1003B_XCS_High() <br /> <br /><br />#define Mp3SelectData() Macro_SetVS1003B_XDCS_Low()<br /><br />#define Mp3DeselectData() Macro_SetVS1003B_XDCS_High()<br /><br /><br /><br />#define Macro_Set_SI_High() Macro_SetVS1003B_SDIN_High()<br />#define Macro_Set_SI_Low() Macro_SetVS1003B_SDIN_Low() <br />#define Macro_Set_CLK_High() Macro_SetVS1003B_SCLK_High()<br />#define Macro_Set_CLK_Low() Macro_SetVS1003B_SCLK_Low()<br /><br />//获取vs1003b芯片spi接口的数据输出引脚的值<br />bool GetVS1003B_SO_Value(void)<br />{<br /> unsigned int n;<br /> <br /> n = AT91F_PIO_GetInput( AT91C_BASE_PIOA);<br /><br /> return((n&VS1003B_SDO) );<br /> <br />}<br />//获取vs1003b芯片spi接口的数据输出引脚的值<br />bool GetVS1003B_DREQ_Value(void)<br />{<br /> unsigned int n;<br /> <br /> n = AT91F_PIO_GetInput( AT91C_BASE_PIOA);<br /><br /> return((n&VS1003B_DREQ) );<br /> <br />}<br /><br /><br />void wait(uchar ucDelayCount)<br />{<br /> uchar ucTempCount;<br /> uchar uci;<br /><br /> for(ucTempCount=0; ucTempCount<ucDelayCount; ucTempCount++)<br /> {<br /> uci = 230;<br /> while(uci--)<br /> {<br />// _nop_();<br /> }<br /> }<br />}<br /><br />//#define wait(x) Delay(x)<br />/**********************************************************/<br />/* 函数名称 : MSPI_Init */<br />/* 函数功能 : 初始化SPI接口,设置为主机。 */<br />/* 参数 : 无 */<br />/* 返回值 : 无 */<br />/*--------------------------------------------------------*/<br />void MSPI_Init(void)<br />{ <br />// c_SPI_SO = 1;<br />// MP3_DREQ = 1;<br />}<br /><br />/**********************************************************/<br />/* 函数名称 : InitPortVS1003 */<br />/* 函数功能 : MCU与vs1003接口的初始化 */<br />/* 参数 : 无 */<br />/* 返回值 : 无 */<br />/*--------------------------------------------------------*/<br />void InitPortVS1003(void)<br />{<br /> MSPI_Init();//SPI口的初始化<br />// IODIR &= 0xfffeffff; //其他接口线的设置,其中dreq 为输入口<br />// IODIR |= MP3_XRESET | MP3_XCS | MP3_XDCS;//xRESET,xCS,xDS均为输出口<br />// IOSET |= MP3_XRESET | MP3_XCS | MP3_XDCS;//xRESET,xCS,xDS默认输出高电平 <br />// MP3_DREQ = 1; //置为输入<br /><br /> Macro_SetVS1003B_XRESET_High();<br /> Macro_SetVS1003B_XCS_High();<br /> Macro_SetVS1003B_XDCS_High();<br />}<br /><br />//uint8 SD_SPI_ReadByte(void);<br />//void SD_SPI_WriteByte(uint8 ucSendData);<br /><br />//#define SPI_RecByte() SD_SPI_ReadByte()<br />//#define SPIPutChar(x) SD_SPI_WriteByte(x)<br /><br />#if 1<br />/**********************************************************/<br />/* 函数名称 : SPIPutChar */<br />/* 函数功能 : 通过SPI发送一个字节的数据 */<br />/* 参数 : 待发送的字节数据 */<br />/* 返回值 : 无 */<br />/*--------------------------------------------------------*/<br />void SPIPutChar(unsigned char ucSendData)<br />{ <br />// S0SPDR = c;<br />// while((S0SPSR & 0x80) == 0); //等待SPI将数据发送完毕<br /> uchar ucCount;<br /> uchar ucMaskCode;<br /><br /> ucMaskCode = 0x80;<br /> for(ucCount=0; ucCount<8; ucCount++)<br /> {<br /> Macro_Set_CLK_Low();<br /><br /> if(ucMaskCode & ucSendData)<br /> {<br /> Macro_Set_SI_High();<br /> }<br /> else<br /> {<br /> Macro_Set_SI_Low();<br /> }<br /><br /> Macro_Set_CLK_High();<br /> ucMaskCode >>= 1;<br /><br /> }<br />}<br /><br />/*******************************************************************************************************************<br />** 函数名称: INT8U SPI_RecByte() Name: INT8U SPI_RecByte()<br />** 功能描述: 从SPI接口接收一个字节 Function: receive a byte from SPI interface<br />** 输 入: 无 Input: NULL<br />** 输 出: 收到的字节 Output: the byte that be received<br />********************************************************************************************************************/<br />static uchar SPI_RecByte(void)<br />{<br /> uchar ucReadData;<br /> uchar ucCount;<br /><br /> ucReadData = 0;<br /> Macro_Set_SI_High();<br /><br /> for(ucCount=0; ucCount<8; ucCount++)<br /> {<br /> ucReadData <<= 1;<br /> //降低时钟频率<br /> Macro_Set_CLK_Low();<br /><br /> <br /> if(GetVS1003B_SO_Value())<br /> {<br /> ucReadData |= 0x01;<br /> }<br /> Macro_Set_CLK_High();<br /><br /> }<br /><br /> return(ucReadData);<br />}<br /><br />#endif<br /><br />/*************************************************************/<br />/* 函数名称 : Mp3WriteRegister */<br />/* 函数功能 : 写vs1003寄存器 */<br />/* 参数 : 寄存器地址,待写数据的高8位,待写数据的低8位 */<br />/* 返回值 : 无 */<br />/*-----------------------------------------------------------*/<br />void Mp3WriteRegister(unsigned char addressbyte, unsigned char highbyte, unsigned char lowbyte)<br />{<br /> Mp3DeselectData();<br /> Mp3SelectControl();//XCS = 0<br /> SPIPutChar(VS_WRITE_COMMAND); //发送写寄存器命令<br /> SPIPutChar(addressbyte); //发送寄存器的地址<br /> SPIPutChar(highbyte); //发送待写数据的高8位<br /> SPIPutChar(lowbyte); //发送待写数据的低8位<br /> Mp3DeselectControl();<br />}<br /><br />/*************************************************************/<br />/* 函数名称 : Mp3ReadRegister */<br />/* 函数功能 : 写vs1003寄存器 */<br />/* 参数 : 寄存器地址 */<br />/* 返回值 : vs1003的16位寄存器的值 */<br />/*-----------------------------------------------------------*/<br />unsigned int Mp3ReadRegister(unsigned char addressbyte)<br />{<br /> unsigned int resultvalue = 0;<br /> uchar ucReadValue;<br /><br /> Mp3DeselectData();<br /> Mp3SelectControl();//XCS = 0<br /> SPIPutChar(VS_READ_COMMAND); //发送读寄存器命令<br /> SPIPutChar((addressbyte)); //发送寄存器的地址<br /><br />// SPIPutChar(0xff); //发送读时钟<br />// resultvalue = (SPI_RESULT_BYTE) << 8;//读取高8位数据<br /> ucReadValue = SPI_RecByte();<br /> resultvalue = ucReadValue<<8;<br />// SPIPutChar(0xff); //发送读时钟<br />// resultvalue |= (SPI_RESULT_BYTE); //读取低8位数据<br /> ucReadValue = SPI_RecByte();<br /> resultvalue |= ucReadValue;<br /><br /> Mp3DeselectControl(); <br /> return resultvalue; //返回16位寄存器的值<br />}<br /><br />/**********************************************************/<br />/* 函数名称 : Mp3SoftReset */<br />/* 函数功能 : vs1003软件复位 */<br />/* 参数 : 无 */<br />/* 返回值 : 无 */<br />/*--------------------------------------------------------*/<br />void Mp3SoftReset(void)<br />{<br /> Mp3WriteRegister (SPI_MODE, 0x08, 0x04); //软件复位<br /><br /> wait(1); //延时1ms<br /> while (GetVS1003B_DREQ_Value() == 0); //等待软件复位结束<br /> Mp3WriteRegister(SPI_CLOCKF, 0x98, 0x00);//设置vs1003的时钟,3倍频<br /> Mp3WriteRegister (SPI_AUDATA, 0xBB, 0x81); //采样率48k,立体声<br /> Mp3WriteRegister(SPI_BASS, 0x00, 0x55);//设置重音<br /> Mp3SetVolume(50,50);//设置音量<br /> wait(1); //延时1ms<br /> <br /> //向vs1003发送4个字节无效数据,用以启动SPI发送<br /> Mp3SelectData();<br /> SPIPutChar(0);<br /> SPIPutChar(0);<br /> SPIPutChar(0);<br /> SPIPutChar(0);<br /> Mp3DeselectData();<br /><br />}<br />/**********************************************************/<br />/* 函数名称 : Mp3Reset */<br />/* 函数功能 : vs1003硬件复位 */<br />/* 参数 : 无 */<br />/* 返回值 : 无 */<br />/*--------------------------------------------------------*/<br />void Mp3Reset(void)<br />{ <br /> Mp3PutInReset();//xReset = 0 复位vs1003 <br /> wait(200);//延时100ms<br /> SPIPutChar(0xff);//发送一个字节的无效数据,启动SPI传输<br /> Mp3DeselectControl(); //xCS = 1<br /> Mp3DeselectData(); //xDCS = 1<br /> Mp3ReleaseFromReset(); //xRESET = 1<br /> wait(200); //延时100ms<br /> while (GetVS1003B_DREQ_Value()== 0);//等待DREQ为高<br /><br /> wait(200); //延时100ms<br /> Mp3SetVolume(50,50); <br /> Mp3SoftReset();//vs1003软复位<br />}<br /><br /><br />bool CheckVS1003B_DRQ(void)<br />{<br /> bool bResult;<br /><br /> bResult =GetVS1003B_DREQ_Value();<br /> return(bResult);<br />}<br /><br />/***********************************************************/<br />/* 函数名称 : VsSineTest */<br />/* 函数功能 : vs1003正弦测试,将该函数放在while循环中, */<br />/* 如果能持续听到一高一低的声音,证明测试通过 */ <br />/* 参数 : 无 */<br />/* 返回值 : 无 */<br />/*---------------------------------------------------------*/<br />void VsSineTest(void)<br />{<br /> Mp3PutInReset(); //xReset = 0 复位vs1003<br /> wait(200); //延时100ms <br /> SPIPutChar(0xff);//发送一个字节的无效数据,启动SPI传输<br /> Mp3DeselectControl(); <br /> Mp3DeselectData(); <br /> Mp3ReleaseFromReset(); <br /> wait(200); <br /> Mp3SetVolume(50,50); <br /><br /> Mp3WriteRegister(SPI_MODE,0x08,0x20);//进入vs1003的测试模式<br /> while (GetVS1003B_DREQ_Value() == 0); //等待DREQ为高<br /> Mp3SelectData(); //xDCS = 1,选择vs1003的数据接口<br /> <br /> //向vs1003发送正弦测试命令:0x53 0xef 0x6e n 0x00 0x00 0x00 0x00<br /> //其中n = 0x24, 设定vs1003所产生的正弦波的频率值,具体计算方法见vs1003的datasheet<br /> SPIPutChar(0x53); <br /> SPIPutChar(0xef); <br /> SPIPutChar(0x6e); <br /> SPIPutChar(0x24); <br /> SPIPutChar(0x00); <br /> SPIPutChar(0x00);<br /> SPIPutChar(0x00);<br /> SPIPutChar(0x00);<br />// wait(500);<br /> wait(250);<br /> wait(250);<br /> Mp3DeselectData();//程序执行到这里后应该能从耳机听到一个单一频率的声音<br /> <br /> //退出正弦测试<br /> Mp3SelectData();<br /> SPIPutChar(0x45);<br /> SPIPutChar(0x78);<br /> SPIPutChar(0x69);<br /> SPIPutChar(0x74);<br /> SPIPutChar(0x00);<br /> SPIPutChar(0x00);<br /> SPIPutChar(0x00);<br /> SPIPutChar(0x00);<br />// wait(500);<br /> wait(250);<br /> wait(250);<br /><br /> Mp3DeselectData();<br /><br /> //再次进入正弦测试并设置n值为0x44,即将正弦波的频率设置为另外的值<br /> Mp3SelectData(); <br /> SPIPutChar(0x53); <br /> SPIPutChar(0xef); <br /> SPIPutChar(0x6e); <br /> SPIPutChar(0x44); <br /> SPIPutChar(0x00); <br /> SPIPutChar(0x00);<br /> SPIPutChar(0x00);<br /> SPIPutChar(0x00);<br />// wait(500);<br /> wait(250);<br /> wait(250);<br /><br /> Mp3DeselectData(); <br /><br /> //退出正弦测试<br /> Mp3SelectData();<br /> SPIPutChar(0x45);<br /> SPIPutChar(0x78);<br /> SPIPutChar(0x69);<br /> SPIPutChar(0x74);<br /> SPIPutChar(0x00);<br /> SPIPutChar(0x00);<br /> SPIPutChar(0x00);<br /> SPIPutChar(0x00);<br />// wait(500);<br /> wait(250);<br /> wait(250);<br /><br /> Mp3DeselectData();<br /> }<br /><br />void test_1003_PlayMP3File();<br /><br />void TestVS1003B(void)<br />{<br /> Mp3Reset();<br /> VsSineTest();<br /> Mp3SoftReset();<br /> test_1003_PlayMP3File();<br />}<br /><br />//写寄存器,参数,地址和数据<br />void VS1003B_WriteCMD(unsigned char addr, unsigned int dat)<br />{<br />/*<br /> VS1003B_XDCS_H();<br /> VS1003B_XCS_L();<br /> VS1003B_WriteByte(0x02);<br /> //delay_Nus(20);<br /> VS1003B_WriteByte(addr);<br /> VS1003B_WriteByte(dat>>8);<br /> VS1003B_WriteByte(dat);<br /> //delay_Nus(200);<br /> VS1003B_XCS_H();<br />*/<br /> Mp3WriteRegister(addr,dat>>8,dat);<br />}<br /><br />//读寄存器,参数 地址 返回内容<br />unsigned int VS1003B_ReadCMD(unsigned char addr)<br />{<br />/*<br /> unsigned int temp;<br /> unsigned char temp1;<br /> VS1003B_XDCS_H();<br /> VS1003B_XCS_L();<br /> VS1003B_WriteByte(0x03);<br /> //delay_Nus(20);<br /> VS1003B_WriteByte(addr);<br /> temp= VS1003B_ReadByte();<br /> temp=temp<<8;<br /> temp1= VS1003B_ReadByte();<br /> temp=temp|temp1;;<br /> VS1003B_XCS_H();<br /> return temp;<br />*/<br /> return(Mp3ReadRegister(addr));<br />}<br /><br />//写数据,音乐数据<br />void VS1003B_WriteDAT(unsigned char dat)<br />{<br />// VS1003B_XDCS_L();<br />// VS1003B_WriteByte(dat);<br />// VS1003B_XDCS_H();<br />// VS1003B_XCS_H();<br /><br /> Mp3SelectData();<br /> SPIPutChar(dat);<br /> Mp3DeselectData();<br /> Mp3DeselectControl();<br /><br />}<br /><br />//开启环绕声<br />void VS1003B_SetVirtualSurroundOn(void)<br />{<br /> uchar ucRepeatCount;<br /> uint uiModeValue;<br /><br /> ucRepeatCount =0;<br /><br /> while(1)//写时钟寄存器<br /> {<br /> uiModeValue = VS1003B_ReadCMD(0x00);<br /> if(uiModeValue & 0x0001)<br /> {<br /> break;<br /> }<br /> else<br /> {<br /> uiModeValue |= 0x0001;<br /> VS1003B_WriteCMD(0,uiModeValue);<br /> }<br /> ucRepeatCount++;<br /> if(ucRepeatCount++ >10 )break;<br /> }<br /><br />}<br /><br />//关闭环绕声<br />void VS1003B_SetVirtualSurroundOff(void)<br />{<br /> uchar ucRepeatCount;<br /> uint uiModeValue;<br /><br /> ucRepeatCount =0;<br /><br /> while(1)//写时钟寄存器<br /> {<br /> uiModeValue = VS1003B_ReadCMD(0x00);<br /> if(uiModeValue & 0x0001)<br /> {<br /> break;<br /> }<br /> else<br /> {<br /> uiModeValue |= 0x0001;<br /> VS1003B_WriteCMD(0,uiModeValue);<br /> }<br /> ucRepeatCount++;<br /> if(ucRepeatCount++ >10 )break;<br /> }<br /><br />}<br /><br />//增强重音<br />//入口参数 1.强度0-15<br />// 2.频率0-15 (X10Hz)<br />void VS1003B_SetBassEnhance(uchar ucValue, uchar ucFrequencyID)<br />{<br /> uchar ucRepeatCount;<br /> uint uiWriteValue;<br /> uint uiReadValue; <br /><br /> ucRepeatCount =0;<br /><br /> uiWriteValue = VS1003B_ReadCMD(0x02);<br /><br /> uiWriteValue &= 0xFF00;<br /> uiWriteValue |= ucValue<<4;<br /> uiWriteValue &= (ucFrequencyID & 0x0F);<br /><br /> while(1)//写时钟寄存器<br /> {<br /><br /> VS1003B_WriteCMD(2,uiWriteValue);<br /> uiReadValue = VS1003B_ReadCMD(0x02);<br /> <br /> if(uiReadValue == uiWriteValue)<br /> {<br /> break;<br /> }<br /> ucRepeatCount++;<br /> if(ucRepeatCount++ >10 )break;<br /> }<br /><br />}<br /><br /><br /> uint uiVolumeCount; //当前音量值<br /><br />//VS1003初始化,0成功 1失败<br />unsigned char VS1003B_Init()<br />{<br /> unsigned char retry;<br />/*<br /> PORT_INI();<br /> DDRB|=0xa0;<br /> VS1003B_DDR &=~(1<<VS1003B_DREQ);<br /> //delay_Nus(50);<br /> VS1003B_XCS_H();<br /> VS1003B_XDCS_H();<br /> VS1003B_XRESET_L();<br /> VS1003B_Delay(0xffff);<br /> VS1003B_XRESET_H();//使能芯片<br /> VS1003B_SPI_Low();//先以低频操作<br /> VS1003B_Delay(0xffff);//延时<br />*/<br />Mp3Reset();<br /><br /> retry=0;<br /> while(VS1003B_ReadCMD(0x00) != 0x0800)//写mode寄存器<br /> {<br /> VS1003B_WriteCMD(0x00,0x0800);<br /> if(retry++ >10 )break;//{PORTB|=_BV(PB1);break;}<br /> }<br /> retry=0;<br /> /*while(VS1003B_ReadCMD(0x02) != 0x75)//写mode寄存器<br /> {<br /> VS1003B_WriteCMD(0x02,0x75);<br /> if(retry++ >10 )break;//{PORTB|=_BV(PB1);break;}<br /> }*/<br /> retry=0;<br /> while(VS1003B_ReadCMD(0x03) != 0x9800)//写时钟寄存器<br /> {<br /> VS1003B_WriteCMD(0x03,0x9800);<br /> if(retry++ >10 )break;<br /> }<br /> retry=0;<br />// while(VS1003B_ReadCMD(0x0b) != 0x1111)//设音量<br />// {<br />// VS1003B_WriteCMD(0x0b,0x1111);<br />// if(retry++ >10 )break;<br />// }<br /> while(VS1003B_ReadCMD(0x0b) != uiVolumeCount)//设音量<br /> {<br /> VS1003B_WriteCMD(0x0b,uiVolumeCount);<br /> if(retry++ >10 )break;<br /> }<br /><br />// VS1003B_SPI_High();//提高速度,全速运行<br /> if(retry > 10)return 1;<br /> return 0;<br />}<br /><br />//VS1003软件复位<br />void VS1003B_SoftReset()<br />{<br /> VS1003B_WriteCMD(0x00,0x0804);//写复位<br />// VS1003B_Delay(0xffff);//延时,至少1.35ms<br /> wait(2);<br />}<br /><br />
|