久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 8752|回復: 8
打印 上一主題 下一主題
收起左側

第21章 單片機mp3播放器實驗

  [復制鏈接]
跳轉到指定樓層
樓主
51單片機輕松入門—基于STC15W4K系列(C語言版)
李友全
編著 詳見:http://www.zg4o1577.cn/bbs/dpj-37954-1.html

21MP3播放器實驗
1 電路圖
2 程序移植

本章實現的功能是單片機讀取SD卡中的MP3音樂文件進行自動播放。
1 電路圖

1號單片機與VS1003的接口電路

2 程序移植
程序中比較重要的代碼是VS1003的復位操作,每首歌曲播放完畢都需執行一次復位操作,否 則后面播放的音樂會出現模糊不清的問題,復位操作包括硬件復位與軟件復位。
void VS_Reset()
{
/////////// 硬件復位 //////////
unsigned char retry=0;
VS_XDCS=1; // 取消數據傳輸 VS_XCS=1; // 取消指令傳輸 VS_XRESET=1;
delay(10);
VS_XRESET=0; // 硬件低電平復位 delay100mS(); // 延時100ms VS_XRESET=1;
while(VS_DREQ==0&&retry<200) // 等待DREQ為高
{
retry++;
delay50us();
};
delay20ms();
/////////// 軟件復位 //////////

VS_Write_Reg(0x00,0x08,0x04); // 軟件復位,向模式寄存器寫入0x0804即可

/////////// 初始化 ////////// VS_Write_Reg(0x03,0x98,0x00); // 時鐘設置,3倍頻 VS_Write_Reg(0x0b,0x00,0x00); // 音量設置,左右聲道均最大音量

VS_XDCS=0; // 打開數據片選,注意此時XCS(片選)為高電平 SPI_WriteByte(0);

// 寫入數據,這里寫入4個字節00或FF,是無關數據,用來啟動數據傳輸 SPI_WriteByte(0);

SPI_WriteByte(0); SPI_WriteByte(0);

VS_XDCS=1; // 關閉數據片選 if(retry>=200)return 1; // 硬件復位失敗 else return 0; // 硬件復位成功

}


