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