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


    原文:http://www.51hei.com/bbs/dpj-144165-1.html

    电路原理图如下:
    <ignore_js_op>0.png <ignore_js_op>0.png <ignore_js_op>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黑下载附件…………
    复制代码
     
  • 相关阅读:
    C#调试信息打印到输出窗口
    C#拼接SQL中in条件
    从图像到知识:深度神经网络实现图像理解的原理解析
    Cocoa Touch(六):App运行机制 NSRunLoop, KVC, KVO, Notification, ARC
    Cocoa Touch(五):网络请求 NSURLSession/AFNetworking, GCD, NSURLResquest
    JQuery:选择器、动画、AJAX请求
    Cocoa Touch(四): 多线程GCD, NSObject, NSThread, NSOperationQueue
    Socket、RPC通信实例,简单版本,仅供查阅
    Cocoa Touch(三):图形界面UIKit、Core Animation、Core Graphics
    Cocoa Touch(二):数据存储CoreData, NSKeyArchiver, NSOutputStream, NSUserDefaults
  • 原文地址:https://www.cnblogs.com/bruce1992/p/16653539.html
Copyright © 2020-2023  润新知