部分程序預覽:
vs1003.c文件:
  1. #include "vs1003.h"
  2. #include "patch.h"
  3. #include "myfun.h"
  4. /****************《51單片機輕松入門-基于STC15W4K系列》配套例程 *************
  5. ★★★★★★★★★★★★★★★★★★★★★★★★
  6. 《51單片機輕松入門-基于STC15W4K系列》 一書已經由北航出版社正式出版發行。
  7.   作者親手創作的與教材配套的51雙核實驗板(2個MCU)對程序下載、調試、仿真方便,不需要外部
  8.   仿真器與編程器,這種設計方式徹底解決了系統中多個最高優先級誰也不能讓誰的中斷競爭問題。
  9.   QQ群:STC51-STM32(3) :515624099 或 STC51-STM32(2):99794374。
  10.         驗證信息:STC15單片機
  11.   郵箱:xgliyouquan@126.com
  12.   ★★★★★★★★★★★★★★★★★★★★★★★★*/
  13. unsigned char bdata dat; //dat是可位尋址的變量

  14. sbit dat7=dat^7;
  15. sbit dat6=dat^6;
  16. sbit dat5=dat^5;
  17. sbit dat4=dat^4;
  18. sbit dat3=dat^3;
  19. sbit dat2=dat^2;
  20. sbit dat1=dat^1;
  21. sbit dat0=dat^0; //取出dat的各個位

  22. /******************************************************************
  23. 功能:IO模擬SPI,發送一個字節
  24. ******************************************************************/
  25. void SPI_WriteByte(unsigned char x)
  26. {
  27.         dat=x;              // 將x的值賦給可位尋址的變量dat,以便取出各個位
  28.         
  29.         SPI_SI=dat7;  // 取出第7個位,寫到數據線上
  30.         SPI_SCLK=0;
  31.         SPI_SCLK=1;          // 時鐘線產生上升沿,數據被寫入
  32.         
  33.         SPI_SI=dat6;
  34.         SPI_SCLK=0;
  35.         SPI_SCLK=1;
  36.         
  37.         SPI_SI=dat5;
  38.         SPI_SCLK=0;
  39.         SPI_SCLK=1;
  40.         
  41.         SPI_SI=dat4;
  42.         SPI_SCLK=0;
  43.         SPI_SCLK=1;
  44.         
  45.         SPI_SI=dat3;
  46.         SPI_SCLK=0;
  47.         SPI_SCLK=1;
  48.         
  49.         SPI_SI=dat2;
  50.         SPI_SCLK=0;
  51.         SPI_SCLK=1;
  52.         
  53.         SPI_SI=dat1;
  54.         SPI_SCLK=0;
  55.         SPI_SCLK=1;
  56.         
  57.         SPI_SI=dat0;
  58.         SPI_SCLK=0;
  59.         SPI_SCLK=1;
  60. }

  61. /******************************************************************
  62. 功能:IO模擬SPI,讀取一個字節
  63. ******************************************************************/
  64. //unsigned char SPI_ReadByte()
  65. //{  
  66. //        SPI_SO=1;
  67. //        
  68. //        SPI_SCLK=1;
  69. //        delay(1);
  70. //        SPI_SCLK=0;
  71. //        delay(1);
  72. //        dat7=SPI_SO;
  73. //        
  74. //        SPI_SCLK=1;
  75. //        delay(1);
  76. //        SPI_SCLK=0;
  77. //        delay(1);
  78. //        dat6=SPI_SO;
  79. //        
  80. //        SPI_SCLK=1;
  81. //        delay(1);
  82. //        SPI_SCLK=0;
  83. //        delay(1);
  84. //        dat5=SPI_SO;
  85. //        
  86. //        SPI_SCLK=1;
  87. //        delay(1);
  88. //        SPI_SCLK=0;
  89. //        delay(1);
  90. //        dat4=SPI_SO;
  91. //        
  92. //        SPI_SCLK=1;
  93. //        delay(1);
  94. //        SPI_SCLK=0;
  95. //        delay(1);
  96. //        dat3=SPI_SO;
  97. //        
  98. //        SPI_SCLK=1;
  99. //        delay(1);
  100. //        SPI_SCLK=0;
  101. //        delay(1);
  102. //        dat2=SPI_SO;
  103. //        
  104. //        SPI_SCLK=1;
  105. //        delay(1);
  106. //        SPI_SCLK=0;
  107. //        delay(1);
  108. //        dat1=SPI_SO;
  109. //        
  110. //        SPI_SCLK=1;
  111. //        delay(1);
  112. //        SPI_SCLK=0;
  113. //        delay(1);
  114. //        dat0=SPI_SO;
  115. //        
  116. //        return dat;
  117. //}


  118. /******************************************************************
  119. 功能:向VS1003的功能寄存器中寫入數據(兩個字節)
  120. 參數:addr是功能寄存器的地址
  121.       hdat是要寫入的高字節
  122.       ldat是要寫入的低字節
  123. ******************************************************************/
  124. void VS_Write_Reg(unsigned char addr,unsigned char hdat,unsigned char ldat)
  125. {  
  126.         VS_DREQ=1;            // 51單片機IO作輸入時先置為1
  127.         while(!VS_DREQ);      // VS1003的DREQ為高電平時才接收數據
  128.         VS_XCS=0;             // 打開命令片選,這樣才能對功能寄存器進行讀寫
  129.         SPI_WriteByte(0x02);  // 寫入操作碼0x02   00000010 (功能寄存器寫操作)
  130.         SPI_WriteByte(addr);  // 寫入寄存器地址
  131.         SPI_WriteByte(hdat);  // 寫入高字節
  132.         SPI_WriteByte(ldat);  // 寫入低字節   
  133.         VS_XCS=1;             // 關閉命令片選
  134. }

  135. /******************************************************************
  136. 功能:從VS1003的功能寄存器中讀取數據(2個字節)
  137. 參數:addr是功能寄存器的地址
  138. 返回:返回從VS1003的功能寄存器中讀到的值
  139. ******************************************************************/
  140. //unsigned int VS_Read_Reg(unsigned char addr)
  141. //{
  142. //        unsigned int temp=0;
  143. //        VS_DREQ=1;            // 51單片機IO作輸入時先置為1   
  144. //        while(!VS_DREQ);      // VS1003的DREQ為高電平時才接收數據
  145. //        VS_XCS=0;                  // 打開命令片選,這樣才能對功能寄存器進行讀寫
  146. //        SPI_WriteByte(0x03);  // 讀出操作碼0x03   00000011(功能寄存器讀操作)
  147. //        SPI_WriteByte(addr);  // 寫入寄存器地址
  148. //        temp=SPI_ReadByte();  // 讀高字節
  149. //        temp<<=8;
  150. //        temp|=SPI_ReadByte(); // 讀取低字節,與高字節拼成一個整數
  151. //        
  152. //        VS_XCS=1;                  // 關閉命令片選
  153. //        return temp;          // 返回讀到的值
  154. //}        

  155. /******************************************************************
  156. 功能:VS1003硬件復位+軟件復位+初始化(設置時鐘頻率及音量)
  157. ******************************************************************/
  158. unsigned char VS_Reset()
  159. {
  160.         ///////////  硬件復位 //////////
  161.         unsigned char retry=0;
  162.         VS_XDCS=1;             // 取消數據傳輸
  163.         VS_XCS=1;             // 取消指令傳輸
  164.         VS_XRESET=1;
  165.         delay(10);                 
  166.         VS_XRESET=0;         // 硬件低電平復位
  167.         delay100mS();         // 延時100ms
  168.         VS_XRESET=1;  
  169.         while(VS_DREQ==0&&retry<200)   //等待DREQ為高
  170.         {
  171.                 retry++;
  172.                 delay50us();
  173.         };            
  174.         delay20ms();        

  175.         ///////////  軟件復位 //////////
  176.         VS_Write_Reg(0x00,0x08,0x04); // 軟件復位,向模式寄存器寫入0x0804即可

  177.         ///////////  初始化 //////////
  178.         VS_Write_Reg(0x03,0x98,0x00); // 時鐘設置,3倍頻
  179.         VS_Write_Reg(0x0b,0x00,0x00); // 音量設置,左右聲道均最大音量
  180.         
  181.         VS_XDCS=0;                 // 打開數據片選,注意此時XCS(片選)為高電平
  182.         SPI_WriteByte(0);    // 寫入數據,這里寫入4個字節00或FF,是無關數據,用來啟動數據傳輸
  183.         SPI_WriteByte(0);
  184.         SPI_WriteByte(0);
  185.         SPI_WriteByte(0);
  186.         VS_XDCS=1;                 // 關閉數據片選

  187.         if(retry>=200)return 1;          // 硬件復位失敗
  188.         else return 0;                          // 硬件復位成功
  189. }

  190. /******************************************************************
  191. 功能:向VS1003寫入一個字節的音頻數據(即用于播放的數據)
  192. 參數:dat是要寫入的字節
  193. ******************************************************************/
  194. void VS_Send_Dat(unsigned char dat)
  195. {
  196.         VS_XDCS=0;           // 打開數據片選
  197.         VS_DREQ=1;
  198.         while(!VS_DREQ);     // VS1003的DREQ為高才能寫入數據
  199.         SPI_WriteByte(dat);  // 通過SPI向VS1003寫入一個字節的音頻數據
  200.         VS_XDCS=1;           // 關閉數據片選
  201. }

  202. /******************************************************************
  203. 功能:向VS1003寫入2048個0,用于清空VS1003的數據緩沖區,在播放完一個完整的音頻(如MP3)
  204.       后,調用函數,清空VS1003數據緩沖區,為下面的音頻數據(如下一首MP3)作準備。
  205. ******************************************************************/
  206. void VS_Flush_Buffer()
  207. {
  208.         unsigned int i;
  209.         VS_XDCS=0;                 // 打開數據片選
  210.         for(i=0;i<2048;i++)
  211.         {
  212.                 VS_Send_Dat(0);
  213.         }
  214.         VS_XDCS=1;           // 關閉數據片選
  215. }

  216. /******************************************************************
  217. 功能:正弦測試,這是測試VS1003芯片是否正常的有效手段。
  218. 參數:x決定了正弦測試中產生的正弦波的頻率,直接影響聽到的聲音的頻率
  219. ******************************************************************/
  220. void VS_sin_test(unsigned char x)
  221. {
  222.         VS_Write_Reg(0x00,0x08,0x20);  // 啟動正弦測試,
  223.         VS_DREQ=1;
  224.         while(!VS_DREQ);               // 等待DREQ變為高電平
  225.         VS_XDCS=0;                           // 打開數據片選 SDI有效
  226.         SPI_WriteByte(0x53);           // 寫入以下8個字節,進入正弦測試
  227.         SPI_WriteByte(0xef);                    // 正弦測試命令:0x53 0xef 0x6e xx 0x00 0x00 0x00 0x00
  228.         SPI_WriteByte(0x6e);
  229.         SPI_WriteByte(x);   // 參數x用來調整正弦測試中正弦波的頻率
  230.         SPI_WriteByte(0);   // 比如x=126 (0b 011 11110) FsIdx=011=3   Fs=22050Hz   S=11110=30    F=22050Hz X 30 /128 =5168 Hz
  231.         SPI_WriteByte(0);
  232.         SPI_WriteByte(0);
  233.         SPI_WriteByte(0);

  234.         delay200mS();                  // 這里延時一段時間,為了聽到“正弦音”         

  235.         SPI_WriteByte(0x45);  //寫入以下8個字節,退出正弦測試
  236.         SPI_WriteByte(0x78);
  237.         SPI_WriteByte(0x69);
  238.         SPI_WriteByte(0x74);
  239.         SPI_WriteByte(0);
  240.         SPI_WriteByte(0);
  241.         SPI_WriteByte(0);
  242.         SPI_WriteByte(0);
  243.         VS_XDCS=1;                 // 關閉數據片選  
  244. }

  245. /******************************************************************
  246. 功能:為VS1003打補丁,獲得實時頻譜,atab與dtab是VS1003頻譜功能補丁碼,在patch.h中
  247. ******************************************************************/
  248. void LoadPatch()
  249. {
  250.         unsigned int i;
  251.         for(i=0;i<943;i++)
  252.         {
  253.                 VS_Write_Reg(atab[i],dtab[i]>>8,dtab[i]&0xff);
  254.         }
  255. }
