有一個東西你一定聽說過或用過,那就MP3播放器。MP3播放器以其小巧的體積、強大的功能、優異的音質倍受人們的青睞。如果把它嵌入到我們的單片機系統中,實現音頻輸出,那么對系統的增色是不言而喻的。單獨拿單片機來說,要解碼MP3文件,是不可能的,因為從處理速度和資源各個方面都是不能滿足要求的。所以要依賴于專用MP3解碼芯片,而單片機要作的就是對其進行控制。這里我們圍繞芬蘭VLSI公司出品的VS1003來進行解MP3的實現方法。
1、VS1003芯片
1)芯片簡介
VS1003是由荷蘭VLSI公司出品的一款單芯片的MP3/WMA/MIDI音頻解碼和ADPCM編碼芯片,其擁有一個高性能低功耗的DSP處理器核VS_DSP,5K的指令RAM,0.5K的數據RAM,串行的控制和數據輸入接口, 4個通用IO口,一個UART口;同時片內帶有一個可變采樣率的ADC、一個立體聲DAC以及音頻耳機放大器。
VS1003通過一個串行接口來接收輸入的比特流,它可以作為一個系統的從機。輸入的比特流被解碼,然后通過一個數字竟是控制器到達一個18位過采樣多位 ε-ΔDAC。通過串行總線控制解碼器。除了基本的解碼,在用戶RAM中它還可以做其他特殊應用,例如DSP音效處理。
2)芯片實物與SiriuS板上的VS1003
3)芯片封裝
以下的講述都是針對于LQFP-48封裝的。
4)VS1003特性
1.能解碼MPEG1 與MPEG2音頻層III(CBR+VBR+ABR);WMA 4.0/4.1/7/8/9 5~384kbps所有流文件;WAV(PCM+IMA AD-PCM);產生MIDI/SP-MIDI文件。
2.對話筒輸入或線路輸入的音頻信號進行IMA ADPCMM編碼
3.支持MP3和WAVV流
4.高低音控制
5.單時鐘12~13MHz
6.內部PLLL鎖相環時鐘倍頻器
7.低功耗
8.內含高性能片上立體聲數模轉換器,兩聲道間無相位差
9.內含能驅動30歐負載的耳機驅動器
10.模擬,數字,I/O單獨供電
11.為用戶代碼和數據準備的5.5KB片上RAM
12.串行的控制/數據接口
13.可被用作微處理器的從機
14.特殊應用的SPI Flash引導
15.借高度用途的UART接口
16.新功能可以通過軟件和4 GPIO添加
5)VS1003的引腳定義
管腳名稱 |
LQFP-48 |
管腳類型 |
管腳功能 |
MICP |
1 |
AI |
同相差分話筒輸入,自偏壓 |
MICN |
2 |
AI |
反相差分話筒輸入,自偏壓 |
XRESET |
3 |
DI |
低電平有效,異步復位端 |
DGND0 |
4 |
DGND |
處理器核與I/O地 |
CVDD0 |
5 |
CPWR |
處理器核電源 |
IOVDD0 |
6 |
IOPWR |
I/O電源 |
CVDD1 |
7 |
CPEW |
處理器核電源 |
DREQ |
8 |
DO |
數據請求,輸入總線 |
GPIO/DCLK |
9 |
DIO |
通用I/O2 /串行數據總線時鐘 |
GPIO3/SDATA |
10 |
DIO |
通用I/O3 /串行數據總線數據 |
XDCS/BSYNC |
13 |
DI |
數據片選端/字節同步 |
IOVDD1 |
14 |
IOPWR |
I/O 電源 |
VCO |
15 |
DO |
時鐘壓控振蕩器VCO 輸出 |
DGND1 |
16 |
DGND |
處理器核與I/O 的地 |
XTALO |
17 |
AO |
晶振輸出 |
XTALI |
18 |
AI |
晶振輸入 |
IOVDD2 |
19 |
IOPWR |
I/O 電源 |
DGND2 |
20 |
DGND |
處理器核與I/O 地 |
DGND3 |
21 |
DGND |
處理器核與I/O 地 |
DGND4 |
22 |
DGND |
處理器核與I/O 地 |
XCS |
23 |
DI |
片選輸入,低電平有效 |
CVDD2 |
24 |
CPWR |
處理器核電源 |
RX |
26 |
DI |
UART接收口,不用時接IOVDD |
TX |
27 |
DO |
UART發送口 |
SCLK |
28 |
DI |
串行總線的時鐘 |
SI |
29 |
DI |
串行輸入 |
SO |
30 |
DO3 |
串行輸出 |
CVDD3 |
31 |
CPWR |
處理器核電源 |
TEST |
32 |
DI |
保留做測試,連接至IOVDD |
GPIO0/SPIBOOT |
33 |
DIO |
通用I/O0 /SPIBOOT,使用100K 下拉電阻 |
GPIO1 |
34 |
DIO |
通用I/O1 |
AGND0 |
37 |
APWR |
模擬地,低噪聲參考地 |
AVDD0 |
38 |
APWR |
模擬電源 |
RIGHT |
39 |
AO |
右聲道輸出 |
AGND1 |
40 |
APWR |
模擬地 |
AGND2 |
41 |
APWR |
模擬地 |
GBUF |
42 |
AO |
公共地緩沖器 |
AVDD1 |
43 |
APWR |
模擬電源 |
RCAP |
44 |
AIO |
基準濾波電容 |
AVDD2 |
45 |
APWR |
模擬電源 |
LEFT |
46 |
AO |
左聲道輸出 |
AGND3 |
47 |
APWR |
模擬地 |
LINE IN |
48 |
AI |
線路輸入 |
6)VS1003的功能寄存器
VS1003共有16個16位的寄存器,地址分別為0X0~0XF;除了模式寄存器(MODE,0X0)和狀態寄存器(STATUS,0X1)在復位后的初始值分別為0X800和OX3C外,其余的寄存器在VS1003初始化后的值均為0。下面將VS1003各寄存器逐一進行介紹。
1.MODE(地址:0X0 可讀寫)
bit0:SM_DIFF
SM_DIFF=0 正常音頻相位
SM_DIFF=1 左聲道反轉
當SM_DIFF置位時,VS1003將左聲道反相輸出,立體聲輸入將產生環繞效果,對于單聲道輸入將產生差分(反相)左/右聲道信號。
bit1:SM_SETTOZERO
置零。
bit2:SM_RESET
SM_RESET=1,VS1003軟復位。軟復位之后該位會自動清零。
bit3:SM_OUTOFWAV
SM_OUTOFWAV=1,停止WAV解碼。
當你要中途停止WAV、WMA或者MIDI文件的解碼時,置位SM_OUTOFWAV,并向VS1003持續發送數據(對于WAV文件發送0)直到將SM_OUTOFWAV清零;同時SCI_HIDAT1也將被清零。
bit4:SM_PDOWN
SM_PDOWN=1,軟件省電模式,該模式不及硬件省電模式(可由VS1003的XRESET來激活)。
bit5:SM_TESTS
SM_TESTS=1,進入SDI測試模式。
bit6:SM_STREAM
SM_STREAM=1,使能VS1003的流模式。
bit7:SM_PLUSV
SM_PLUSV=1,MP3+V解碼使能。
bit8:SM_DACT
SM_DACT=0,SCLK上升沿有效;SM_DACT=1,SCLK下降沿有效。
bit9:SM_SDIORD
SM_SDIORD=0,SDI總線字節數據MSB在前,即須先發送MSB;
SM_SDIORD=1,SDI總線字節數據LSB在前,即須先發送LSB;
該位的設置不會影響SCI總線。
bit10:SM_SDISHARE
SM_SDISHARE=1,SDI與SCI將共用一個片選信號(同時SM_SDINEW=1),即將XDCS與XCS這兩根信號線合為一條,能省去一個IO口。
bit11:SM_SDINEW
SM_SDINEW=1,VS1002本地模式(新模式)。VS1003在啟動后默認進入該模式。(這里所說的模式指的是總線模式。)
bit12:SM_ADPCM
SM_ADPCM=1,ADPCM錄音使能。
同時置位SM_ADPCM和SM_RESET將使能VS1003的IMA ADPCM錄音功能。
bit13:SM_ADPCM_HP
SM_ADPCOM_HP=1,使能ADPCM高通濾波器。同時置位SM_ADPCM_HP、SM_ADPCM和SM_RESET將開啟ADPCM錄音用高通濾波器,對錄音時的背景噪音有一定的抑制作用。
bit14:SM_LINE_IN
錄音輸入選擇,SMLINE_IN=1,選擇線入(line in);SM_LINE_IN=0,選擇麥克風輸入(默認)。
2.SCI_STATUS(地址:0X1 可讀寫)
SCI_STATUS為VS1003的狀態寄存器,提供VS1003當前狀態信息。
3.SCI_BASS(地址:0X2 可讀寫)
重音/高音設置寄存器。
VS1003的內置的重音增強器VSBE是種高質量的重音增強DSP算法,能夠最大限度的避免音頻削波。當SB_AMPLITUDE(bit:7~4)不為零時,重音增強器將使能?梢愿鶕䝼人需要來設置SB_AMPLITUDE。例如,SCI_BASS=0x00f6,即對60Hz以下的音頻信號進行 15dB的增強。當ST_AMPLITUDE(bit:15~12)不為零時,高音增強將使能。例如,SCI_BASS=0x7a00,即10kHz以上的音頻信號進行10.5dB的增強。
4.SCI_CLOCKF(地址:0X3 可讀寫)
bit15~bit13:SC_MULT
時鐘輸入XTALI的倍頻設置,設置之后將啟動VS1003內置的倍頻器。
bit12~bit11:SC_ADD
用于在WMA流解碼時給倍頻器增加的額外的倍頻值。
bit10~bit0:SC_FREQ
當XTALI輸入的時鐘不是12.288M時才需要設置該位段,其默認值為0,即VS1003默認使用的是12.228M的輸入時鐘。
5.SCI_DECODE_TIME(地址:0X4 可讀寫)
解碼時間寄存器。當進行正確的解碼時,讀取該寄存器可以獲得當前的解碼時長(單位為秒)?梢愿脑摷拇嫫鞯闹,但是新值須要對該寄存器進行兩次寫操作。在每次軟件復位或是WAV(PCM、IMA ADPCM、WMA、MIDI)解碼開始與結束時SCI_DECODE_TIME的值將清零。
6.SCI_AUDATA(地址:0X5 可讀寫)
當進行正確的解碼時,該寄存器的值為當前的采樣率(bit:15~bit1)和所使用的聲道(bit0)。采樣率須為2的倍數;bit0=0,單聲道數據,bit0=1,立體聲數據。寫該寄存器半直接改變采樣率。
7.SCI_WRAM(地址:0X6 可讀寫)
讀寄存器用來加載用戶應用程序和數據到VS1003的指令的數據RAM中。起始地址在SCI_WRAMADDR中進行設置,且必須先于讀寫 SCI_WRAM。對于16位的數據可以在進行一次SCI_WRAM的讀寫中完成;而對32位的指令字來說則需要兩次連續讀寫。字節順序是大端模式,即高字節在前,低字節在后。在每一次完成全字讀寫后,內部指針將自動增加。
8. SCI_WRAMADDR(地址:0X7 可讀寫)
用于設置RAM讀寫的首地址。
9.SPI_HDAT0gng SPI_HDAT1(地址:0X8 只讀)
這兩個寄存器用來存放所解碼的音頻文件的相關信息,為只讀寄存器。
當為WAV文件時,SPI_HDAT0=0X7761,SPI_HDAT1=0X7665;
當為WMA文件時,SPI_HDAT0的值為解碼速率(字節/秒),要轉換為位率的話則將SPI_HDAT0的值乘8即可,SPI_HDAT1=0X574D;
當為MIDI文件時,SPI_HDAT0的值可以參考VLSI的技術文檔第33頁,SPI_HDAT1=0X4D54;
當為MP3文件時,SPI_HDAT0和SPI_HDAT1包含較為復雜的信息(來自于解壓之后的MP3文件頭),包括當前正在 解碼的MP3文件的采樣率、位率等,具體請參考數據手冊的第33頁到第34頁。復位后SPI_HDAT0和SPI_HDAT1將清零。
10.SCI_AIADDR(地址:0XA 可讀寫)
用戶應用程序的起始地址,初始化先于SCI_WRAMADDR和SCI_WRAM。如果沒有使用任何用戶應用程序,則該寄存器不應進行初始化,或是將其初始化為零。
11.SCI_VOL(地址:0XB 可讀寫)
音量控制寄存器。高八位用于設置左聲道,低八位用于設置右聲道。設置值為最大竟是的衰減倍數,步進值為0.5dB,范圍為0到255.最大竟是的設置值為 0x0000,而靜音為0xffff。例如,左聲道:-2.0dB,右聲道:-3.5dB,則SCI_VOL=(4X256)+7=0x0407。硬件復位將使SCI_VOL清零(最大音量),而軟件復位將不改變音量設置值。
(設置靜音(SCI_COL=0XFFFF)將關閉模擬部分的供電。)
12.SCI_AICTRL[X](地址:0XC~0XF 可讀寫)
用于訪問用戶應用程序。
7)VS1003有應用電路
2、VS1003的驅動方法
這里就來介紹單片片對VS1003的控制方法,最終實現MP3播放。
1)準備工作
在對VS1003進行驅動之前,我們需要確保以下幾點已經沒問題,否則后面的工作都將是沒有意義的。
1.VS1003各部分的供電電壓與輸出電壓值是不同的。
供電部分 |
最小電壓 |
推薦電壓 |
最大電壓 |
AVDD(模擬部分) |
2.5V |
2.8V |
3.6V |
CVDD(數字部分,內核) |
2.4V |
2.5V |
2.7V |
IOVDD(I/O電壓) |
CVDD-0.6V |
2.8V |
3.6V |
2.VS1003與單片機正確可靠連接。
VS1003與單片機連接的引腳主要有7個,分別為 SO、SI、SCLK、/XCS、/XRESET、DREQ、/XDCS。只有保證它們與單片機正確可靠的連接,才能對VS1003進行有效的操作與控制。
2)寫命令操作
要控制VS1003首先要實現的就是寫命令,這是控制是否成功的前提。關于通信接口部分,是一種同步串行接口方式(SPI從機模式),它要求SCLK信號必須由外部電路產生,數據(SDATA)在SCLK的上升沿或下降沿時被寫入。在筆者的實驗中,采用的是軟件模擬SPI,讀者也可以選用帶有硬件SPI的單片機(如STC12系列、AVR系列等),驅動效果會更好。寫命令的過程如下:
1.等待DREQ為高(當DREQ為低時,說明芯片還沒有就緒)
2.將XCS(命令片選)拉低
3.寫入0x02
4.寫入寄存器地址
5.分別寫入數據的高字節與低字節
6.將XCS置高
實現代碼如下:
void wr_commad(unsigned char addr,unsigned char hdat,unsigned char ldat )
{
DREQ=1;
while(!DREQ);
XCS=0;
spi_write(0x02);
spi_write(addr);
spi_write(hdat);
spi_write(ldat);
XCS=1;
}
3)VS1003的初始化
如其它芯片一樣,初始化對于VS1003來說同樣是極其重要的。初始化的過程大致是這樣的:
1.硬件復位:接XRESET拉低
2.延時,將XDCS、XCS、XRESET置高
3.向MODE中寫入0X0804
4.等待DREQ為高
5.設置VS1003的時鐘:SCI_CLOCKF=0x9800,3倍頻
6.設置VS1003的采樣率:SPI_AUDATA=0xbb81,采樣率48k,立體聲
7.設置重音:SPI_BASS=0x0055
8.設置音量:SCI_VOL=0x2020
9.這一步被很多人忽視,向VS1003發送4個字節的無效數據,用以啟動SPI發送
實現代碼如下:
void Mp3Reset(void)
{
XRESET=0;
delay(100);
XDCS=XCS=XRESET=1;
wr_commad(0x00,0x08,0x04);
delay(10);
DREQ=1;
while(!DREQ);
wr_commad(0x03,0x98,0x00);
delay(10);
wr_commad(0x05,0xbb,0x81);
delay(10);
wr_commad(0x02,0x00,0x55);
delay(10);
wr_commad(0x0b,VOL_VALUE,VOL_VALUE); // 音量
delay(10);
spi_write(0);
spi_write(0);
spi_write(0);
spi_write(0);
}
在進行了正確的初始化后,還要著重檢查一下VS1003的模擬部分是否正常
將VS1003的所有DVDD、AVDD管腳以及XRESET、TEST(第32個引腳)接+3.0V,然后測量RCAP引腳,它應該是1.3V左右,否則芯片模擬部分未正常工作。
4)正弦測試
在上面的各種操作與檢測沒有問題后,就可以讓VS1003放出聲音了?梢岳肰S1003自帶的正弦測試對音頻輸出進行測試。要啟動 VS1003的正弦測試,需要向其寫入正弦測試命令。這里提供啟動正弦測試的流程,在真實的硬件運行通過,最終的效果是在耳機中聽到單一頻率的正弦音(頻率可以通過程序來更改)。
具體流程如下:
1.進入VS1003的測試模式:SPI_MODE=0X0820
2.等待DREQ為高
3.將XDCS接低,而XCS要置高,選擇VS1003的數據接口
4.向VS1003發送正弦測試命令:0X53 0XEF 0X6E 0X30 0X00 0X00 0X00 0X00
其中0X30為頻率,用戶可以修改為其它值
5.延時一段時間
6.退出正弦測試,發送命令:0X45 0X78 0X69 0X74 0X00 0X00 0X00 0X00
7.延時一段時間
8.循環以上流程
實現代碼如下:
void Sintest(unsigned char x)
{
wr_commad(0x00,0x08,0x20);
DREQ=1;
while(!DREQ);
XDCS=0;XCS=1;
spi_write(0x53);
spi_write(0xef);
spi_write(0x6e);
spi_write(x);
spi_write(0);
spi_write(0);
spi_write(0);
spi_write(0);
delay(5000);
spi_write(0x45);
spi_write(0x78);
spi_write(0x69);
spi_write(0x74);
spi_write(0);
spi_write(0);
spi_write(0);
spi_write(0);
delay(5000);
XDCS=1;
}
如果能夠通過這一步,就說明你的VS1003已經做好了為你播放MP3的準備了。下面的工作 就是將MP3文件的數據有條不紊地發給VS003,讓它來為你完成MP3的解碼和播放任務 。
5)MP3文件數據寫入
以上的對VS1003的初始化與測試都通過后,現在就可以給它發送MP3文件了。但是這時就又出現一個新的問題。MP3文件通常是比較大的,小的也要1M~2M,如果使單片機內部的Flash Rom的話,容量是遠遠不夠的。需要有一種大容量的存儲器來作為MP3文件的載體。在筆者的調試系統中采用了SD卡(256M)、U盤(1G)與移動硬盤(40G)來存儲MP3文件。關于SD卡與U盤的讀寫方法可以參看相關章節。這些大容量的存儲設備通常也是按照扇區來進行讀寫的,但在實際的應用中更多的是結合FAT32等文件系統來進行文件讀寫。文件系統部分可以參照《FAT32的存儲機制及其在單片機中的實現》。
這里拋開存儲介質不談,只談數據的寫入方法。其實寫入數據的方法十分簡單。主要就是看DREQ信號,在VS1003的FIFO能夠接受數據的時候輸出高電平。每次可以寫入32個字節的數據。而DREQ變低時,單片機就要停止數據的發送。
具體的寫數據的方法如下:
1.將XDCS拉低
2.等待DREQ為高
3.通過SPI寫入數據
4.在文件沒有結束前不斷重復2與3操作
5.在所有的數據都發送完畢后,最后發送2048個無效字節,用以清除VS1003的數據緩沖區
6.將XDCS置高
以下是筆者的程序中的寫數據部分:
XDCS=0;
for(j=621;j<2783;j++)
{
for(k=0;k<8;k++)
{
MMC_get_data_LBA(j,64,get);
for(i=0;i<64;i++)
{
DREQ=1;
while(!DREQ);
spi_write(get[i]);
//delay(60000);
}
}
}
for(temp=0;temp<2048;temp++)
{
DREQ=1;
while(!DREQ);
spi_write(0);
}
XDCS=1;