MP3播放器制作心歷——VS1003調試
在調試的時(shí)候只是拿網(wǎng)上找的代碼,做了相應的修改(接口改為我自己的,功能改為我自己想要的功能),這樣只是為了快速測試我的vs1003模塊能不能用,當然這首先是要你能理解其代碼,要不然是第一次調試你也不知道是程序有錯還是硬件有錯。在確定程序沒(méi)錯之后,我就可以確定如果沒(méi)有效果,那肯定是我的解碼模塊不行。測試通過(guò)之后我就可以放心的使用我自己的解碼模塊。接下來(lái)的程序我就可以根據自己想要的慢慢來(lái)寫(xiě)。
第一次寫(xiě)程序進(jìn)去就聽(tīng)到耳機里輸出了很高的鳴叫聲,這是因為我把正弦測試(vs1003自帶的一種測試,這樣就能很快確定你的vs1003是否能工作)頻率調的很高 所以聲音很尖,被嚇了一次。第二次就把它改小了一點(diǎn),嘟的一聲,呵呵相當激動(dòng),這說(shuō)明我的vs1003可以用(s1003非常脆弱 很容易壞 又貴又不好買(mǎi))
正弦測試成功之后我就開(kāi)始想給vs1003發(fā)送MP3音頻數據 看能不能解碼放出聲音來(lái)
我最初的想法是通過(guò)winhex軟件打開(kāi)查看MP3代碼然后拷貝出來(lái)作為一個(gè)數組發(fā)給vs1003。這個(gè)數據要儲存在我的單片機的程序儲存區里,還好我的單片機程序儲存區夠大有64K。這樣多的MP3代碼也只能夠聽(tīng)到一點(diǎn)點(diǎn)聲音,效果肯定是無(wú)法體會(huì )的道。果然 ,在耳機里只聽(tīng)到吱~的一聲就沒(méi)了 根本沒(méi)用
之后我就想把sd卡加進(jìn)來(lái),讓MCU一邊從sd里讀取MP3數據,再一邊發(fā)送到vs1003里邊去解碼,這樣就可以一直把一首MP3的數據全部發(fā)送到vs1003進(jìn)行解碼。于是我先拷貝了一個(gè)碼率比較低的MP3,因為單片機的速度畢竟很慢 從sd卡里讀取數據然后又要發(fā)送給vs1003解碼 先找一個(gè)碼率比較低的MP3做測試這是明智的選擇。
開(kāi)始組合程序,編寫(xiě)相應的主函數,通電測試。沒(méi)有任何反應,串口調試(如果讀寫(xiě)sd正??梢詮拇诮邮盏絪d'卡的第0扇區數據(邏輯扇區)這是我程序特意設定的,為了方便看出sd是否在工作)也接收不到任何數據 ,確定sd卡未啟用。我以為sd卡的讀寫(xiě)又出問(wèn)題了 ,拿之前做好的sd測試程序重新測試,也沒(méi)有數據輸出,很暈。
不經(jīng)意間我發(fā)現當我拔掉解碼模塊sd卡讀寫(xiě)正常,找到這一重要點(diǎn)之后,我開(kāi)始分析問(wèn)題。
因為我的sd卡和vs1003與MCU的通訊方式都是spi。而我的MCU只有一個(gè)硬件spi,所以都統一連接到一起了 只是通過(guò)不同的片選讓它們輪流使用spi??上У氖沁@樣不行。經(jīng)過(guò)多次試驗,猜想,也在網(wǎng)上尋求答案(未果)。最終我自己搞明白了,是應為我用的MCU為5V器件,為了能跟vs1003、sd卡正常通訊 ,我把MCU的spi口設置成為開(kāi)漏形式,讓后加3.3v的上拉。這樣我的單片機spi口最大電壓也只能是3.3v了。不過(guò)同時(shí)開(kāi)漏形式讓它的驅動(dòng)能力變得很弱,無(wú)法同時(shí)接兩個(gè)spi通訊模塊~~~
于是我把sd卡的接口換到P0口采用軟件模擬spi讀取數據,這樣一來(lái),呵呵串口可以看到接收到數據了隨之耳機里傳來(lái)了久違的音樂(lè ),不過(guò)聲音很亂,就像快進(jìn)一樣。還是很興奮 ,畢竟是能出聲音了。
為什么聲音會(huì )亂掉,這個(gè)時(shí)候開(kāi)始找問(wèn)題,一直花了我兩天的時(shí)間,vs1003的datasheet看了一遍又一遍 ,敢肯定我的程序絕對是沒(méi)錯。那就是硬件了。
分析它的原理開(kāi)始查問(wèn)題,看看是那步錯了。
vs1003解碼MP3數據,你只要把正確的MP3數據傳送給它,它就能自動(dòng)識別你的MP3是多少碼率的,然后通過(guò)一定的解碼速率進(jìn)行解碼。這個(gè)時(shí)候就有疑問(wèn)了,既然解碼的速率確定了,為了能流暢的播放出音樂(lè )來(lái),你給vs1003發(fā)送MP3數據的速率必須跟它解碼的速率一樣,那怎么去保證這兩個(gè)速度一樣呢?如果送給vs1003的數據過(guò)快,那我們可以加延時(shí)讓它一樣,那這時(shí)候又出問(wèn)題了,難道每一首不同碼率的歌都要去加個(gè)延時(shí)嗎(這里是按發(fā)送數據永遠比解碼速率快的情況來(lái)分析),這樣肯定是不合理的。不用擔心,vs1003為用戶(hù)準備了0.5k的數據緩沖區做為音頻數據的緩沖,這就好像一個(gè)漏斗一樣,0.5k空間就像漏斗的容量,你只要保證漏斗里邊始終有東西,那么漏斗底下就始終有東西流出,保持連續。你給漏斗加料的速度無(wú)所謂,只要你別讓漏斗里邊為空就行。vs1003是一樣的為了解碼正常,播放流暢,你只要保證數據緩沖區里始終有數據作為待解碼對象,這樣就可以放出流暢的音樂(lè )來(lái)。這里又有問(wèn)題了,我們怎么確定數據緩沖區里到低有沒(méi)有數據,或者是還有多少,怎么控制發(fā)送數據。vs1003也幫你考慮到這一點(diǎn)了,所以他專(zhuān)門(mén)設定了一個(gè)中斷腳DREQ,當DREQ變高時(shí),外部可以至少為vs1003發(fā)送 32字節的數據(這是SDI數據,還有一種SCI數據,這里不說(shuō)了),為了保證播放流暢。當vs1003收到32字節的數據之后他的DREQ腳變?yōu)榈?,此時(shí)可以暫時(shí)不往里邊發(fā)送數據,如果數據緩沖區內少于32字節的有效數據,那么vs1003將DREQ置為高電平,此時(shí)需要往里邊發(fā)送數據(對于DREQ腳的變化,網(wǎng)上有異議,這是我個(gè)人的理解)。這里你會(huì )發(fā)現,我之前不是說(shuō)數據緩沖區是0.5k,為什么每次才32個(gè)數據就可以了。vs1003只是設置了一個(gè)32byte為標準,當然 你可以當在檢測到DREQ腳變高時(shí),往里邊一次性發(fā)送少于(這是必須的)0.5k的字節,然后再去檢測DREQ的狀態(tài),當再次變高時(shí) 你就可以再往里邊發(fā)送那么多數據,是可以的。32byte只是一個(gè)最低標準。個(gè)人理解~~
按這個(gè)尋到問(wèn)題的根源~~~我的DREQ沒(méi)有在工作,屏蔽了他 播放跟本沒(méi)變,所以說(shuō),我的MCU無(wú)法判斷vs1003的數據區是否滿(mǎn)了 是否需要新數據,這里只是一股腦的往vs1003里灌數據
所以導致我的音樂(lè )播放不正常,測量初始化之后的vs1003的DREQ腳,發(fā)現竟然出現1.8v,不高不低,處于模糊狀態(tài)。
確定DREQ腳不能工作,網(wǎng)上尋求答案,對我的情況都沒(méi)用。之后又翻到pcb圖上去,發(fā)現一個(gè)很重要的地方未連接,就是當用spi模式給vs1003發(fā)送數據的時(shí)候,其串口RX必須接到IOVDD.
還有一個(gè)test腳要接到IOVDD。到此時(shí)已經(jīng)是11點(diǎn)54分,馬上要熄燈了。
終于找到一個(gè)可行性的問(wèn)題。
今天一大早,我把那條線(xiàn)補上去,初始化vs1003一測DREQ腳為3.3(高)。很是激動(dòng),DREQ可以工作了,那么音樂(lè )播放就可以了,哈哈。下載程序測試。
一切OK!!!!
評論