摘要:基于HCSl2X單片機(jī)SPI模塊讀取Micro SD卡與SD卡,并解析SD卡上FAT文件系統(tǒng)以實(shí)現(xiàn)文件的讀取與寫入。測(cè)試證明,系統(tǒng)對(duì)FAT文件系統(tǒng)的讀取穩(wěn)定,誤差小,速度較快。使用HCSl2X類單片機(jī)對(duì)SD卡進(jìn)行讀取,在汽車智能設(shè)計(jì)和單片機(jī)調(diào)試方面有較高的應(yīng)用價(jià)值。
關(guān)鍵詞:HCSl2X單片機(jī);SPI模塊;SD卡;Micro SD卡;FAT文件系統(tǒng)
隨著信息技術(shù)的飛速發(fā)展,高容量存儲(chǔ)芯片日益向大容量小體積發(fā)展,其中以SD卡、Micro SD卡為突出代表。SD卡由日本松下、東芝及美國(guó)SanDisk公司于1999年8月共同開發(fā)研制。大小猶如一張郵票的SD卡,重量只有2 g,卻擁有高記憶容量、快速數(shù)據(jù)傳輸率、極大的移動(dòng)靈
活性以及很好的安全性。通過(guò)單片機(jī)處理SD卡信息,可以將信息化嵌入式產(chǎn)業(yè)向更小體積發(fā)展。考慮到穩(wěn)定性與讀取速度,研究中采用了Freescale公司的16位單片機(jī)MC9S12XSl28MAA。為了進(jìn)一步滿足嵌入式研究的實(shí)時(shí)調(diào)試與應(yīng)用需要,把SD卡的讀取以及FATl6文件系統(tǒng)的讀取寫入移植到此單片機(jī)中,使開發(fā)應(yīng)用有更好的擴(kuò)展性。本文首次把FATl6文件系統(tǒng)的讀取移植到HCSl2X單片機(jī)上,并通過(guò)HCSl2X單片機(jī)的SPI模塊進(jìn)行SD卡的讀寫,取得了良好的效果。
1 研究平臺(tái)和設(shè)計(jì)思想
1.1 平臺(tái)介紹
①M(fèi)CS9S12XSl28MAA:Freescale公司16位單片機(jī)HCSl2X家族中的一員,相比于其他HCSl2X單片機(jī),去除了XGATE協(xié)處理器,大大降低了成本。此單片機(jī)內(nèi)嵌了許多資源,包括128KB Flash、4 KB EEPROM、16 KBROM以及多種通信接口。
②Micro SD卡:采用SD架構(gòu)設(shè)計(jì)而成,尺寸幾乎只有一片指甲蓋大小,由摩托羅拉公司與SanDisk公司共同研發(fā),是一種超小型卡(11 mm×15 mm×1 ram),約為SD卡的1/4。它支持3種傳輸模式,SPI模式(獨(dú)立序列輸入和序列輸出),1位SD模式(獨(dú)立指令和數(shù)據(jù)通道,獨(dú)有的
傳輸格式),以及4位SD模式(使用額外的引腳以及某些重新設(shè)置的引腳,支持4位寬的并行傳輸)。
③CodeWarrior:Freescale公司開發(fā)的編程環(huán)境。本文使用的CodeWarrior Special 5.0 For S12(X)是專門針對(duì)HCSl2X單片機(jī)開發(fā)的,可以進(jìn)行程序的編輯、編譯、鏈接和在線調(diào)試等多項(xiàng)功能,支持在C語(yǔ)言中嵌入?yún)R編語(yǔ)言。
④移植條件:對(duì)于本文中的SD卡讀取與寫入,用戶的單片機(jī)推薦使用HCSl2X系列,也可使用HCSl2系列,但總線超頻會(huì)不穩(wěn)定,從而影響SD卡讀寫速率以及穩(wěn)定性。
1.2 設(shè)計(jì)思想
圖1顯示了本文中所使用的SD卡FAT文件系統(tǒng)通過(guò)MC9S12XSl28MAA進(jìn)行解析的軟硬件結(jié)構(gòu)體系。編譯鏈接軟件使用CodeWarrior 5.O,硬件采用MC9S12XSl28MAA單片機(jī)與Kingston公司的Micro SD卡。代碼由4部分組成:用戶應(yīng)用部分(由用戶編寫控制,本文使用MC9S12XS128MAA SCI串口模塊進(jìn)行信息調(diào)試),F(xiàn)AT文件系統(tǒng)讀取解析部分,硬件控制部分(通過(guò)單片機(jī)SPI模塊與SD卡連接),以及單片機(jī)CPU的初始化部分。其中,SPI模塊與SD卡連接的硬件控制部分,以及FAT文件系統(tǒng)的讀取解析部分是本文的重點(diǎn)。
其中,Sd_SPI.h是關(guān)于SD卡讀取寫入部分的一些宏定義、常量和函數(shù)的聲明;Sd_SPI.c包括了通過(guò)SPI模塊讀寫SD卡的代碼;Fat.h是關(guān)于Fat文件系統(tǒng)解析的全局變量、宏定義以及函數(shù)聲明;Fat.c包括了Fat文件系統(tǒng)解析的代碼;SimpleFat.c是簡(jiǎn)易讀取Fat文件系統(tǒng)信息的代碼;SimpleFat.h是其全局變量以及函數(shù)的聲明。
2 硬件設(shè)計(jì)
SD卡有2種操作模式:SD卡模式、SPI模式。SD卡模式允許通過(guò)4線高速總線傳輸,但由于大部分單片機(jī)無(wú)此接口模塊,故選擇SPI模式。HCSl2X系列單片機(jī)內(nèi)部都帶有此同步串行外部設(shè)備接口(Serial Peripheral Interface,SPI)。單片機(jī)可以通過(guò)SPI系統(tǒng)組成一個(gè)通信速率比SCI高的同步網(wǎng)絡(luò),故使用SPI模式可以把外設(shè)減少到最低。SPI模式相對(duì)于SD卡模式的缺點(diǎn)是損失了傳輸速度;但是目前的微處理器的處理速度越來(lái)越高,利用SPI模式大都能滿足工程需要。
HCSl2X單片機(jī)的全雙工8位SPI模塊有4個(gè)引腳,分別為主入從出引腳MISO、主入從出引腳MOSI、串行時(shí)鐘引腳SCK以及從機(jī)片選引腳SS。當(dāng)CS信號(hào)線為低電平時(shí),主機(jī)開始所有的總線傳輸。數(shù)據(jù)從單片機(jī)的MOSI引腳同步輸入Micro SD卡的DA引腳,Micro SD卡返回?cái)?shù)據(jù)由DO線同步輸入單片機(jī)的MISO引腳,數(shù)據(jù)在CLK信號(hào)的上升沿同步輸入和輸出。
3 軟件設(shè)計(jì)
3.1 HCSl2X總線時(shí)鐘超頻
MC9S12XSl28MAA默認(rèn)總線時(shí)鐘默認(rèn)同外接晶振相關(guān),但可以通過(guò)配置PLL鎖相環(huán)實(shí)現(xiàn)單片機(jī)總線超頻,從而加快SD卡讀取速率。實(shí)驗(yàn)中可通過(guò)下列代碼將單片機(jī)總線頻率超頻到80MHz:
3.2 HCSl2XSPl模塊初始化
MC9S12XSl28MAA單片機(jī)包含2個(gè)串行外設(shè)接口SPI,可以很方便地實(shí)現(xiàn)對(duì)Micro SD卡接口的數(shù)據(jù)傳輸。為了配置時(shí)鐘和數(shù)據(jù)長(zhǎng)度,需要對(duì)SPI控制寄存器(SPCRl和SPICR2)、SPI波特率寄存器SPIBR和SPI數(shù)據(jù)寄存器SPIDR進(jìn)行設(shè)置:使能SPI模塊,將SPICRl中的MSTR位置1使單片機(jī)工作在主機(jī)模式,產(chǎn)生串行時(shí)鐘來(lái)同步主從雙方的移位寄存器,配置SPI時(shí)鐘極性位與SPI時(shí)鐘相位控制位,使能從機(jī)輸出選擇;初始化SPI波特率寄存器。
3.3 SD卡初始化
SD卡初始數(shù)據(jù)傳輸需工作在低于400 kb/s的頻率,因此配置SPI波特率寄存器,以工作在低速模式下。片選信號(hào)后應(yīng)延時(shí)至少74個(gè)時(shí)鐘周期。SD卡默認(rèn)缺省使用SD總線傳輸協(xié)議,主機(jī)需要發(fā)出命令CMDO(CMD_GO_IDLE_STATE)才能使SD卡工作在SPI傳輸模式下,當(dāng)單片機(jī)返回0x 01時(shí)說(shuō)明已經(jīng)進(jìn)入了IDLE狀態(tài)。此時(shí)應(yīng)循環(huán)發(fā)送CMD55+ACMD41以確認(rèn)是否為SD卡,如果回應(yīng)超時(shí)則發(fā)送CMDl(CMD_SEND_OP_COND)以確認(rèn)是否為MMC卡。經(jīng)實(shí)驗(yàn)發(fā)現(xiàn),Kingston公司的Micro SD卡使用CMD55+ACMD41或者CMDl都可以進(jìn)行激活。激活SD卡的SPI模式后SD卡進(jìn)入準(zhǔn)備狀態(tài),此時(shí)發(fā)送CMDl6(CMD_SET_BLOCKLEN)設(shè)置SD卡的讀寫塊大小,然后重新配置SPI波特率寄存器SPIBR使單片機(jī)SPI工作在高速頻率下,延時(shí)8個(gè)時(shí)鐘周期后返回,完成SD卡初始化。圖2為SD卡SPI高速模式初始化流程。
3.4讀寫單塊數(shù)據(jù)
SD卡單塊數(shù)據(jù)的讀取是先通過(guò)單片機(jī)發(fā)送CMDl7(CMD_READ_SINGLE_BLOCK)命令,以SD卡指定數(shù)據(jù)塊起始位地址作為參數(shù),如果讀取成功SD卡會(huì)返回1個(gè)R1命令作為響應(yīng)。然后發(fā)送1個(gè)起始數(shù)據(jù)命令,接著發(fā)送單塊字節(jié)數(shù)量的數(shù)據(jù)并接收SPI數(shù)據(jù)寄存器SPIDR中的數(shù)據(jù),最后是2字節(jié)CRC校驗(yàn)。
SD卡單塊數(shù)據(jù)的寫入與讀取相似,通過(guò)單片機(jī)發(fā)送CMD24(CMD_WRITE_SINGLE_BLOCK)命令,以SD卡指定數(shù)據(jù)塊起始位地址作為參數(shù),如果讀取成功SD卡會(huì)返回1個(gè)R1命令作為響應(yīng)。然后發(fā)送1個(gè)起始數(shù)據(jù)命令,接著發(fā)送單塊字節(jié)數(shù)量的需寫入數(shù)據(jù),最后是2字節(jié)CRC校驗(yàn)。
3.5 FAT文件系統(tǒng)信息讀取
為了SD卡文件數(shù)據(jù)管理方便并且與PC機(jī)之間兼容得更好,同時(shí)考慮到SD卡自身容量的限制,選擇FATl6文件系統(tǒng)對(duì)SD卡信息進(jìn)行管理。
為了方便管理和擴(kuò)展性開發(fā),對(duì)SD卡進(jìn)行了分區(qū)。模擬硬盤模式創(chuàng)建出了MBR區(qū)(主引導(dǎo)扇區(qū))與DBR區(qū)(操作系統(tǒng)引導(dǎo)記錄區(qū)),在向下兼容的同時(shí)實(shí)現(xiàn)了對(duì)分區(qū)過(guò)的SD卡FAT文件系統(tǒng)的讀寫。
SD卡數(shù)據(jù)可分為5部分:MBR區(qū)、DBR區(qū)、FAT區(qū)、DIR區(qū)和DATA區(qū)。MBR區(qū)是主引導(dǎo)區(qū),位于整個(gè)SD卡的第1單塊上。在總共512字節(jié)的主引導(dǎo)扇區(qū)中,MBR只占用了其中的446個(gè)字節(jié),另外的64個(gè)字節(jié)是DPT(Disk Partition Table,分區(qū)表),最后2個(gè)字節(jié)“55 AA”是分區(qū)的結(jié)束標(biāo)志。這整體構(gòu)成了SD卡的主引導(dǎo)扇區(qū)。DBR是操作系統(tǒng)引導(dǎo)記錄區(qū),是操作系統(tǒng)可以直接訪問(wèn)的第1個(gè)扇區(qū),它包括1個(gè)引導(dǎo)程序和1個(gè)被稱為BPB(Bios Parameter Block)的本分區(qū)參數(shù)記錄表。BPB參數(shù)塊記錄著本分區(qū)的起始扇區(qū)、結(jié)束扇區(qū)、文件存儲(chǔ)格式、硬盤介質(zhì)描述符、根目錄大小、FAT、個(gè)數(shù),分配單元的大小等重要參數(shù)。
FAT文件系統(tǒng)的分區(qū)有如下幾個(gè)部分:保留區(qū),存放FAT文件系統(tǒng)的重要參數(shù)和引導(dǎo)程序;FAT表,記錄簇使用情況;根目錄區(qū),記錄根目錄信息。
本文中單片機(jī)對(duì)FAT系統(tǒng)的讀寫利用的是MBR區(qū)上的DPT分區(qū)表信息,用于找到FAT分區(qū)。然后通過(guò)FAT分區(qū)的DBR區(qū)上的BPB分區(qū)參數(shù)記錄表信息找到根目錄,讀取根目錄信息并通過(guò)FAT表中的文件簇信息實(shí)現(xiàn)文件的管理。
研究中為方便代碼的移植和優(yōu)化,在FAT初始化的時(shí)候?qū)⒆x寫扇區(qū)函數(shù)指針指向Micro SD卡的讀寫函數(shù),并使用了2個(gè)結(jié)構(gòu)體來(lái)存儲(chǔ)SD卡的MBR與DBR信息。但鑒于單片機(jī)自身的內(nèi)存容量,又建立了1個(gè)SimpleFat.c程序文件,只存儲(chǔ)程序所需的幾個(gè)地址常量:StartMbrAddress(MBR起始地址)、StartDbrAddress(DBR起始地址)、StartFatlAddress(FATl表起始地址)以及SeePerClu(簇扇區(qū)數(shù)量),大大減小了單片機(jī)內(nèi)存的開銷。
3.6 應(yīng)用層函數(shù)接口
FAT文件系統(tǒng)向應(yīng)用層設(shè)計(jì)了如下幾個(gè)初級(jí)程序接口:Get Filelnfo(UINT8*F Info,F(xiàn)ileInfo*TempFilelnfo)(獲取文件信息),OutPut _RootFileinfo(void)(輸出根目錄文件信息),DirOr(UINT8 FileAttrib)(判斷目錄),Get Next Cluster(UINTl6 TempCluster)(獲取下一文件簇信息),OutPutFileCluster(UINTl6 TempStart Cluster)(輸出文件簇地址),OutPutFile(UINTl6 Temp StartCluster)(輸出文件內(nèi)容),ShowClusterContent(UINTl6 TempCluster)(輸出簇內(nèi)容)。通過(guò)這些初級(jí)程序接口實(shí)現(xiàn)了OpenDir(UINTl6 TempStartCluster)(目錄打開),F(xiàn)ileDelete(文件刪除),F(xiàn)ileDataRead(文件數(shù)據(jù)讀取),F(xiàn)ileCreate(UINTl6 TempStartCluster,UINT32TempFileLength)(文件創(chuàng)建)等功能。
3.6.1 目錄讀取及文件信息獲取
FAT文件系統(tǒng)的具體文件和目錄項(xiàng)都是通過(guò)讀取ROOT目錄來(lái)進(jìn)行查找的,所以FAT的文件排布是以樹形的結(jié)構(gòu)排布。對(duì)于FAT來(lái)說(shuō),目錄項(xiàng)與文件項(xiàng)在同一目錄中是同樣占32個(gè)字節(jié)的屬性項(xiàng)。研究中使用了1個(gè)數(shù)據(jù)結(jié)構(gòu)Filelnfo來(lái)存儲(chǔ)文件信息,并通過(guò)if(Temp_F_Info[0x0b]&0x l0)來(lái)分辨文件與目錄。
在FAT文件系統(tǒng)中,文件是以簇的形式保存在SD卡中的,簇的排布是不連續(xù)的,1個(gè)文件如果大于1個(gè)簇的話,則要通過(guò)FAT表來(lái)查找該文件所有簇所在的位置,從而找到整個(gè)文件。目錄一般只占有1個(gè)簇的大小,在FAT表中等同于小于1個(gè)簇的小文件,值顯示為FF。
目錄是以文件的形式存儲(chǔ)在父目錄中的,目錄中的文件信息記錄了該文件的起始簇以及文件的大小,知道了文件的起始簇,通過(guò)FAT表中的信息可以很方便地找到文件的下一個(gè)簇的位置,并由文件的大小判斷出文件的結(jié)束位置。
3.6.2 文件的讀寫
在FAT文件系統(tǒng)中,讀取文件只需要知道該文件的起始簇以及大小便可以很方便地得到整個(gè)文件的信息。讀取步驟是:獲取根目錄信息,通過(guò)根目錄信息找到下一層目錄所在簇位置,通過(guò)下一層目錄信息遞歸找到文件所在目錄,讀取文件信息屬性,得到文件的起始簇位置和文件大小,通過(guò)FAT表遞歸查找到文件的全部簇地址,最終以FF結(jié)尾;根據(jù)文件大小判斷文件的結(jié)束位置,最后輸出整個(gè)文件。
文件的創(chuàng)建和寫入則是通過(guò)FAT表查找未被使用的空簇(值為00),寫滿1簇之后再查找下一未被使用的空簇,并同時(shí)更新FAT1表和FAT2表。然后在文件所被創(chuàng)建的目錄信息中添加文件信息,最終實(shí)現(xiàn)文件的創(chuàng)建。
3.6.3 文件的刪除
在FAT文件系統(tǒng)中,對(duì)文件的刪除不需要把整個(gè)文件信息全部清除,只需要清除FAT表中的文件簇信息以及目錄中的文件信息,避免了對(duì)SD卡的頻繁讀寫,同時(shí)也節(jié)省了時(shí)間。
結(jié)語(yǔ)
本設(shè)計(jì)將SD卡的存儲(chǔ)方式應(yīng)用到單片機(jī)系統(tǒng)中,簡(jiǎn)化了復(fù)雜的文件數(shù)據(jù)的存儲(chǔ)設(shè)計(jì),減小了系統(tǒng)的尺寸,提高了系統(tǒng)的可靠性,使得單片機(jī)對(duì)文件的讀出和存取簡(jiǎn)單易行。對(duì)FAT裁減實(shí)現(xiàn)了嵌入式文件系統(tǒng),提高了系統(tǒng)的存儲(chǔ)能力,同時(shí)也增強(qiáng)了單片機(jī)與PC級(jí)之間的通信能力,簡(jiǎn)化了繁瑣的調(diào)試。采用Freescale 16位單片機(jī)MC9S12XSl28MAA的串行外設(shè)接口SPI對(duì)SD卡進(jìn)行訪問(wèn),加快了整個(gè)系統(tǒng)的設(shè)計(jì)進(jìn)度。實(shí)踐證明,該設(shè)計(jì)讀寫SD卡文件信息的速度以及穩(wěn)定性滿足調(diào)試要求。該設(shè)計(jì)只需對(duì)底層驅(qū)動(dòng)進(jìn)行簡(jiǎn)單修改就可直接應(yīng)用于MMC卡、Micro SD卡等其他存儲(chǔ)介質(zhì)上。