媒體卡MMC(MultiMedia Card)是由美國SanDisk公司和德國Simens公司于1997年共同開發推出的一種多功能存儲卡。內置控制電路,可以使用在手機、數碼相機、MP3、PDA等多種數字設備上,可反復記錄30萬次。現在市場上的主流容量有128 MB~2 GB。
???
?????? ?文中首先介紹單片機對SPI協議下的MMC卡的底層讀寫操作,然后分析MMC卡文件系統的結構,最后詳細說明MMC卡文件的創建、讀寫、刪除等操作。該方法可應用到與Windows有交互的嵌入式系統中,便于文件的統一管理。
?????? 1 單片機與MMC卡的接口
?????? 1.1 單片機與MMC卡的接口電路
???
?????? 接口電路采用的是Philips公司的增強型LPC93x系列單片機。它除了比普通的8051有更快的指令執行周期外,還提供多種在片的硬件接口功能,如UART、SPI、I2C等,因此用LPC93x的SPI接口實現單片機與MMC卡的互連。
???
?????? MMC卡有7個引腳,支持兩種串行數據傳輸協議,即MMC(Multimedia Card)模式和SPI(Serial PeripheralInterface)模式。在SPI模式中,通過4條信號線完成數據的傳輸。這4條信號線分別是時鐘SPICLK、數據輸入MISO、數據輸出MOSI和片選SS#。
???
?????? ?LPC93x單片機與MMC卡的接口電路如圖1所示。
?
?????? 1.2 MMC卡底層讀寫原理
???
??????? MMC卡讀寫操作都是基于命令的,通過向MMC卡發送樞直的命令并讀取樞直的響應來實現對MMC卡的控制。在對MMC卡讀寫之前,首先要進行初始化操作。這是確保MMC卡能在SPI模式下進行正常數據讀寫的前提。需要注意的是,在發送使MMC卡空閑命令CMD0之前至少等待74個時鐘,確保MMC卡進入SPI模式。
???
??????? 初始化完成之后,如果使用默認的塊讀寫長度(512字節),就可進行MMC卡的讀寫。當然,也可用CMD16來設置。MMC卡的塊讀取長度,可以是1~512字節之間的任意值。但是對MMC的寫過程則要求塊長度必須為512字節。無論是MMC卡的讀還是寫,都要求在讀寫命令發送后有數據起始令牌FEH,數據傳輸結束之后有2個字節的循環冗余編碼CRC(Cyclic Redundancy Codes)。
??????? 2 MMC卡文件系統的結構分析
???
?????? 要使寫入MMC卡的數據在Windows下訪問,需要在MMC卡上創建Windows支持的FATl6文件系統。MMC卡上的FATl6文件系統的結構包含分區引導記錄、文件分配表、文件目錄表以及數據區4個部分。
???
???? ?分區引導記錄通常包含4塊內容;
???? ?①BIOS參數記錄塊BPB(BIPS Parameter Block);
???? ?②磁盤標志記錄表;
???? ?③分區引導記錄代碼區;
????? ④結束標志55AA。
???
?????? BPB表從扇區字節位移0bH開始,共占25字節。表1是從MMC卡的首扇區中讀出的BPB表的內容。
?????? 在分區引導記錄之后是FAT(File Allocation Table,文件分配表)區。FATl6的文件系統中有兩份完全相同的文件分配表FAT1和FAT2,每份FAT表占用空間的大小可從BPB表中查得。
???
?????? 文件在磁盤上以簇為單位存儲,但是同一個文件的數據并不一定完整地存放在磁盤的一個連續的區域內,往往會分成若干簇,FAT表就是記錄文件存儲中簇與簇之問連接信息的,這就是文件的鏈式存儲。FATl6以2個字節(即16位)表示1個簇,起始2個字為F8FFH、FFFFH,后面的FFFFH表示終止,0000H表示未使用。
???
?????? 緊接在FAT表之后的是文件目錄表FDT,固定占32個扇區,每個扇區可以容納16個登記項,每個登記項的長度是32字節。
???
??????? 文件目錄表之后就是數據區DATA,用來存放文件數據,占用大部分的磁盤空間。
?????? 3 MMC卡文件系統的實現
???
??????? 單片機對MMC底層的讀寫,按照FAT16的格式對MMC卡上數據進行操作,就可在MMC卡上創建文件、讀寫文件和刪除文件等,從而實現文件的管理。3.1 文件(或目錄)的創建
???
?????? 在MMC卡上創建文件(或目錄)的過程就是在文件目錄表FDT中申請登記項的過程。登記項中包括文件名、文件長度和起始簇號等內容。為此定義了如下結構:???
???? 代碼
typedef struct{???
? u8 FileName[8]; //文件名,不足8字節用空格補充???
? u8 ExtName[3]; //擴展名???
? u8 attribute; //屬性,典型值:存檔(0x20)、卷標(0x08)???
? u8 reserved[10]; //保留???
? u16 time; //time=Hr*2048+Min*32+Sec+2???
? u16 date; //date=(Yr-1980)*512+Mon*32+Day???
? u16 StartCluster; //起始簇號???
? u32 FileLength; //文件長度???
}DIR_tag;??
????? ? 文件名一般占用8字節,長的文件名需要用resetx,ed[]數組。文件名的首字節又表明該文件的狀態,00H表示該目錄項未使用,E5H表示該文件(或目錄)已被刪除。創建目錄時,屬性值設置為10H(表示子目錄),文件長度為0。
????? 3.2 文件的讀寫
???
??????? MMC卡上文件都是以簇為單位存取的。當讀取MMC卡上的文件時,首先要根據文件名查找到該文件的目錄登記項。根據目錄登記項中的起始簇號既可找到文件在數據區DATA中第1簇的內容,又可在FAT表中找到第2個簇號。根據第2個簇號又能找到第2簇的內容和FAT表中的第3個簇號。這樣,就可以根據FAT表中的簇號讀取到全部文件數據。寫文件時要保證FAT1和FAT2中內容的一致性,即對兩塊都要進行同樣的寫操作。對于FATl6,可以由下面的公式計算出數據起始邏輯扇區號:
???
?????? 起始邏輯扇區=隱藏扇區數+1+2*每FAT扇區數+FDT扇區數+(起始簇號-2)*每簇扇區數
???
?????? 從表1可知,MMC卡上隱藏的扇區數為0,每個FAT占用243個扇區,FDT固定占用32個扇區。寫文件的相關代碼如下(設文件長度小于512字節):
?????? 代碼
void file_write(DIR_tag? *file_tag,char *data){???
??? //data為指向數據的指針???
??? u16? j,offset=file_tag.StartCluster*2;???
??? //FAT16用16位表示1個簇???
??? mmc_read block(&sdc,fat1_addr+offset/512,mmc_buffer);??? //讀取起始簇號所在的塊???
??? mmc_buffer[offset%512]=0xff;//文件結束標志ff ff???
??? mme_buffer[offset%512+1]=0xff;???
??? mmc_write_block(&sdc,fat1_addr+offset/512,mmc_buffer);??? //寫FAT1???
? mmc_write_block(&sdc,fat2_addr+offset/512,mmc_buffer);??? //寫FAT2,與FAT1同???
? for(j=0,j
}??
?????? 3.3 文件的刪除
???
??????? 文件的刪除也是對MMC卡上文件管理的一個重要方面。刪除文件時,并不涉及數據區的操作,只須在文件的目錄登記項上作一個刪除標記,并把文件在FAT表中所占用的簇標記為“空簇”。刪除文件的代碼如下:
- int?file_delete(DIR_tag?*file_tag){ ??
- ??u16?k,clust_buf,offset1,offset=?file_tag.StartCluster*2;?//FAT16用16位表示1個簇 ??
- ??file_tag.FileName[7]=0xe5;//FDT中文件被刪除標志 ??
- ??write_fdt(file_tag);//寫修改過的目錄登記項寫回MMC卡 ??
- ??k=?file_tag.FileLength/512+1;//總循環次數 ??
- ??mmc_read_block(&sde,fat1_addr+offset/512,mmc_buffer); ??
- //讀取起始簇號所在的塊 ??
- ??do?{ ??
- ????clust_buf=?mmc_buffer[offset%512]&0x00ff(mmc_buffer[offset%512+1]&0x00ff)<<8; ??
- ????if(clust_buf!=?0xffff){?//不是文件終止 ??
- ????mmc_buffer[offset%512]=0;?//空簇標志00?00 ??
- ????mmc_buffer[offset%512+1]=0; ??
- ????offset1=?clust_buf*2;?//偏移地址 ??
- ????} ??
- ????else{?//文件終止,完成返回1 ??
- ????mmc_buffer[offset%512]=0; ??
- ????mmc_buffer[offset%512+1]=0; ??
- ????mmc_write_block(&sde,fat1_addr+?offset/512,mmc_buffer);?//寫FAT1 ??
- ????mmc_write_block(&sdc,fat2_addr+?offset/512,mmc_buffer);?//寫FAT2,內容與FAT1同 ??
- ????return?1; ??
- ????} ??
- ????if(offset1/512?!=offset/512){ ??
- ????mmc_write_block(&sdc,fat1_addr+?offset/512,mmc_buffer);?//寫FAT1 ??
- ????mmc_write_block(&sdc,fat2_addr+?offset/512,mmc_buffer);?//寫FAT2,內容與FAT1同 ??
- ????mmc_read_block(&sdc,fat1_addr+?offset1/512,mmc_buffer);?//讀取下一簇號所在的塊 ??
- ????} ??
- ????offset=?offset1;?k--; ??
- }while(k>=0); ??
- return?0;?//未找到文件結束標志,返回0??
????? 4 小結
???
?????? 通過對SPI模式下MMC卡讀寫和文件系統的研究,實現了單片機對MMC卡FAT16文件的管理,包括文件的創建、讀寫、刪除等操作。該方法為數據采集系統提供了一種非易失性存儲器的解決方案,采集到的數據會以標準文件的格式記錄到MMC卡上,數據文件可在Windows下用讀卡器讀取,在保證高性價比的同時,又方便了數據的進一步分析、處理。通過在長時間心電圖監測系統中的實際應用,證明了該方法的可行性。該方案也可應用到諸如MP3等與Windows有交互的移動存儲設備中,便于文件的統一管理。
???
??????? 系統采用SPI接口,占用較少的I/O資源。由于SD卡也支持SPI模式,故文中的MMC卡也可以用SD卡替代。
評論
查看更多