版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
./本科生畢業(yè)設(shè)計畢業(yè)設(shè)計題目基于單片機的音樂播放器設(shè)計學生姓名所在學院能源與動力工程學院專業(yè)及班級指導教師完成日期20年6月2日.摘要本論文首先針對基于SD卡的MP3的播放器整體設(shè)計加以研究和介紹,并討論系統(tǒng)軟硬件的選擇,及具體開發(fā)調(diào)試環(huán)境;然后,深入介紹了系統(tǒng)設(shè)計方案及其實現(xiàn),并著重研究了SD卡、FAT格式、解碼芯片及其軟件驅(qū)動的設(shè)計;最后,詳細介紹了性能優(yōu)化等方面的工作及其開發(fā)前景。本設(shè)計在Atmel公司生產(chǎn)的atmega8L單片機上實現(xiàn)并取得了較好的效果。關(guān)鍵詞:MP3播放器,AVR單片機,SD卡,音頻解碼,FAT分析.ABSTRACTInthispaper,firstofallfortheSDcard-basedMP3playertostudytheoveralldesignandpresentation,anddiscussthesystemhardwareandsoftwarechoices,andspecificdevelopinganddebuggingenvironment;andtheninsightintothesystemdesignanditsimplementation,focusingontheSDcard,FATformat,decoderchipandsoftware-drivendesign;Finally,thedetailedperformanceoptimizationaspectsoftheworkanditsdevelopmentprospects.ThisdesignproducedbytheAtmel’smicrocontrollerATmega8ltoachieveandhasachievedgoodresults.KEYWORDS:MP3Player,AVRMicroChipUnit,SDCard,AudioDecorde,FATansysly目錄TOC\o"1-3"\u摘要IABSTRACTII第一章緒論11.1基于單片機的MP3概述11.1.1基于單片機的MP3系統(tǒng)組成11.1.2基于單片機的MP3播放器特點21.2課題研究的背景及意義21.2.1課題研究的背景21.2.2課題研究的意義41.3論文研究的內(nèi)容和目標41.3.1論文研究的內(nèi)容41.3.2論文研究的目標5第二章硬件設(shè)計62.1AVR單片機簡介62.2AVR單片機性能接口分析72.3基于SD卡的MP3接口設(shè)計72.3.1ATmega8l引腳介紹72.3.2ATmega8l接口介紹與設(shè)計9第三章軟件設(shè)計163.1軟件設(shè)計流程163.2鍵盤程序設(shè)計173.3SD卡驅(qū)動程序設(shè)計173.4FAT驅(qū)動程序設(shè)計193.5VS1003B驅(qū)動程序設(shè)計223.6MP3軟件運行設(shè)計24第四章總結(jié)274.1基于單片機的MP3播放器測試結(jié)果274.2前景與展望27參考文獻28致謝30附錄31.第一章緒論1.1基于單片機的MP3概述1.1.1基于單片機的MP3系統(tǒng)組成基于單片機的MP3播放器主要由主控制器、SD卡、解碼芯片、鍵盤等四個部分組成。其基本框架如下圖所示。圖1-1基本框架圖1.控制模塊控制模塊是整個系統(tǒng)的核心。主要完成對系統(tǒng)中各種芯片的輸入、輸出控制,也是實現(xiàn)數(shù)據(jù)交換、軟硬件接口的中心模塊。2.解碼模塊這是系統(tǒng)中又一重要模塊。其主要功能是實現(xiàn)對數(shù)據(jù)進行處理并輸出模擬信號驅(qū)動耳機發(fā)聲。3.輸入模塊此模塊可大致分為鍵盤部分和SD卡部分。鍵盤部分主要用來控制對MP3的操作。SD卡部分主要是對SD卡的讀取。4.輸出模塊此部分主要包括音頻輸出。音頻輸出主要會用到一些模擬電路,對電路進行去噪等。1.1.2基于單片機的MP3播放器特點在半導體行業(yè)中,消費類電子是近年來發(fā)展最迅猛的一個領(lǐng)域。20XX消費類電子在中國Mcu市場的需求所占份額超過了百分之四十[1]。現(xiàn)在mp3技術(shù)已基本成熟,一般mp3都采用專用DSP芯片和集成的數(shù)據(jù)程序存儲器。集成數(shù)據(jù)存儲器優(yōu)點是成本低廉,但是,這樣卻無法方便的進行容量的擴展。因此,本次論文在于設(shè)計出能夠用SD或CF卡作為音樂存儲介質(zhì)的存儲器,從而,使mp3的容量能夠方便地得到擴展。隨著現(xiàn)在存儲器微型化快速發(fā)展,無法擴展容量的mp3已經(jīng)很難滿足人們的需求。雖然現(xiàn)在一些mp3容量已經(jīng)達到2G、4G甚至8G。但是,由于其容量無法擴展,為用戶以后的使用造成了極大不便。當用戶想要擴展容量時,不得不再換一個新的mp3。這樣就造成了用戶成本上的增加,會使用戶覺得得不償失。而SD卡mp3的出現(xiàn)則可以解決用戶的這一煩惱。這也是本次設(shè)計的優(yōu)勢所在。另外,mp3為了達到音質(zhì)效果的完美,往往采用高檔DSP器件作為專門的解碼播放芯片,這樣雖然在效果上取得較大的突破,但是,由于mp3格式本身的限制,因此,即使盡可能提高系統(tǒng)性能和效果也會有一定限制,不可能無限制地提高,而且這些提高對于成本來說是得不償失的。所以,這類mp3價格是一般mp3的好幾倍。因此,本次論文并不采用這種DSP器件作為mp3載體,而是采用一般的單片機控制和mp3格式解碼芯片實現(xiàn)。由于社會上的大多數(shù)人群都屬于低端消費者,也并不是專業(yè)的音樂欣賞者,他們對音樂的要求并不高。因此,此次設(shè)計的播放SD卡數(shù)據(jù)的mp3能夠適合于大多數(shù)人群。1.2課題研究的背景及意義1.2.1課題研究的背景便攜式音樂播放器的歷史從1979年Sony的WalkmanTPS-12隨身聽的問世開始。這臺磁帶機音樂系統(tǒng)開啟了個人娛樂市場的大門,在此之前,人們只能呆在家里用笨重的立體聲錄音機欣賞音樂[2]。至今,便攜式音樂播放器產(chǎn)品已經(jīng)經(jīng)歷了磁帶機、CD機、MD播放器、MP3播放器四個階段[3]。1980年,索尼和飛利浦共同制定了數(shù)字音頻光盤格式的標準,光盤直徑為12厘米,采樣頻率44.1K,比特率1411.2Kbps,16位音頻數(shù)據(jù),CD的音軌可以說幾乎是無損的。一張光盤可以容納75分鐘的音樂。1982年索尼推出的D-50是真正意義上的CD隨身聽,拉開了CD隨身聽的序幕。1990年左右發(fā)展達到了鼎盛時期。時至如今,不管音樂播放器的未來怎么樣發(fā)展,CD這承載完美音質(zhì)的載體永遠不會落伍,即使因為體積上有著無法回避的缺點[3]。1989年,德國人Brandenburg的博士論文,為MP3這一數(shù)字音頻壓縮技術(shù)提供了理論基礎(chǔ)。1995年誕生的MP3標準具有較高的壓縮比以及較小的音質(zhì)損失,是音樂史上劃時代的革命性技術(shù)。這種數(shù)字音樂壓縮技術(shù)的誕生和流行,推動了MP3隨身聽的開發(fā)和應用。在MP3標準誕生不久的20世紀90年代后期,便攜式MP3音樂播放器正式登場[2]。從1995年上半年開始直到整個九十年代后期,MP3開始在因特網(wǎng)上蓬勃發(fā)展。MP3的流行主要得益于如Nullsoft于1997年發(fā)布的Winamp和Napster于1999年發(fā)布的Napster這樣的公司和軟件包的成功,并且它們相互促進發(fā)展。這些程序使得普通用戶很容易地播放、制作、共享和收集MP3文件[4]。1998年Saehan公司推出了世界上第一臺的MP3播放器——MPManF10。MPMan,取意于MP3與WALKMAN的結(jié)合。MPManF10的體積為70x90x16.5mm,約有四個1.44M軟盤堆疊起來這么大,體重為65克,可謂非常輕巧[5]。在世韓的MPmanF10為人們帶來了驚喜之后,美國的帝盟〔Diamond公司挑頭,于1998年底推出了RioPMP300,這是第一個讓全世界都印象深刻的MP3。RioPMP300最大的優(yōu)點就是可在互聯(lián)網(wǎng)上下載MP3而不用花一分錢[5]。MP3文化的標志——AppleiPod。誕生于20XX10月,作為一款MP3,它在很多方面并不出色:價格高、音質(zhì)一般、使用時間短以及缺乏對Windows的支持等等,但它卻是第一個把互聯(lián)網(wǎng)音樂與MP3隨身聽捆綁銷售的產(chǎn)品。許多人都愿意付少量錢到Apple官方站下載單歌,或使用包月制的無限時Download,iPod真正讓唱片公司獲得利潤,所以得到了消費者和唱片商的雙重支持[5]。直到20XX,MP3行業(yè)不平凡的一年。隨著隨身聽的發(fā)展,人們已經(jīng)越來越被迷你小巧的MP3所征服,原本人們對于MP3音質(zhì)上的顧慮,已經(jīng)被現(xiàn)有MP3高品質(zhì)所打消。在這一年中,無論是從本身的品質(zhì),還是市場銷售的情況來看,MP3已經(jīng)完全占有了市場,成為隨身聽行業(yè)的霸主[6]。當MP3在容量、外觀、音質(zhì)上的發(fā)展無法再吸引更多眼球的時候,開始轉(zhuǎn)向多功能方向發(fā)展。正如在手機身上所發(fā)生的一切,人們對于MP3的要求,不再是單一的欣賞音樂,而是能像手機一樣身兼多職[5]。而目前消費類電子產(chǎn)品的發(fā)展呈現(xiàn)出數(shù)字化和多功能集成化的明顯趨勢[7]。在MP3的研究上,由于市場趨近飽和,大多數(shù)公司都將精力集中在外觀造型上,對于其功能及性價比的探索趨勢相對較弱。1.2.2課題研究的意義本次論文主要是為了開發(fā)出一套低成本、可擴展容量的MP3?,F(xiàn)在一般個人隨身攜帶使用MP3存在容量固定,性價比較低的情況。此次論文便是根據(jù)這些情況而設(shè)計。此次設(shè)計的突出優(yōu)勢是:1、突破了存儲容量限制。本系統(tǒng)提供了SD卡接口,可以方便地訪問外部的移動存儲介質(zhì),這樣就不會有特定的容量限制。當前,個人多媒體娛樂市場的需求快速增長,各種多媒體的應用也日趨豐富,對存儲容量的要求必然越來越高,因此本系統(tǒng)采用的方案可以說是應勢而生。2、低成本。由于MP3編碼算法的CPU的性能要求非常,因此目前大部分的MP3實時編碼都是采用專用的DSP芯片來實現(xiàn),這些芯片大部分價格較高[8]。本系統(tǒng)采用通用單片機處理,對MP3算法做了硬件方式的實時編碼滿足音質(zhì)要求。設(shè)計中又將漢字存儲芯片移除,大大降低了系統(tǒng)的成本。1.3論文研究的內(nèi)容和目標1.3.1論文研究的內(nèi)容1.分析FAT32磁盤文件格式。由于此次論文要求對SD卡數(shù)據(jù)進行讀寫,而現(xiàn)在大多數(shù)SD卡的數(shù)據(jù)格式幾乎都是FAT16或FAT32格式。其內(nèi)部數(shù)據(jù)存儲方式及引導區(qū)大小等情況顯得尤其重要。如果忽略此環(huán)節(jié),勢必在讀取數(shù)據(jù)時造成錯誤,對結(jié)果造成重大影響。2.分析mp3文件格式。在進行MP3播放時,MP3解碼器并不能夠完成數(shù)據(jù)的分析任務,它只能根據(jù)控制部分給出的控制方式及速率接受并運算數(shù)據(jù),并將其轉(zhuǎn)換為相應的模擬信號。故進行MP3格式的分析可以幫助我們編寫相應分析程序,并為控制MP3解碼芯片作出必要的準備。3.分析出mp3解碼方法。在使用MP3解碼芯片解碼時,必然會用到解碼相關(guān)知識。而且,在將數(shù)據(jù)送到MP3解碼芯片前,對數(shù)據(jù)做必要的處理也可以提高MP3解碼芯片處理效率,增加設(shè)計的可實現(xiàn)性。如果對MP3解碼不夠了解,就可能導致設(shè)計的失敗。4.了解mp3解碼芯片的相關(guān)使用。對于不同的MP3解碼芯片,其操作、控制字及外圍電路也各不相同,找出性價比高且外圍電路簡單的芯片就顯得比較重要。這不但可以降低成本,也會大大提高系統(tǒng)的可行性并降低系統(tǒng)成本。5.對MiniSD卡的初始化及文件讀寫。SD屬于存儲設(shè)備,但是,它卻與一般存儲設(shè)備不同。其與集成芯片相似,需要對其初始化才能正常工作。而對其進行讀寫操作也與其它存儲器不同,每次讀寫均需寫入相應的命令控制字,否則,對SD卡的操作均為無效操作。1.3.2論文研究的目標1.能夠完成對SD卡或CF卡的初始化及SD卡中mp3數(shù)據(jù)進行讀取。2.通過mp3解碼芯片播放出原音頻文件。3.通過控制部分,能夠進行上一曲、下一曲的切換等。第二章硬件設(shè)計本章著重介紹基于SD卡的MP3播放器設(shè)計的硬件設(shè)計。其設(shè)計流程如圖2-1所示。圖2-1硬件框圖2.1AVR單片機簡介一般MP3文件大小都在3-8MB之間,而每個文件的播放時間為5分鐘左右,按這樣計算,單片機的處理能力必須在200kb/s以上,再加上SD卡的讀取時間、解碼時間和單片機自身需要的控制指令時間,因此,單片機的處理能力必須在600kb/s以上,即每微秒執(zhí)行1.6條指令。而51系列單片機大部分指令為雙周期指令,其工作頻率在12MHZ時,每條指令需要2μm,所以,本論文采用AVR系列的ATmega8l單片機,其具有更高的工作性能。下面我們作以簡單介紹。ATmega8l單片機屬于AVR單片機中配置較高的產(chǎn)品。它在AVR內(nèi)核基礎(chǔ)上,增加了更多的功能,并完善了接口性能,在省電、穩(wěn)定性、抗干擾以及靈活性方面也考慮得更加周全和完善,所以,ATmega8l單片機的系統(tǒng)結(jié)構(gòu)相對于其他AVR單片機結(jié)構(gòu)來說復雜一些。ATmega8l單片機是基于AVRRISC結(jié)構(gòu)的8位低功耗CMOS微處理器。其內(nèi)核具有豐富的指令集和32個通用工作寄存器。所有的寄存器都直接與算術(shù)邏輯單元<ALU>相連接,使得一條指令可以在一個時鐘周期內(nèi)同時訪問兩個獨立的寄存器。這種結(jié)構(gòu)大大提高了代碼的效率,并且具有比普通的復雜指令集微處理器高10倍的數(shù)據(jù)吞吐率[9]。ATmega8l單片機的內(nèi)部資源有先進的RISC指令集、非易失性程序和數(shù)據(jù)存儲器、JTAG接口、特殊功能接口。其中,RISC指令集有32個8位通用工作寄存器,支持全靜態(tài)工作,工作于16MHz時性能高達16MIPS,內(nèi)部含有RC振蕩電路,并且還有只需兩個時鐘周期的硬件乘法器。單片機內(nèi)部還含有32KB系統(tǒng)內(nèi)可編程Flash,其可擦寫周期達到10,000次,獨立的鎖定位,可對芯片進行軟件加密以及1KB的EEPROM和2KB的片內(nèi)SRAM。最值得一提的是,ATmega8l單片機內(nèi)部含有8通道的10位ADC電路,4路PWM通道,可編程串口和支持主機/從機工作模式的SPI接口。其中,SPI接口通信速度可達到2MB/s,由于本次設(shè)計的SD卡及解碼芯片均含有SPI接口,因此,這種接口給設(shè)計帶來了很大方便。而且,其內(nèi)部含有RC振蕩電路,無須提供外部時鐘仍然能夠正常工作。2.2AVR單片機性能接口分析因為ATmega8l單片機在工作在16MHz時能達到16MIPS<即16百萬條指令每秒>的速度,即,它每執(zhí)行一條指令的時間為0.0625μs,這種速度是51系列單片機的12倍。從上面的分析我們知道,MP3所需單片機性能要求約為每微秒執(zhí)行1.6條指令。故,ATmega8l單片機符合設(shè)計MP3的系統(tǒng)要求,能夠通過它實現(xiàn)MP3的設(shè)計。另外,SD卡含有集成的SPI接口。使用專門的SPI接口比使用位操作模擬接口時序的方法操作更簡單,效率也更加高。其工作速度與振動器頻率的關(guān)系如表2-1所示。從上表我們可以知道:當ATmega8l工作于16MHz時,其最大傳輸速率可以達到16MHz/2=8MHz。這個速度完全可以滿足MP3的播放要求。2.3基于SD卡的MP3接口設(shè)計2.3.1ATmega8l引腳介紹在進行單片機的接口設(shè)計以前,我們首先來了解并分析一下ATmega32單片機的引腳。其具體結(jié)構(gòu)如圖2-2所示。圖2-2ATmega8l引腳圖引腳說明:VCC:數(shù)字電路的電源。GND:地。端口B<PB7..PB0>XTAL1/XTAL2/TOSC1/TOSC2:端口B為8位雙向I/O口,具有可編程的內(nèi)部上拉電阻。其輸出緩沖器具有對稱的驅(qū)動特性,可以輸出和吸收大電流。作為輸入使用時,若內(nèi)部上拉電阻使能,端口被外部電路拉低時將輸出電流。在復位過程中,即使系統(tǒng)時鐘還未起振,端口B處于高阻狀態(tài)。通過時鐘選擇熔絲位的設(shè)置,PB6可作為反向振蕩放大器或時鐘操作電路的輸入端。通過時鐘選擇熔絲位的設(shè)置PB7可作為反向振蕩放大器的輸出端。若將片內(nèi)標定RC振蕩器作為芯片時鐘源,且ASSR寄存器的AS2位設(shè)置,PB7..6作為異步T/C2的TOSC2..1輸入端。端口C<PC5..PC0>:端口C為7位雙向I/O口,具有可編程的內(nèi)部上拉電阻。其輸出緩沖器具有對稱的驅(qū)動特性,可以輸出和吸收大電流。作為輸入使用時,若內(nèi)部上拉電阻使能,端口被外部電路拉低時將輸出電流。在復位過程中,即使系統(tǒng)時鐘還未起振,端口C處于高阻狀態(tài)。PC6/RESET若RSTDISBL熔絲位編程,PC6作為I/O引腳使用。注意PC6的氣特性與端口C的其他引腳不同若RSTDISBL熔絲位未編程,PC6作為復位輸入引腳。持續(xù)時間超過最小門限時間的低電平將引起系統(tǒng)復位。門限時間見P35Table15。持續(xù)時間小于門限時間的脈沖不能保證可靠復位。端口D<PD7..PD0>:端口D為8位雙向I/O口,具有可編程的內(nèi)部上拉電阻。其輸出緩沖器具有對稱的驅(qū)動特性,可以輸出和吸收大電流。作為輸入使用時,若內(nèi)部上拉電阻使能,則端口被外部電路拉低時將輸出電流。在復位過程中,即使系統(tǒng)時鐘還未起振,端口D處于高阻狀態(tài)。RESET:復位輸入引腳。持續(xù)時間超過最小門限時間的低電平將引起系統(tǒng)復位。持續(xù)時間小于門限時間的脈沖不能保證可靠復位。AVCC:AVCC是A/D轉(zhuǎn)換器、端口C<3..0>及ADC<7..6>的電源。不使用ADC時,該引腳應直接與VCC連接。使用ADC時應通過一個低通濾波器與VCC連接。注意,端口C<5..4>為數(shù)字電源,VCC。AREF:A/D的模擬基準輸入引腳。2.3.2ATmega8l接口介紹與設(shè)計首先,介紹一下時鐘和復位電路的設(shè)計。1.時鐘電路的設(shè)計。ATmega32單片機時鐘電路可以采用三種設(shè)計方式。方式一,采用內(nèi)部RC振蕩電路。采用此種設(shè)計時要保持XTAL1和XTAL2為空,這樣可以減少MP3體積大小,但是,這種方式下,不能對CK-OPT進行編程,且頻率受溫度影響較大。方式二,采用外部RC振蕩電路。這種電路可以減少晶體振蕩器的使用,但是,會要增加一個電阻和電容。而且,這兩種器件一般情況下精度有限且抗干擾能力不足,延時不夠精確。因此,這種方式只適用于對時間不敏感場合,在本次設(shè)計中不能使用。方式三,采用石英晶體振蕩器。石英晶體頻率較穩(wěn)定,抗干擾能力較強。只是,啟動時頻率穩(wěn)定性較差。但是,可以通過軟件延時的方法消除這個問題。綜上,本次設(shè)計中可以采用方式三。而在實際大批量生產(chǎn)時可以采用方式一。具體電路如圖2-3所示。圖2-3時鐘電路復位電路的設(shè)計。ATmega8l單片機與51單片機不同,它使用的是低電平復位,其連接方法比較固定,本次設(shè)計中我們采用一般接法。如圖2-4所示。圖2-4復位電路剛上電時,由于電容C5的作用,REST引腳會保持一段時間的低電平,使電路復位,然后,緩慢變高,使電路進入正常工作狀態(tài)。當按鍵按下時,REST與地接通變低電平,電路發(fā)生復位。3,按鍵電路。按鍵電路如圖2-5所示。圖2-5按鍵電路4,電源電路。由于SD卡的供電及接口標準電壓均為3.3V。因此使用AMS1117進行降壓,電源電路如圖2-6所示。圖2-6電源電路最后,介紹一下SPI接口及其電路設(shè)計。這是本次設(shè)計的最重要的接口,它工作性能的好壞直接影響到本次設(shè)計的成敗。SPI系統(tǒng)的發(fā)送方向只有一個緩沖器,而在接受方向有兩個緩沖器。即是說,在發(fā)送時一定要等到移位過程全部結(jié)束后,才能對SPI數(shù)據(jù)寄存器執(zhí)行寫操作。而在接收數(shù)據(jù)時,需要在下一個字符移位過程全部結(jié)束前,通過訪問SPI數(shù)據(jù)寄存器讀取當前接受到的字符;否則第一個字節(jié)將會丟失。其數(shù)據(jù)傳遞過程如圖2-7所示。圖2-7SPI主從機的連接[10]從圖中可以看出:SPI接口內(nèi)部數(shù)據(jù)全由寄存器控制,在進行數(shù)據(jù)移出的同時也在進行數(shù)據(jù)的移入。其中,還有一個SPI接口使能端口SS,通過這個端口,我們可以控制SPI的使用。同時,我們可以通過設(shè)計模擬其工作特性的硬件引腳,從而達到節(jié)約端口、操作方便的目的。在本次設(shè)計中,我們采用SD卡作為數(shù)據(jù)存儲介質(zhì)。因此,我們現(xiàn)在來分析一下其接口及數(shù)據(jù)傳輸模式。SD卡有9個引腳,它們分別是:VCC、GND、DAT0-DAT3、CLK、CMD。其中,它們在不同的模式下有不同的定義。其具體定義如表2-2所示。表2-2SD卡引腳定義針腳名稱類型1描述1CS/DAT3I/O/PP卡監(jiān)測/數(shù)據(jù)位32CMD/MOSIPP命令/回復3VssS地4VccS供電電壓5CLKI時鐘6Vss2S地7DAT0/MISOI/O/PP數(shù)據(jù)位08DAT1/IRQI/O/PP數(shù)據(jù)位19DAT2I/O/PP數(shù)據(jù)位21:S:電源供電,I:輸入O:輸出I/O:雙向PP:I/O使用推挽驅(qū)動SD卡的總線概念SD卡數(shù)據(jù)傳輸分為SPI模式和SD模式。在SD模式下速度較快,但是,由于使用引腳過多,而且,在SPI模式下速度已經(jīng)足夠,因此,本次設(shè)計中采用SPI模式。在SPI模式下,SD卡只需要接MISO、MOSI、CLK、CS、CLK、Vss、Vcc這7個引腳就可以了。而ATmega32單片機也提供了相應的接口。但是,由于AVR單片機的接口標準電壓為5V,SD卡的供電及接口標準電壓均為3.3V。因此在ISP借口處接入5V工作電壓。如圖2-7所示。圖2-7SD卡接口電路解碼作為MP3必不可少的部分,它的設(shè)計也關(guān)系著整個設(shè)計的成敗。下面這種介紹一下這部分的設(shè)計步驟。第一步,我們必須選擇一款解碼芯片。這款芯片應該盡可能包含解碼、放大電路。其次,要求價格實惠、外圍電路簡單等。在本次設(shè)計中,采用了VS1003B。這是一款專用音頻解碼芯片。芯片內(nèi)部包含MP3、wma等硬件解碼,還包含放大電路。其體積較小,外圍電路也比較簡單。第二步,管腳分析。其引腳如圖2-8所示。它的模擬、數(shù)字及I/O口電源是分開的,其也含有SPI接口,支持2.5V電源供電,接口電源采用3.3V,可以進行串行通信,硬件復位等。圖2-8VS1003B引腳圖[12]根據(jù)數(shù)據(jù)手冊中提供的信息,要成功運用VS1003B這款芯片,還必須注意:當不使用RX引腳時應接到IOVDD上。TEST為測試保留,也應該連接到IOVDD上。GPIO0需要使用100K歐下拉電阻。其它引腳可以根據(jù)其定義進行連接。未使用功能可不進行連接。第三步,接口設(shè)計。根據(jù)第二步中管腳分析結(jié)果。我們?nèi)匀恍枰獙π酒斎胍_進行電平轉(zhuǎn)換。這里我們?nèi)匀徊捎秒娮璺謮旱姆绞?。主要輸入引腳為數(shù)據(jù)選擇、命令選擇、復位、時鐘、查詢忙、數(shù)據(jù)輸入。具體電路如圖2-9所示。圖2-9vs1003電平轉(zhuǎn)換電路另外,還有第二步中介紹的時鐘、電源以及特殊引腳的連接。由于使用的是成熟的音頻解碼芯片,硬件連接方式比較固定,且其數(shù)據(jù)手冊給出了示例,不需要太多自行設(shè)計部分,只要根據(jù)時序設(shè)計好軟件,便可以實現(xiàn)各種功能。圖2-10vs1003b連接電路自此,基于SD卡的MP3播放器硬件部分設(shè)計全部完成。在設(shè)計中充分考慮了以后的升級擴展等問題。但是,在電平轉(zhuǎn)換時使用了較多的電阻實現(xiàn),對系統(tǒng)模型最終大小有一定影響。在實際生產(chǎn)中可以用貼片電阻代替,這樣就可以大大減小電路板的體積。第三章軟件設(shè)計3.1軟件設(shè)計流程前一章介紹了硬件電路的設(shè)計,本章就要根據(jù)相應的硬件,進行軟件設(shè)計。軟件設(shè)計可以分為自底向上或自頂向下的設(shè)計方法,這里我們采用后者。首先,我們分別對鍵盤、SD卡、FAT、vs1003b進行驅(qū)動程序設(shè)計,然后,對這些驅(qū)動程序加以排列、組合,做到最優(yōu)啟動順序,最后進行高層人機接口程序的設(shè)計。為了能夠明確我們具體所需的驅(qū)動程序設(shè)計,下面我們先將設(shè)計的總體程序流程圖確定下來。如圖3-1所示。否否是是開始初始化各驅(qū)動程序是否有歌曲否結(jié)束播放一幀數(shù)據(jù)掃描鍵盤一次獲取歌曲信息讀入一幀數(shù)據(jù)歌曲是否結(jié)束下一曲圖3-1程序流程圖在完成程序流程圖之后,我們需要分別對各個部分進行程序設(shè)計,下面就分別介紹各種驅(qū)動程序的編寫方法。3.2鍵盤程序設(shè)計鍵盤部分:由于鍵盤在設(shè)計中使用的是2*3的矩陣鍵盤,所以在編寫程序時相對較為麻煩。必須先將其中的2個設(shè)置為輸出低電平,另外3個引腳設(shè)置為輸入。當檢測到3輸入引腳有低電平輸入時,為了防止是干擾,使用軟件延時10ms再次檢測,若仍然為低電平,則說明有鍵按下,讀出鍵值;然后,再將另外3個引腳設(shè)置為輸出低電平,原來的2個引腳設(shè)置為輸入,使用同樣的辦法可以讀出按鍵值。這樣得到的兩組按鍵值可以組合成唯一的一個按鍵值。在掃描按鍵時,不用進行過多的處理,處理越多,耗時越多,對輸出的聲音影響也就越大,所以,在掃描程序中,只需要將按鍵值返回即可,不需要進行太多處理。對于鍵盤接口的設(shè)置,可以利用一初始化程序,將接口進行一種定義,這樣,在掃描過程中程序可以節(jié)約更多的時間進行數(shù)據(jù)的讀寫。3.3SD卡驅(qū)動程序設(shè)計SD卡使用的是SPI模式,這種總線接口在AVR單片機中可以直接使用其寄存器加以控制。因此,在編寫SD卡驅(qū)動程序之前,必須先將單片機的SPI總線初始化。其具體代碼如圖3-2所示圖3-2SPI總線初始化代碼段在初始化SPI總線時,一般總線設(shè)置為低速模式,因為大多數(shù)器件在其初始化過程中,都不能有太高的速度,否則,很容易造成部分指令不能被接收,導致初始化失敗。在MP3播放過程中,用單片機作為控制中心,所以,在設(shè)置時還應該將單片機設(shè)為主機,其它模塊作為從機。在單片機SPI總線初始化完成后,就要對SD卡進行初始化。初始化SD卡,必須先對SD卡進行激活,其激活步驟如圖3-3所示。在SD卡被激活后,就可以進行初始化操作。初始化時,我們必須進行一下設(shè)置:1.設(shè)置一次讀寫SD卡數(shù)據(jù)塊的長度;2.開啟或關(guān)閉校驗位,這里我們選擇關(guān)閉校驗位,因為在SD卡使用過程中會有數(shù)據(jù)起始標志位等,而且SD卡在低速模式下,本身讀寫出錯的可能性不大。另外,SD卡的數(shù)據(jù)、指令長度為32位,而SPI總線為8位,在使用過程中還需要編寫一些接口函數(shù)以便編寫SD卡控制函數(shù),操作SD卡。在開始激活時序時,至少需要先發(fā)送108個初始時鐘,才能夠進行后面的步驟。在我們平常使用的mini卡中,還包含很多MMC卡。這兩種卡的使用指令基本相同,唯一的差別是激活時的最后幾條指令。因此,我們可以在本次設(shè)計中加入幾條關(guān)鍵性指令,判斷并激活兩種微型存儲卡。在不知道使用的是什么類型的存儲卡時,可以用一般辦法判斷存儲卡的類型。即,在寫入55H返回01H且寫入41H返回00H,則說明是SD卡;否則,寫入01H返回00H,則為MMC卡。圖3-3SD卡激活步驟[15]在初始化SD卡完成后,需要對本次設(shè)計中需要使用的一些特殊功能進行設(shè)計,如是否需要校驗位,一次讀寫的數(shù)據(jù)長度為多少等。當SD卡激活并完成初始化后,就可以對SD卡數(shù)據(jù)進行讀寫了,其讀取數(shù)據(jù)會在歌曲播放過程中經(jīng)常使用,因此,我們可以編寫一個讀函數(shù)。只要需要讀取數(shù)據(jù)時,只需要調(diào)用此函數(shù)就可以獲得所需數(shù)據(jù)。3.4FAT驅(qū)動程序設(shè)計當讀取到SD卡中的數(shù)據(jù)后,我們還不能直接使用這些數(shù)據(jù),這些數(shù)據(jù)是根據(jù)微軟制定的FAT/NTFS格式排列存放的。其中,在磁盤的開始區(qū)域存放的是磁盤系統(tǒng)的相關(guān)信息。當我們讀取到這些信息時,還需要進行一些相應的計算,找出其中的MP3或其它音樂格式文件的數(shù)據(jù)入口地址、結(jié)束地址等,這樣,單片機才能夠獲得相應的數(shù)據(jù),并對數(shù)據(jù)進行分析送給解碼芯片解碼。現(xiàn)在市場上大多數(shù)SD/MMC卡都采用的是FAT32格式,因此,下面我們就開始以FAT32格式為例進行分析。在本次設(shè)計中,為了能夠方便地看到SD卡內(nèi)部數(shù)據(jù),我們采用WinHex軟件對SD看內(nèi)部數(shù)據(jù)進行分析。每張磁盤都有自己固定的存儲結(jié)構(gòu)。磁盤的第一個區(qū)域是系統(tǒng)區(qū),從0面,0磁道,1扇區(qū)開始。系統(tǒng)區(qū)一般用來存放系統(tǒng)存儲和維護的信息,系統(tǒng)區(qū)由三部分組成:1.引導記錄〔包含磁盤大小、格式、存儲方式等信息;2.文件分配表FAT〔為文件分配磁盤空間;3.目錄〔包括文件名、磁盤地址和文件狀態(tài)[16]。其具體結(jié)構(gòu)如圖3-4所示。引導記錄引導記錄FAT目錄系統(tǒng)文件用戶文件系統(tǒng)區(qū)數(shù)據(jù)區(qū)圖3-4系統(tǒng)區(qū)和數(shù)據(jù)區(qū)組織圖本次設(shè)計中,需要對引導記錄進行詳細分析,計算出數(shù)據(jù)位置,找到音樂文件。而在引導區(qū)最重要的部分為前512字節(jié)。在前512字節(jié)中,前96字節(jié)記錄了系統(tǒng)的詳細信息,這些信息可以幫助我們算出系統(tǒng)區(qū)和數(shù)據(jù)區(qū)各組成部分的位置。其內(nèi)部前96個字節(jié)如圖3-5所示。圖3-5SD卡前96字節(jié)截圖在圖3-5中,每個字節(jié)含有為:前3字節(jié)為跳轉(zhuǎn)指令結(jié)構(gòu);4-11字節(jié)為依賴的系統(tǒng)文件名;第12、13字節(jié)為字節(jié)數(shù)/扇區(qū);14字節(jié)為扇區(qū)數(shù)/簇;15、16字節(jié)為保留扇區(qū)數(shù);17字節(jié)為FAT數(shù)目;18、19字節(jié)為啟動入口;19-21字節(jié)為小卷標扇區(qū)數(shù);第22字節(jié)為多媒體類型描述〔一般為F8;23、24字節(jié)為扇區(qū)數(shù)/小卷標FAT;25、26字節(jié)為扇區(qū)數(shù)/磁道;27字節(jié)為頭字節(jié)數(shù);29-32字節(jié)為隱藏扇區(qū)數(shù);第33-36字節(jié)為磁盤總扇區(qū)數(shù);37-40為扇區(qū)數(shù)/FAT;41字節(jié)為擴展標志位;42-44字節(jié)為磁盤版本號;45-48字節(jié)為啟動目錄的第一簇;49-50啟動信息扇區(qū)位置;51、52字節(jié)為啟動數(shù)據(jù)備份扇區(qū)位置;另外,83-87字節(jié)為文件系統(tǒng)格式;其余信息在本次設(shè)計中暫未用到。知道以上信息及其含有,我們就可以計算出磁盤數(shù)據(jù)的位置等信息。為了能夠方便地使用這些信息,在設(shè)計中可用如圖3-6所示的結(jié)構(gòu)體進行賦值,使程序能夠高效的運行。在知道以上信息后,可以采用下面計算公式進行計算,算出數(shù)據(jù)所在位置。FAT表起始地址=〔隱藏扇區(qū)數(shù)+保留扇區(qū)數(shù)*字節(jié)數(shù)/扇區(qū)目錄區(qū)起始地址=FAT表起始地址+FAT數(shù)目*扇區(qū)數(shù)/FAT*字節(jié)數(shù)/扇區(qū)+啟動目錄首簇*扇區(qū)數(shù)/簇*字節(jié)數(shù)/扇區(qū)第一個數(shù)據(jù)扇區(qū)地址=目錄區(qū)起始地址+目錄簇數(shù)*扇區(qū)數(shù)/簇*字節(jié)數(shù)/扇區(qū)目錄區(qū)的大小是不固定,其大小會根據(jù)文件的多少而進行調(diào)整,只有在一個文件目錄后不存在其它文件,才說明已經(jīng)不含有其它文件。因此,在讀取到的數(shù)據(jù)名為00H時,就說明文件已經(jīng)結(jié)束,可以不再往后面讀取文件。圖3-6啟動信息結(jié)構(gòu)體在獲取到啟動信息以及數(shù)據(jù)區(qū)等位置關(guān)系以后,就可以讀取自己需要的數(shù)據(jù)了。在使用過程中,我們可以編寫一些專門用于計算文件下一簇/扇區(qū)的程序,這樣就可以通過調(diào)用函數(shù)的方法方便地找到自己需要的數(shù)據(jù),判斷文件是否結(jié)束等情況。3.5VS1003B驅(qū)動程序設(shè)計設(shè)計MP3最重要環(huán)節(jié)之一是音頻解碼,解碼質(zhì)量直接關(guān)系到播放效果。本次設(shè)計中使用的是解碼芯片VS1003B,那么,編寫VS1003B的驅(qū)動程序就是解碼中關(guān)鍵環(huán)節(jié)。VS1003B有一個硬件復位引腳,在進行硬件復位后,還需要進行初始化設(shè)置,和音樂信息相關(guān)的設(shè)置,這樣才能讓其正常工作。因此,下面對MP3文件格式做簡略介紹,以方便對VS1003B進行設(shè)置。MP3文件是由幀構(gòu)成,幀是MP3文件最小組成單位。MP3文件大體分為三部分:TAG_V2<ID3V2>,Frame,TAG_V1<ID3V1>[17]。每個MP3數(shù)據(jù)幀又分為幀頭和數(shù)據(jù)部分構(gòu)成。幀頭長度為4BYTE〔32位,幀后面可能有兩個字節(jié)的CRC校驗。幀頭數(shù)據(jù)結(jié)構(gòu)如圖3-7所示。圖3-7MP3幀頭結(jié)構(gòu)A表示幀同步,所有位置位;B表示MPEG音頻版本;C表示音樂層描述;D為保護位;E為位速率索引;F表示采樣頻率索引;G為填充位;I為聲道模式;其余信息與本次設(shè)計關(guān)系不大,暫未使用,這里不做介紹。以上介紹中最重要的為E和F部分。E部分具體含義如表3-2所示。表3-2位速率索引表BitsV1,L11V1,L2V1,L3V2,L1V2,L2V2,L30000FreeFreeFreeFreeFreeFree000132323232328<8>0010644840644816<16>0011965648965624<24>010012864561286432<32>010116080641608064<40>011019296801929680<48>01112241129622411256<56>100025612811225612864<64>1001288160128288160128<80>1010320192160320192160<96>1011352224192352224112<112>1100384256224384256128<128>1101416320256416320256<144>1110448384320448384320<160>1111BadBadBadBadBadBad1:V1-MPEG1;V2–MPEG2/MPEG2.5;L1-LayerI;L2-LayerII;L3-LayerIII2:Free–可以利用的位率;Bad–不允許的值在幀頭B、C部分可以查到MP3版本及層數(shù),根據(jù)B、C的值在上表中可以查出音樂播放速率。F區(qū)決定音樂采樣率,而采樣率值則通過表3-3可以查出。表3-3采樣率索引表<單位:Hz>BitsMPEG1MPEG2MPEG2.50044100220501102501480002400012000103200016000800011ReservedReservedReserved無論幀長度是多少,每幀的播放時間都是26ms;每幀的大小可以通過以下方法計算得出:幀大小=<<<MPEGversion==MPEG1?144:72>*比特率>/采樣率>+填充位。當計算出幀大小波特率和采樣率后,我們就可以對MP3文件進行解碼。在對MP3格式做簡要介紹后,下面就對VS1003B解碼芯片做一些重要說明。其硬件連接方式在第二章已經(jīng)做了說明,此次設(shè)計中使用的是SPI接口,另外還連接了復位端、數(shù)據(jù)請求端、數(shù)據(jù)端及命令端。VS10003B接口指令為8位,0X2為寫;0X3為讀。一般我們只需要寫,只有在驗證寫入是否成功時,才讀VS1003B內(nèi)部寄存器。在每次讀寫數(shù)據(jù)后,數(shù)據(jù)請求端會變低表示忙。只有當數(shù)據(jù)請求端變高后才能進行數(shù)據(jù)/指令讀寫。其具體時序如圖3-8所示。圖3-8VS1003B寫數(shù)據(jù)時序圖[18]根據(jù)時序圖可以看出:要操作VS1003B,需要一條8為指令,再跟上8位地址,和寫入該地址的16位數(shù)據(jù)。然后,DREQ會變低,直到內(nèi)部完成數(shù)據(jù)的操作。VS1003B初始化時,需要對模式寄存器、時鐘頻率及倍頻寄存器、音量寄存器進行設(shè)置。另外,還需要對音頻寄存器進行設(shè)置,其取值由具體MP3文件幀頭數(shù)據(jù)計算得到,計算過程在MP3分析時已經(jīng)說明,這里不再解釋。在進行初始化設(shè)置以后,就可以進行數(shù)據(jù)送入解碼芯片進行解碼。由于軟件復位不會改變這些寄存器的值,我們在進行歌曲切換時可以進行軟件復位,這樣,在進行歌曲切換時可以不用進行其它復雜操作,直接進行軟件復位就可以了。另外,DREQ引腳在VS1003B的FIFO在能夠接受數(shù)據(jù)的時候輸出高電平。此時,VS1003B可獲取至少32Byte的SDI數(shù)據(jù)或一個SCI命令。遵循這個標準,當DREQ變低時,發(fā)送器必須停止發(fā)送新的數(shù)據(jù)[19]。根據(jù)這個信息,我們在對VS1003B芯片大量寫入音樂數(shù)據(jù)時,可以一次性寫入32字節(jié),這樣就可以大大提高數(shù)據(jù)輸入的效率,讓音樂播放更為流暢。3.6MP3軟件運行設(shè)計在完成了各種驅(qū)動程序設(shè)計后,就需要對音樂播放流程、界面和操作進行設(shè)計。如果在播放過程中,沒有好的界面及人機接口程序,就會不利于使用者操作,而且,在使用過程中,客戶由于不知道怎樣操作,胡亂按鍵就容易造成其它未知錯誤。因此,下面我們就怎樣進行整體設(shè)計做簡要說明。首先,程序需要對系統(tǒng)進行初始化。初始化各個驅(qū)動的順序必須有嚴格規(guī)定,應該從鍵盤開始,到顯示器,再到SPI接口初始化,到SD卡和FAT格式初始化,最后是VS1003B的初始化。采用以上順序,主要是為了能夠在任何一個接口或器件初始化失敗時,在顯示器中能夠給出相應的動作,指示哪一部分出錯,用戶應該怎樣繼續(xù)往下操作。正因為如此,在鍵盤和顯示器初始化過程中,絕對不能有死循環(huán),而其它程序中循環(huán)部分必須保留一定次數(shù),超過這個次數(shù)就跳出循環(huán)并報錯,交給系統(tǒng)處理錯誤,并發(fā)出警告。在初始化各驅(qū)動程序完成后,需要進入主程序,播放SD卡中的音樂。這部分程序可以在死循環(huán)中完成。一旦開始播放音樂,就不需要停下,除非暫停鍵〔可設(shè)一標志位加以判斷被按下。其程序段如圖3-9所示。圖3-9主程序段代碼在MP3播放過程中,可以先搜索全部音樂,將其放入一全局變量中,然后,利用這個全局變量判斷是否所有音樂已經(jīng)播放完成。播放過程主要為搜索音樂,找到音樂數(shù)據(jù)位置,讀取數(shù)據(jù),送入VS1003B解碼,判斷文件是否結(jié)束,沒有則再查找下一簇數(shù)據(jù)并讀取數(shù)據(jù),否則,送入結(jié)束數(shù)據(jù)代碼,跳到下一曲。其中,在進行完每一塊數(shù)據(jù)的解碼之后,需要進行一次鍵盤掃描,根據(jù)鍵盤的值,對VS1003B或單片機的相應寄存器進行操作,達到控制MP3播放的目的。第四章總結(jié)4.1基于單片機的MP3播放器測試結(jié)果首先,在一張容量為1G的SD卡中存儲了幾首MP3、WMA格式的歌曲文件,然后,插入自制的電路板中,上電播放。音樂播放成功,無任何異常產(chǎn)生。然后,進行按鍵測試。音量加減鍵能夠正常工作,但是,在按下按鍵時,歌曲出現(xiàn)播放聲音出現(xiàn)斷續(xù)情況。根據(jù)程序分析,由于每26ms需要一幀數(shù)據(jù),而按下按鍵會導致程序中斷數(shù)百毫秒,故出現(xiàn)歌曲播放聲音不連續(xù)的情況。進行歌曲切換、暫停/播放按鍵測試時,一切正常,無任何異常。到此,基于SD卡的播放器測試完成。所有電路及預期功能基本完成,無異常產(chǎn)生。4.2前景與展望MP3播放器在現(xiàn)在市場上已經(jīng)變得非常常見,從這個角度看,MP3的發(fā)展?jié)摿σ呀?jīng)不是很樂觀。但是,微型存儲卡技術(shù)卻在飛速發(fā)展,而且,將存儲卡與MP3相結(jié)合的技術(shù)卻并不樂觀,因為在這方面字庫處理的方法還需要得到提升,當SD/MMC卡更換后,怎樣才能讓漢字字庫保持不變很難辦到,即使這樣處理了,卻不得不在MP3內(nèi)部再加一塊存儲器存儲字庫,這樣,產(chǎn)品在成本上增加了,這也是基于SD卡的MP3不能快速發(fā)展的原因。因此,這種基于SD卡的MP3播放器在現(xiàn)實中,仍然具有一定潛力。而且,它在被用作MP3的同時還可以用作存儲器。對于用戶來說,這無疑是一種新意、一種優(yōu)勢,值得去購買、體驗。由于它本身的小巧,還可以嵌入車載系統(tǒng)、家庭娛樂系統(tǒng)等設(shè)備中,如果能在這些方面加以應用,這種基于SD卡的MP3播放器還有很大潛力可供挖掘。綜上所述,這種使用微型存儲卡作為存儲介質(zhì)的MP3播放器仍具有良好的發(fā)展勢頭,擁有一定潛力可供挖掘。參考文獻[1]CECA.ChainElectronicComponentsAssociation[OL]http://ic-ceca.Org.cn.2007[2]沈磊.基于ColdFire和uCLinux的便攜式多媒體播放器軟件系統(tǒng)的設(shè)計與實現(xiàn)[D].上海:上海交通大學,2005:1-2[3]有風無雨歷史不會忘記-索尼Walkman數(shù)十年回憶[OL]./doc/0/104/104282.shtml,2005.8[4]workstar百度百科MP3[OL]./view/1310.htm#8,2009.6.10[5]麥建邦百度百科MP3播放器[OL].13614.html[6]文夢夢.回首昨日展望明天淺談MP3播放器發(fā)展趨勢[J].PCPOP-電腦時尚,2005.2:19[7]譚文杰.基于USB主機的多媒體播放器的設(shè)計與實現(xiàn)[D].XX:XX大學,2007:1[8]陳杰.基于ARM平臺的MP3編碼器的實現(xiàn)及其性能優(yōu)化[D].上海:上海交通大學,2007:1[9]陳冬云、杜敬倉、任柯燕等ATmega128單片機開發(fā)原理與指導[M].北京:機械工業(yè)出版社,2006.10:4[10]2503J-AVR-10/06.8-bitAVRMicrocontrollerwith32KBytesIn-SystemProgrammableFlashATmeg32[S].Atmel.2006.10[11]OfficialRelease.MultimediaCardSystemSpecification[S].version3.31.MMCATechnicalCommittee,May2003MMCA[12]VLSISolution.VS1003PRELIMINARY[S].Version0.92,2005-06-07[13]SpecificationforLCDModuleTS1620-1[S].SHENZHENTECHSTARELECTRONICSCO.,LTD[14]SMC1602ALCM使用說明書[S].XX太陽人電子有限公司[15]ApplicationNoteSecureDigitalCardInterfacefortheMSP430[S].Dept.ofElectricalandComputerEngineering.MichiganStateUniversity,2004[16]沈美明溫冬嬋編著IBM-PC匯編語言程序設(shè)計[M]〔第二版北京:清華大學出版社[17]佚名MP3文件格式[EB].2006.1:2[18]魏廣寅VS1003-MP3/WMA音頻解碼器[S].XX永青儀電科技開發(fā)部[19]VS1003-MP3/WMAAUDIOCODEC數(shù)據(jù)手冊[S].Version0.92,2005-06-07致謝時光飛逝,快樂、充實、短暫、難忘的大學生活即將結(jié)束,在這三年半的時間內(nèi),自己的能力在各方面都有很大的提高,取得的這些進步和成績,離不開許多人的幫助和關(guān)心。籍此向他們表示衷心的感謝。首先感謝我的導師劉大年老師。在他的諄諄教誨和悉心指導下,我的學術(shù)水平、理論修養(yǎng)和實踐能力才能獲得很大提高。他嚴謹?shù)闹螌W態(tài)度、對問題深刻的洞察力,也使我獲益良多。感謝劉大年老師在學習、課程設(shè)計上對我的指導平易隨和、治學認真嚴謹,和他在一起的時光總是充滿歡笑。感謝測控0901的各位同學,和他們共同學習和工作的日子充滿了歡樂,大家在生活上互相幫助,在學習上互相幫助,給我留下了美好的回憶。感謝我的父母,感謝他們一直以來對我的支持和鼓勵,對我的關(guān)心和照顧。最后,衷心地感謝所有在百忙中抽出寶貴時間來參加論文審閱和答辯的老師。謝謝大家!附錄附錄1:原理圖附錄2:VS1003模塊原理圖附錄3:PCB板圖附錄4:實物圖附錄5:程序1,FAT驅(qū)動程序:#include"FAT.h"DWORDFirstDirClust;//firstdirectoryclusterDWORDFirstDataSector; //ThefirstsectornumberofdataWORDBytesPerSector; //BytespersectorWORDFATsectors; //TheamountsectoraFAToccupiedWORDSectorsPerClust; //SectorperclusterDWORDFirstFATSector; //ThefirstFATsectorDWORDFirstDirSector; //ThefirstDirsectorDWORDRootDirSectors; //ThesectornumberaRootdiroccupiedDWORDRootDirCount; //ThecountofdirectoryinrootdirBYTEFAT32_Enable;BYTE<*FAT_ReadSector><DWORD,BYTE*>;BYTE<*FAT_WriteSector><DWORD,BYTE*>;//函數(shù)指針指向sd卡的讀寫函數(shù)//functionpointertothesdcardread&writesingleblock//wirtesectorarenotuseinthisplayerBYTE<*FAT_ReadSector><DWORDsector,BYTE*buffer>=MMC_SD_ReadSingleBlock;//devicereadBYTE<*FAT_WriteSector><DWORDsector,BYTE*buffer>=MMC_SD_WriteSingleBlock;//devicewritestructFileInfoStructFileInfo;//temporarilybufferforfileinformation//FAT初始化,不含SD的初始化,用之前應先調(diào)用sd的初始化unsignedcharFAT_Init<>//InitializeofFATneedinitializeSDfirst{ structbootsector710*bs=0; structbpb710*bpb=0;// structpartsector*ps=0; structpartrecord*pr=0; BYTEbuffer[512]; DWORDhidsec=0; DWORDCapacity; Capacity=MMC_SD_ReadCapacity<>;// if<Capacity<0xff>return1; if<FAT_ReadSector<0,buffer>>return2; bs=<structbootsector710*>buffer; pr=<structpartrecord*><<structpartsector*>buffer>->psPart;//firstpartition hidsec=pr->prStartLBA;//thehiddensectors if<hidsec>=Capacity/512> { hidsec=0; } else { if<FAT_ReadSector<pr->prStartLBA,buffer>>return3;//readthebpbsector bs=<structbootsector710*>buffer; if<bs->bsJump[0]!=0xE9&&bs->bsJump[0]!=0xEB> { hidsec=0; if<FAT_ReadSector<0,buffer>>return4;//readthebpbsector bs=<structbootsector710*>buffer; } } if<bs->bsJump[0]!=0xE9&&bs->bsJump[0]!=0xEB>//對付沒有bootsect的sd卡 //deadwiththecardwhichhasnobootsect { return5; } bpb=<structbpb710*>bs->bsBPB; if<bpb->bpbFATsecs>//deteminethdFATtype//donotsupportFAT12 { FAT32_Enable=0; //FAT16 FATsectors =bpb->bpbFATsecs;//FAT占用的扇區(qū)數(shù) //thesectorsnumberoccupiedbyonefattalbe FirstDirClust=2; } else { FAT32_Enable=1; //FAT32 FATsectors =bpb->bpbBigFATsecs;//FAT占用的扇區(qū)數(shù) //thesectorsnumberoccupiedbyonefattalbe FirstDirClust=bpb->bpbRootClust; } BytesPerSector =bpb->bpbBytesPerSec;//每扇區(qū)字節(jié)數(shù) SectorsPerClust =<BYTE>bpb->bpbSecPerClust;//每簇扇區(qū)數(shù) FirstFATSector =bpb->bpbResSectors+hidsec;//第一個FAT表扇區(qū) RootDirCount =bpb->bpbRootDirEnts;//根目錄項數(shù) RootDirSectors =<RootDirCount*32>>>9;//根目錄占用的扇區(qū)數(shù) FirstDirSector =FirstFATSector+bpb->bpbFATs*FATsectors;//第一個目錄扇區(qū) FirstDataSector =FirstDirSector+RootDirSectors;//第一個數(shù)據(jù)扇區(qū) return0;}//讀一個簇中的一個扇區(qū)//readonesectorofonecluster,parameterpartindicatewhichsectorunsignedcharFAT_LoadPartCluster<unsignedlongcluster,unsignedpart,BYTE*buffer>{ DWORDsector; sector=FirstDataSector+<DWORD><cluster-2>*<DWORD>SectorsPerClust;//calculatetheactualsectornumber if<FAT_ReadSector<sector+part,buffer>>return1; elsereturn0;}//讀下一簇簇號//Returntheclusternumberofnextclusteroffile//SuitableforsystemwhichhaslimitedRAMunsignedlongFAT_NextCluster<unsignedlongcluster>{ BYTEbuffer[512]; DWORDsector; DWORDoffset; if<FAT32_Enable>offset=cluster/128; elseoffset=cluster/256; if<cluster<2>return0x0ffffff8; sector=FirstFATSector+offset;//calculatetheactualsector if<FAT_ReadSector<sector,buffer>>return0x0ffffff8;//readfattable/return0xfff8whenerroroccured if<FAT32_Enable> { offset=cluster%128;//findtheposition sector=<<unsignedlong*>buffer>[offset]; } else { offset=cluster%256;//findtheposition sector=<<unsignedint*>buffer>[offset]; } return<unsignedlong>sector;//returntheclustenumber}#ifFIX_DIRECTORY//在給定目錄下查找文件//Findaiteminthedirectorywhichspecifybytheparameter"cluster"http://ReturnthestartclusternumberunsignedintFAT_FindItem<unsignedlongcluster,BYTE*name,structFileInfoStruct*FileInfo>{ BYTE*buffer; DWORDtempclust; DWORDsector; unsignedcharcnt; unsignedintoffset; unsignedchari; structdirentry*item=0; if<<cluster==0>&&<FAT32_Enable==0>>//rootdirectory { buffer=malloc<512>;//applymemory if<buffer==0>return1;//iffailed for<cnt=0;cnt<RootDirSectors;cnt++> { if<FAT_ReadSector<FirstDirSector+cnt,buffer>>{free<buffer>;return1;} for<offset=0;offset<512;offset+=32> { item=<structdirentry*><&buffer[offset]>; if<<item->deName[0]!=0x00>&&<item->deName[0]!=0xe5>&&<item->deAttributes!=0x0f>> { for<i=0;i<11;i++> { if<buffer[offset+i]!=name[i]>break; } if<i==11> { //returntheparameteroftheitem FileInfo->StartCluster=item->deStartCluster+<<<unsignedlong>item->deHighClust><<16>;//don'tcare FileInfo->Size=item->deFileSize; FileInfo->Attr=item->deAttributes; FileInfo->Sector=FirstDirSector+cnt; FileInfo->Offset=offset; free<buffer>; return0; } } } } free<buffer>;//release } else//otherfolders { tempclust=cluster; while<1> { sector=FirstDataSector+<DWORD><tempclust-2>*<DWORD>SectorsPerClust;//calculatetheactualsectornumber buffer=malloc<512>;//applymemory if<buffer==0>return1;//iffailed for<cnt=0;cnt<SectorsPerClust;cnt++> { if<FAT_ReadSector<sector+cnt,buffer>>{free<buffer>;return1;} for<offset=0;offset<512;offset+=32> { item=<structdirentry*><&buffer[offset]>; if<<item->deName[0]!=0x00>&&<item->deName[0]!=0xe5>&&<item->deAttributes!=0x0f>> { for<i=0;i<11;i++> { if<buffer[offset+i]!=name[i]>break; } if<i==11> { FileInfo->StartCluster=item->deStartCluster+<<<unsignedlong>item->deHighClust><<16>;//don'tcare FileInfo->Size=item->deFileSize; FileInfo->Attr=item->deAttributes; FileInfo->Sector=sector+cnt; FileInfo->Offset=offset; free<buffer>; return0; } } } } free<buffer>;//release tempclust=FAT_NextCluster<tempclust>;//nextcluster if<tempclust==0x0fffffff||tempclust==0x0ffffff8||<FAT32_Enable==0&&tempclust==0xffff>>break; } } return1;}//findadirectorywiththegivenpathunsignedlongFAT_OpenDir<BYTE*dir>{ BYTEname[11]; BYTE*p=dir; BYTEdeep=0; BYTEi,j; DWORDcluster=0; if<FAT32_Enable>cluster=FirstDirClust; if<*p!='\\'>return1;//invalidpath while<*p> { if<*p=='\\'> { deep++; } p++; } p=dir; for<i=0;i<deep-1;i++> { p++; for<j=0;j<11;j++>name[j]=0x20; j=0; while<*p!='\\'> { if<<*p>>='a'&&<*p><='z'>name[j]=<*p++>-0x20; elsename[j]=*p++; j++; } if<FAT_FindItem<cluster,name,&FileInfo>>return1;//findthedirectory cluster=FileInfo.StartCluster; } p++; for<j=0;j<11;j++>name[j]=0x20; j=0; while<*p> { if<*p>='a'&&*p<='z'>name[j]=<*p++>-0x20; elsename[j]=*p++; j++; } if<j==0>returncluster; if<FAT_FindItem<cluster,name,&FileInfo>>return1;//findthefinaldirectory cluster=FileInfo.StartCluster; returncluster;}#endif//復制記錄項信息//copyitemvoidCopyDirentruyItem<structdirentry*Desti,structdirentry*Source>{ BYTEi; for<i=0;i<8;i++>Desti->deName[i]=Source->deName[i]; for<i=0;i<3;i++>Desti->deExtension[i]=Source->deExtension[i]; Desti->deAttributes=Source->deAttributes; Desti->deLowerCase=Source->deLowerCase; Desti->deCHundredth=Source->deCHundredth; for<i=0;i<2;i++>Desti->deCTime[i]=Source->deCTime[i]; for<i=0;i<2;i++>Desti->deCDate[i]=Source->deCDate[i]; for<i=0;i<2;i++>Desti->deADate[i]=Source->deADate[i]; Desti->deHighClust=Source->deHighClust; for<i=0;i<2;i++>Desti->deMTime[i]=Source->deMTime[i]; for<i=0;i<2;i++>Desti->deMDate[i]=Source->deMDate[i]; Desti->deStartCluster=Source->deStartCluster; Desti->deFileSize=Source->deFileSize;}#ifFIX_DIRECTORY//searchthefile,when*count=0itwillbringthenumberwholesongs,when*cout!=0the*MusicInfowillbringtheinfomationofthefileBYTESearch<BYTE*dir,structdirentry*MusicInfo,WORD*Count,BYTE*type>//當COUNT為零時,有它帶回這個目錄下總共有多少首音樂{//不為零時有MusicInfo帶回第Count首歌的詳細文件信息 BYTE*buffer; //BYTEbuff[3]; DWORDsector; DWORDcluster; DWORDtempclust; unsignedcharcnt; unsignedintoffset; unsignedinti=0; structdirentry*item=0; cluster=FAT_OpenDir<dir>; if<cluster==1>return1; if<cluster==0&&FAT32_Enable==0>//rootdirectory { buffer=malloc<512>;//applymemory if<buffer==0>return1;//iffailed for<cnt=0;cnt<RootDirSectors;cnt++> { if<FAT_ReadSector<FirstDirSector+cnt,buffer>>{free<buffer
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年租賃合同(設(shè)備)
- 2024年進出口業(yè)務委托合同2篇
- 2024年環(huán)保公益捐贈合同3篇
- 2025年度美容院商鋪租賃及美容院品牌授權(quán)合同3篇
- 2024年西餐廳特許經(jīng)營權(quán)出租及轉(zhuǎn)讓合同
- 2025年度智能家電產(chǎn)品采購與市場推廣合同3篇
- 2024年遺體接送與防腐處理合同3篇
- 教育心理學復習參考試題
- 2025年度旅游景區(qū)門衛(wèi)安全責任書3篇
- 2024綠城物業(yè)服務公司戰(zhàn)略合作合同
- 礦用電纜市場發(fā)展預測和趨勢分析
- 失蹤老人歸家協(xié)議書模板
- 2024年初三數(shù)學競賽考試試題
- 單位委托員工辦理水表業(yè)務委托書
- 2024年江蘇省蘇州市中考英語真題
- 02S501-2 雙層井蓋圖集標準
- 醫(yī)藥制造企業(yè)資本結(jié)構(gòu)優(yōu)化研究以貴州百靈為例
- 小班幼兒能力測查與分析報告
- GB 31335-2024鐵礦開采和選礦單位產(chǎn)品能源消耗限額
- 醫(yī)院高風險意外事件應急措施和救護機制
- 停車場管理系統(tǒng)說明書
評論
0/150
提交評論