復制代碼




所有完整源碼下載: 第21章 MP3播放器.rar (9.79 MB, 下載次數: 118)
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏8 分享淘帖 頂1 踩
回復

使用道具 舉報

沙發
ID:113189 發表于 2016-8-11 20:25 | 只看該作者
學習,希望能學會
回復

使用道具 舉報

板凳
ID:140218 發表于 2016-9-29 23:42 | 只看該作者
好東西,正在研究之中
回復

使用道具 舉報

地板
ID:142974 發表于 2016-10-17 17:56 | 只看該作者
有仿真文件嗎 怎么找不到?
回復

使用道具 舉報

5#
ID:171696 發表于 2017-3-19 17:38 | 只看該作者
好東西,正是我到處找的東西
回復

使用道具 舉報

6#
ID:314710 發表于 2018-4-24 20:17 | 只看該作者
感謝!
回復

使用道具 舉報

7#
ID:393796 發表于 2018-10-23 23:45 | 只看該作者
感謝樓主分享
回復

使用道具 舉報

8#
ID:288930 發表于 2019-1-18 14:01 | 只看該作者
謝謝分享!
回復

使用道具 舉報

9#
ID:229361 發表于 2019-3-17 11:55 | 只看該作者
好東西,感謝樓主分享
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美日韩电影一区二区 | av高清毛片 | 香蕉视频91 | 日韩av成人 | 成人性视频免费网站 | 18gay男同69亚洲网站 | 日本在线一区二区三区 | 国产精品一区二区三区在线 | 国产精品久久久久久久久久 | 精品久久久久久久人人人人传媒 | 国产区在线 | 在线成人免费av | 精品久久久久久久久久久久 | 精品久久视频 | 蜜臀久久99精品久久久久久宅男 | 午夜免费视频 | 免费久久网站 | 亚洲精品aⅴ | 国产成人免费视频网站高清观看视频 | 99精品一区二区三区 | 久久久久国 | 男女羞羞视频在线免费观看 | 一区精品国产欧美在线 | av电影一区二区 | 免费网站国产 | 亚洲精品一区中文字幕 | 欧美一区二区三区在线看 | 99这里只有精品视频 | 欧美成人激情 | 亚洲精品国产第一综合99久久 | 国产成人精品午夜 | 热久色| 精品久久精品 | 日本欧美国产在线 | 亚洲人在线观看视频 | 青娱乐自拍 | 北条麻妃99精品青青久久 | 国产精品视频久久久 | 日韩一区二区在线视频 | 紧缚调教一区二区三区视频 | 综合久久99 |