找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5113|回复: 10
收起左侧

基于51单片机的vs1003 MP3模块原理图+测试程序

  [复制链接]
ID:437541 发表于 2018-12-2 10:49 | 显示全部楼层 |阅读模式
电路原理图如下:
0.png 0.png 0.png

单片机源程序如下:
  1. /*
  2. * MP3模块测试程序
  3. *
  4. * 用途:MP3模块测试程序
  5. *       vs1003 的硬件测试程序,主控芯片为STC12LE5A60S2
  6. *       其他的微处理器(带SPI接口的)只需稍加修改即可适用
  7. *       对于不带硬SPI接口的微处理器可以用IO进行SPI的时序模拟
  8. *
  9. * 作者                                        日期                                备注
  10. * Huafeng Lin                        20010/09/10                        新增
  11. * Huafeng Lin                        20010/09/10                        修改
  12. *
  13. */

  14. #include "vs1003.h"
  15. #include "MusicDataMP3.c"


  16. #include <intrins.h>

  17. #define uchar unsigned char
  18. #define uint unsigned int
  19. #define ulong unsigned long
  20. #define bool bit
  21. #define true 1
  22. #define flase 0


  23. //针对SD卡读写板调整引脚
  24. #define uint8 unsigned char

  25. sbit  MP3_XRESET  = P3^2;

  26. #define Mp3PutInReset()  { MP3_XRESET = 0; }

  27. #define Mp3ReleaseFromReset()  { MP3_XRESET =1; }

  28. sbit MP3_XCS = P3^3;

  29. #define Mp3SelectControl()  { MP3_XCS = 0; }

  30. #define Mp3DeselectControl()  { MP3_XCS = 1; }

  31. sbit MP3_XDCS  = P3^4;

  32. #define Mp3SelectData()                { MP3_XDCS = 0; }

  33. #define Mp3DeselectData()        { MP3_XDCS = 1; }

  34. sbit MP3_DREQ = P3^5;

  35. sbit c_SPI_SI = P1^5;
  36. sbit c_SPI_SO = P1^6;
  37. sbit c_SPI_CLK = P1^7;

  38. #define Macro_Set_SI_High()          c_SPI_SI = 1
  39. #define Macro_Set_SI_Low()          c_SPI_SI = 0
  40. #define Macro_Set_CLK_High()          c_SPI_CLK = 1
  41. #define Macro_Set_CLK_Low()          c_SPI_CLK = 0

  42. void LCD_write_english_string(unsigned char X,unsigned char Y,char *s);

  43. //#define SPIWait()        { while((S0SPSR & 0x80) == 0); }//等待SPI将数据发送完毕

  44. //#define SPI_RESULT_BYTE  S0SPDR

  45. //extern long volatile timeval; //用于延时的全局变量
  46. //1ms Delayfunction
  47. //void Delay(uchar ucDelayCount)
  48. void wait(uchar ucDelayCount)
  49. {
  50.         uchar ucTempCount;
  51.         uchar uci;

  52.         for(ucTempCount=0; ucTempCount<ucDelayCount; ucTempCount++)
  53.         {
  54. //                uci = 200;        //Err
  55. //                uci = 250;        //OK
  56.                 uci = 230;
  57.                 while(uci--)
  58.                 {
  59.                         _nop_();
  60.                    }
  61.         }
  62. }

  63. //#define wait(x) Delay(x)
  64. /**********************************************************/
  65. /*  函数名称 :   MSPI_Init                                */
  66. /*  函数功能 : 初始化SPI接口,设置为主机。               */
  67. /*  参数     :  无                                        */
  68. /*  返回值   :  无                                        */
  69. /*--------------------------------------------------------*/
  70. void  MSPI_Init(void)
  71. {  
  72. /*
  73.         PINSEL0 = (PINSEL0 & 0xFFFF00FF) | 0x00005500;        //选择 SPI
  74.         S0SPCCR = 0x08;                                        // SPI 时钟设置
  75.          S0SPCR  = (0 << 3) |                                // CPHA = 0,
  76.                    (0 << 4) |                                // CPOL = 0,
  77.                    (1 << 5) |                                // MSTR = 1,
  78.                    (0 << 6) |                                // LSBF = 0,
  79.                    (0 << 7);                                // SPIE = 0,
  80. */
  81.         c_SPI_SO = 1;
  82.         MP3_DREQ = 1;

  83. }

  84. /**********************************************************/
  85. /*  函数名称 :  InitPortVS1003                            */
  86. /*  函数功能 : MCU与vs1003接口的初始化                   */
  87. /*  参数     :  无                                        */
  88. /*  返回值   :  无                                        */
  89. /*--------------------------------------------------------*/
  90. void  InitPortVS1003(void)
  91. {
  92.         MSPI_Init();//SPI口的初始化
  93. //        IODIR &= 0xfffeffff;   //其他接口线的设置,其中dreq 为输入口
  94. //        IODIR |= MP3_XRESET | MP3_XCS | MP3_XDCS;//xRESET,xCS,xDS均为输出口
  95. //        IOSET |= MP3_XRESET | MP3_XCS | MP3_XDCS;//xRESET,xCS,xDS默认输出高电平        
  96.         MP3_DREQ = 1;                //置为输入

  97.         MP3_XRESET = 1;
  98.         MP3_XCS = 1;
  99.         MP3_XDCS = 1;
  100. }

  101. //uint8 SD_SPI_ReadByte(void);
  102. //void SD_SPI_WriteByte(uint8 ucSendData);

  103. //#define SPI_RecByte()  SD_SPI_ReadByte()
  104. //#define SPIPutChar(x) SD_SPI_WriteByte(x)

  105. #if 1
  106. /**********************************************************/
  107. /*  函数名称 :  SPIPutChar                                */
  108. /*  函数功能 : 通过SPI发送一个字节的数据                 */
  109. /*  参数     :  待发送的字节数据                          */
  110. /*  返回值   :  无                                        */
  111. /*--------------------------------------------------------*/
  112. void  SPIPutChar(unsigned char ucSendData)
  113. {      
  114. //        S0SPDR = c;
  115. //        while((S0SPSR & 0x80) == 0);         //等待SPI将数据发送完毕
  116.         uchar ucCount;
  117.         uchar ucMaskCode;

  118.         ucMaskCode = 0x80;
  119.         for(ucCount=0; ucCount<8; ucCount++)
  120.         {
  121.                 Macro_Set_CLK_Low();

  122.                 if(ucMaskCode & ucSendData)
  123.                 {
  124.                         Macro_Set_SI_High();
  125.                 }
  126.                 else
  127.                 {
  128.                         Macro_Set_SI_Low();
  129.                 }

  130.                 Macro_Set_CLK_High();
  131.                 ucMaskCode >>= 1;

  132.         }
  133. }

  134. /*******************************************************************************************************************
  135. ** 函数名称: INT8U SPI_RecByte()                                Name:          INT8U SPI_RecByte()
  136. ** 功能描述: 从SPI接口接收一个字节                                Function: receive a byte from SPI interface
  137. ** 输   入: 无                                                                        Input:          NULL
  138. ** 输   出: 收到的字节                                                        Output:          the byte that be received
  139. ********************************************************************************************************************/
  140. static uchar SPI_RecByte(void)
  141. {
  142.         uchar ucReadData;
  143.         uchar ucCount;

  144.         ucReadData = 0;
  145.         Macro_Set_SI_High();

  146.         for(ucCount=0; ucCount<8; ucCount++)
  147.         {
  148.                 ucReadData <<= 1;
  149.                         //降低时钟频率
  150.                 Macro_Set_CLK_Low();

  151.         
  152.                 if(c_SPI_SO)
  153.                 {
  154.                         ucReadData |= 0x01;
  155.                 }
  156.                 Macro_Set_CLK_High();

  157.         }

  158.         return(ucReadData);
  159. }

  160. #endif

  161. /*************************************************************/
  162. /*  函数名称 :  Mp3WriteRegister                             */
  163. /*  函数功能 : 写vs1003寄存器                               */
  164. /*  参数     :  寄存器地址,待写数据的高8位,待写数据的低8位 */
  165. /*  返回值   :  无                                           */
  166. /*-----------------------------------------------------------*/
  167. void Mp3WriteRegister(unsigned char addressbyte, unsigned char highbyte, unsigned char lowbyte)
  168. {
  169.         Mp3DeselectData();
  170.         Mp3SelectControl();//XCS = 0
  171.         SPIPutChar(VS_WRITE_COMMAND); //发送写寄存器命令
  172.         SPIPutChar(addressbyte);      //发送寄存器的地址
  173.         SPIPutChar(highbyte);         //发送待写数据的高8位
  174.         SPIPutChar(lowbyte);          //发送待写数据的低8位
  175.         Mp3DeselectControl();
  176. }

  177. /*************************************************************/
  178. /*  函数名称 :  Mp3ReadRegister                              */
  179. /*  函数功能 : 写vs1003寄存器                               */
  180. /*  参数     :  寄存器地址                                     */
  181. /*  返回值   :  vs1003的16位寄存器的值                       */
  182. /*-----------------------------------------------------------*/
  183. unsigned int Mp3ReadRegister(unsigned char addressbyte)
  184. {
  185.         unsigned int resultvalue = 0;
  186.         uchar ucReadValue;

  187.         Mp3DeselectData();
  188.         Mp3SelectControl();//XCS = 0
  189.         SPIPutChar(VS_READ_COMMAND); //发送读寄存器命令
  190.         SPIPutChar((addressbyte));         //发送寄存器的地址

  191. //        SPIPutChar(0xff);                 //发送读时钟
  192. //        resultvalue = (SPI_RESULT_BYTE) << 8;//读取高8位数据
  193.         ucReadValue = SPI_RecByte();
  194.         resultvalue = ucReadValue<<8;
  195. //        SPIPutChar(0xff);                   //发送读时钟
  196. //        resultvalue |= (SPI_RESULT_BYTE);  //读取低8位数据
  197.         ucReadValue = SPI_RecByte();
  198.         resultvalue |= ucReadValue;

  199.         Mp3DeselectControl();              
  200.         return resultvalue;                 //返回16位寄存器的值
  201. }

  202. /**********************************************************/
  203. /*  函数名称 :  Mp3SoftReset                              */
  204. /*  函数功能 : vs1003软件复位                            */
  205. /*  参数     :  无                                        */
  206. /*  返回值   :  无                                        */
  207. /*--------------------------------------------------------*/
  208. void Mp3SoftReset(void)
  209. {
  210.         Mp3WriteRegister (SPI_MODE, 0x08, 0x04); //软件复位

  211.         wait(1); //延时1ms
  212.         while (MP3_DREQ == 0); //等待软件复位结束
  213.         Mp3WriteRegister(SPI_CLOCKF, 0x98, 0x00);//设置vs1003的时钟,3倍频
  214.         Mp3WriteRegister (SPI_AUDATA, 0xBB, 0x81); //采样率48k,立体声
  215.         Mp3WriteRegister(SPI_BASS, 0x00, 0x55);//设置重音
  216.         Mp3SetVolume(10,10);//设置音量
  217.     wait(1); //延时1ms
  218.             
  219.             //向vs1003发送4个字节无效数据,用以启动SPI发送
  220.            Mp3SelectData();
  221.         SPIPutChar(0);
  222.         SPIPutChar(0);
  223.         SPIPutChar(0);
  224.         SPIPutChar(0);
  225.         Mp3DeselectData();

  226. }
  227. /**********************************************************/
  228. /*  函数名称 :  Mp3Reset                                  */
  229. /*  函数功能 : vs1003硬件复位                            */
  230. /*  参数     :  无                                        */
  231. /*  返回值   :  无                                        */
  232. /*--------------------------------------------------------*/
  233. void Mp3Reset(void)
  234. {        
  235.         Mp3PutInReset();//xReset = 0   复位vs1003      
  236.         wait(200);//延时100ms
  237.         SPIPutChar(0xff);//发送一个字节的无效数据,启动SPI传输
  238.         Mp3DeselectControl();   //xCS = 1
  239.         Mp3DeselectData();     //xDCS = 1
  240.         Mp3ReleaseFromReset(); //xRESET = 1
  241.         wait(200);            //延时100ms
  242.         while (MP3_DREQ == 0);//等待DREQ为高

  243.     wait(200);            //延时100ms
  244.          Mp3SetVolume(50,50);  
  245.     Mp3SoftReset();//vs1003软复位
  246. }


  247. bool CheckVS1003B_DRQ(void)
  248. {
  249.         bool bResult;

  250.         bResult =MP3_DREQ;
  251.         return(bResult);
  252. }

  253. /***********************************************************/
  254. /*  函数名称 :  VsSineTest                                 */
  255. /*  函数功能 : vs1003正弦测试,将该函数放在while循环中,  */
  256. /*              如果能持续听到一高一低的声音,证明测试通过 */                           
  257. /*  参数     :  无                                         */
  258. /*  返回值   :  无                                         */
  259. /*---------------------------------------------------------*/
  260. void VsSineTest(void)
  261. {
  262.         Mp3PutInReset();  //xReset = 0   复位vs1003
  263.         wait(200);        //延时100ms        
  264.         SPIPutChar(0xff);//发送一个字节的无效数据,启动SPI传输
  265.         Mp3DeselectControl();  
  266.         Mp3DeselectData();     
  267.         Mp3ReleaseFromReset();
  268.         wait(200);                       
  269.         Mp3SetVolume(50,50);  

  270.          Mp3WriteRegister(SPI_MODE,0x08,0x20);//进入vs1003的测试模式
  271.         while (MP3_DREQ == 0);     //等待DREQ为高
  272.          Mp3SelectData();       //xDCS = 1,选择vs1003的数据接口
  273.          
  274.          //向vs1003发送正弦测试命令:0x53 0xef 0x6e n 0x00 0x00 0x00 0x00
  275.          //其中n = 0x24, 设定vs1003所产生的正弦波的频率值,具体计算方法见vs1003的datasheet
  276.            SPIPutChar(0x53);      
  277.         SPIPutChar(0xef);      
  278.         SPIPutChar(0x6e);      
  279.         SPIPutChar(0x24);      
  280.         SPIPutChar(0x00);      
  281.         SPIPutChar(0x00);
  282.         SPIPutChar(0x00);
  283.         SPIPutChar(0x00);
  284. //        wait(500);
  285.         wait(250);
  286.         wait(250);
  287.         Mp3DeselectData();//程序执行到这里后应该能从耳机听到一个单一频率的声音
  288.   
  289.         //退出正弦测试
  290.         Mp3SelectData();
  291.         SPIPutChar(0x45);
  292.         SPIPutChar(0x78);
  293.         SPIPutChar(0x69);
  294.         SPIPutChar(0x74);
  295.         SPIPutChar(0x00);
  296.         SPIPutChar(0x00);
  297.         SPIPutChar(0x00);
  298.         SPIPutChar(0x00);
  299. //        wait(500);
  300.         wait(250);
  301.         wait(250);

  302.         Mp3DeselectData();

  303.         //再次进入正弦测试并设置n值为0x44,即将正弦波的频率设置为另外的值
  304.     Mp3SelectData();      
  305.         SPIPutChar(0x53);      
  306.         SPIPutChar(0xef);      
  307.         SPIPutChar(0x6e);      
  308.         SPIPutChar(0x44);      
  309.         SPIPutChar(0x00);      
  310.         SPIPutChar(0x00);
  311.         SPIPutChar(0x00);
  312.         SPIPutChar(0x00);
  313. //        wait(500);
  314.         wait(250);
  315.         wait(250);

  316.         Mp3DeselectData();

  317.         //退出正弦测试
  318.         Mp3SelectData();
  319.         SPIPutChar(0x45);
  320.         SPIPutChar(0x78);
  321.         SPIPutChar(0x69);
  322.         SPIPutChar(0x74);
  323.         SPIPutChar(0x00);
  324.         SPIPutChar(0x00);
  325.         SPIPutChar(0x00);
  326.         SPIPutChar(0x00);
  327. //        wait(500);
  328.         wait(250);
  329.         wait(250);

  330.         Mp3DeselectData();
  331. }

  332. void test_1003_PlayMP3File();

  333. void TestVS1003B(void)
  334. {
  335.         Mp3Reset();
  336.         VsSineTest();
  337.         Mp3SoftReset();
  338.         test_1003_PlayMP3File();
  339. }

  340. //写寄存器,参数,地址和数据
  341. void VS1003B_WriteCMD(unsigned char addr, unsigned int dat)
  342. {
  343. /*
  344.         VS1003B_XDCS_H();
  345.         VS1003B_XCS_L();
  346.         VS1003B_WriteByte(0x02);
  347.         //delay_Nus(20);
  348.         VS1003B_WriteByte(addr);
  349.         VS1003B_WriteByte(dat>>8);
  350.         VS1003B_WriteByte(dat);
  351.         //delay_Nus(200);
  352.         VS1003B_XCS_H();
  353. */
  354.         Mp3WriteRegister(addr,dat>>8,dat);
  355. }

  356. //读寄存器,参数 地址 返回内容
  357. unsigned int VS1003B_ReadCMD(unsigned char addr)
  358. {
  359. /*
  360.         unsigned int temp;
  361.         unsigned char temp1;
  362.         VS1003B_XDCS_H();
  363.         VS1003B_XCS_L();
  364.         VS1003B_WriteByte(0x03);
  365.         //delay_Nus(20);
  366.         VS1003B_WriteByte(addr);
  367.         temp=  VS1003B_ReadByte();
  368.         temp=temp<<8;
  369.         temp1= VS1003B_ReadByte();
  370.         temp=temp|temp1;;
  371.         VS1003B_XCS_H();
  372.         return temp;
  373. */
  374.         return(Mp3ReadRegister(addr));
  375. }

  376. //写数据,音乐数据
  377. void VS1003B_WriteDAT(unsigned char dat)
  378. {
  379. //        VS1003B_XDCS_L();
  380. //        VS1003B_WriteByte(dat);
  381. //        VS1003B_XDCS_H();
  382. //        VS1003B_XCS_H();

  383.            Mp3SelectData();
  384.         SPIPutChar(dat);
  385.         Mp3DeselectData();
  386.         Mp3DeselectControl();

  387. }

  388. //开启环绕声
  389. void VS1003B_SetVirtualSurroundOn(void)
  390. {
  391.         uchar ucRepeatCount;
  392.         uint uiModeValue;

  393.         ucRepeatCount =0;

  394.         while(1)//写时钟寄存器
  395.         {
  396.                 uiModeValue = VS1003B_ReadCMD(0x00);
  397.                 if(uiModeValue & 0x0001)
  398.                 {
  399.                         break;
  400.                 }
  401.                 else
  402.                 {
  403.                         uiModeValue |= 0x0001;
  404.                         VS1003B_WriteCMD(0,uiModeValue);
  405.                 }
  406.                 ucRepeatCount++;
  407.                 if(ucRepeatCount++ >10 )break;
  408.         }

  409. }

  410. //关闭环绕声
  411. void VS1003B_SetVirtualSurroundOff(void)
  412. {
  413.         uchar ucRepeatCount;
  414.         uint uiModeValue;

  415.         ucRepeatCount =0;

  416.         while(1)//写时钟寄存器
  417.         {
  418.                 uiModeValue = VS1003B_ReadCMD(0x00);
  419.                 if(uiModeValue & 0x0001)
  420.                 {
  421.                         break;
  422.                 }
  423.                 else
  424.                 {
  425.                         uiModeValue |= 0x0001;
  426.                         VS1003B_WriteCMD(0,uiModeValue);
  427.                 }
  428.                 ucRepeatCount++;
  429.                 if(ucRepeatCount++ >10 )break;
  430.         }

  431. }

  432. //增强重音
  433. //入口参数        1.强度0-15
  434. //                        2.频率0-15 (X10Hz)
  435. void VS1003B_SetBassEnhance(uchar ucValue, ucFrequencyID)
  436. {
  437.         uchar ucRepeatCount;
  438.         uint uiWriteValue;
  439.         uint uiReadValue;        

  440.         ucRepeatCount =0;

  441.         uiWriteValue = VS1003B_ReadCMD(0x02);

  442.         uiWriteValue &= 0xFF00;
  443.         uiWriteValue |= ucValue<<4;
  444.         uiWriteValue &= (ucFrequencyID & 0x0F);

  445.         while(1)//写时钟寄存器
  446.         {

  447.                 VS1003B_WriteCMD(2,uiWriteValue);
  448.                 uiReadValue = VS1003B_ReadCMD(0x02);
  449.                
  450.                 if(uiReadValue == uiWriteValue)
  451.                 {
  452.                         break;
  453.                 }
  454.                 ucRepeatCount++;
  455.                 if(ucRepeatCount++ >10 )break;
  456.         }

  457. }


  458. uint uiVolumeCount;                //当前音量值

  459. //VS1003初始化,0成功 1失败
  460. unsigned char VS1003B_Init()
  461. {
  462.         unsigned char retry;
  463. /*
  464.         PORT_INI();
  465.         DDRB|=0xa0;
  466.         VS1003B_DDR &=~(1<<VS1003B_DREQ);
  467.         //delay_Nus(50);
  468.         VS1003B_XCS_H();
  469.         VS1003B_XDCS_H();
  470.         VS1003B_XRESET_L();
  471.         VS1003B_Delay(0xffff);
  472.         VS1003B_XRESET_H();//使能芯片
  473.         VS1003B_SPI_Low();//先以低频操作
  474.         VS1003B_Delay(0xffff);//延时
  475. */
  476. Mp3Reset();

  477.         retry=0;
  478.         while(VS1003B_ReadCMD(0x00) != 0x0800)//写mode寄存器
  479.         {
  480.                 VS1003B_WriteCMD(0x00,0x0800);
  481.                 if(retry++ >10 )break;//{PORTB|=_BV(PB1);break;}
  482.         }
  483.         retry=0;
  484.         /*while(VS1003B_ReadCMD(0x02) != 0x75)//写mode寄存器
  485.         {
  486.                 VS1003B_WriteCMD(0x02,0x75);
  487.                 if(retry++ >10 )break;//{PORTB|=_BV(PB1);break;}
  488.         }*/
  489.         retry=0;
  490.         while(VS1003B_ReadCMD(0x03) != 0x9800)//写时钟寄存器
  491.         {
  492.                 VS1003B_WriteCMD(0x03,0x9800);
  493.                 if(retry++ >10 )break;
  494.         }
  495. ……………………

  496. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
VS1003&amp;1053模块.rar (6.28 MB, 下载次数: 139)
回复

使用道具 举报

ID:475031 发表于 2019-2-5 22:21 | 显示全部楼层
这个呵呵,好
回复

使用道具 举报

ID:485223 发表于 2019-3-7 00:28 | 显示全部楼层
你好,为什么下载以后打不开,能不能重新发个连接。拜托了
回复

使用道具 举报

ID:1 发表于 2019-3-7 00:39 | 显示全部楼层
adel 发表于 2019-3-7 00:28
你好,为什么下载以后打不开,能不能重新发个连接。拜托了

改文件扩展名为.rar就可以代开了
回复

使用道具 举报

ID:611525 发表于 2019-9-22 00:17 | 显示全部楼层
支持一下,
回复

使用道具 举报

ID:521117 发表于 2019-9-22 14:48 | 显示全部楼层
这个好厉害
回复

使用道具 举报

ID:447180 发表于 2019-11-8 12:39 | 显示全部楼层
感觉自己差好多  好好学学
回复

使用道具 举报

ID:25162 发表于 2019-12-4 19:36 | 显示全部楼层
还可以
回复

使用道具 举报

ID:689980 发表于 2020-2-4 16:31 | 显示全部楼层

感觉自己差好多  好好学学
回复

使用道具 举报

ID:498837 发表于 2020-3-6 11:13 | 显示全部楼层
谢谢楼主分享
回复

使用道具 举报

ID:824490 发表于 2020-12-9 14:06 | 显示全部楼层
收藏,备用。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表