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