歡迎您光臨本站 登入註冊首頁

單片機與MMC卡的介面

admin @ 2014-03-25 , reply:0

概述

   多媒體卡MMC(MultiMediaCard)是由美國SanDisk公司和德國Simens公司於1997年共同開發推出的一種多功能存儲卡。內置控制電路,可以使用在手……

    多媒體卡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中申請登記項的過程。登記項中包括文件名、文件長度和起始簇號等內容。為此定義了如下結構:    

代碼
  1. typedef struct{   
  2.   u8 FileName[8]; //文件名,不足8位元組用空格補充   
  3.   u8 ExtName[3]; //擴展名   
  4.   u8 attribute; //屬性,典型值:存檔(0x20)、卷標(0x08)   
  5.   u8 reserved[10]; //保留   
  6.   u16 time; //time=Hr*2048+Min*32+Sec+2   
  7.   u16 date; //date=(Yr-1980)*512+Mon*32+Day   
  8.   u16 StartCluster; //起始簇號   
  9.   u32 FileLength; //文件長度   
  10. }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位元組):

代碼
  1. void file_write(DIR_tag  *file_tag,char *data){   
  2.     //data為指向數據的指針   
  3.     u16  j,offset=file_tag.StartCluster*2;   
  4.     //FAT16用16位表示1個簇   
  5.     mmc_read block(&sdc,fat1_addr+offset/512,mmc_buffer);    //讀取起始簇號所在的塊   
  6.     mmc_buffer[offset%512]=0xff;//文件結束標誌ff ff   
  7.     mme_buffer[offset%512+1]=0xff;   
  8.     mmc_write_block(&sdc,fat1_addr+offset/512,mmc_buffer);    //寫FAT1   
  9.   mmc_write_block(&sdc,fat2_addr+offset/512,mmc_buffer);    //寫FAT2,與FAT1同   
  10.   for(j=0,j<file_tag.FileLength;j++) mmc_buffer[i]=data[j];   
  11.   mmc_write_block(&sdc,519+(file_tag.StartCluster-2),mmc_buffer);    //寫入數據   
  12. }  

3.3 文件的刪除
    文件的刪除也是對MMC卡上文件管理的一個重要方面。刪除文件時,並不涉及數據區的操作,只須在文件的目錄登記項上作一個刪除標記,並把文件在FAT表中所佔用的簇標記為“空簇”。刪除文件的代碼如下:

代碼
  1. int file_delete(DIR_tag *file_tag){   
  2.   u16 k,clust_buf,offset1,offset= file_tag.StartCluster*2; //FAT16用16位表示1個簇   
  3.   file_tag.FileName[7]=0xe5;//FDT中文件被刪除標誌   
  4.   write_fdt(file_tag);//寫修改過的目錄登記項寫回MMC卡   
  5.   k= file_tag.FileLength/512+1;//總循環次數   
  6.   mmc_read_block(&sde,fat1_addr+offset/512,mmc_buffer);   
  7. //讀取起始簇號所在的塊   
  8.   do {   
  9.     clust_buf= mmc_buffer[offset%512]&0x00ff(mmc_buffer[offset%512+1]&0x00ff)<<8;   
  10.     if(clust_buf!= 0xffff){ //不是文件終止   
  11.     mmc_buffer[offset%512]=0; //空簇標誌00 00   
  12.     mmc_buffer[offset%512+1]=0;   
  13.     offset1= clust_buf*2; //偏移地址   
  14.     }   
  15.     else//文件終止,完成返回1   
  16.     mmc_buffer[offset%512]=0;   
  17.     mmc_buffer[offset%512+1]=0;   
  18.     mmc_write_block(&sde,fat1_addr+ offset/512,mmc_buffer); //寫FAT1   
  19.     mmc_write_block(&sdc,fat2_addr+ offset/512,mmc_buffer); //寫FAT2,內容與FAT1同   
  20.     return 1;   
  21.     }   
  22.     if(offset1/512 !=offset/512){   
  23.     mmc_write_block(&sdc,fat1_addr+ offset/512,mmc_buffer); //寫FAT1   
  24.     mmc_write_block(&sdc,fat2_addr+ offset/512,mmc_buffer); //寫FAT2,內容與FAT1同   
  25.     mmc_read_block(&sdc,fat1_addr+ offset1/512,mmc_buffer); //讀取下一簇號所在的塊   
  26.     }   
  27.     offset= offset1; k--;   
  28. }while(k>=0);   
  29. return 0; //未找到文件結束標誌,返回0  

4 小結
    通過對SPI模式下MMC卡讀寫和文件系統的研究,實現了單片機對MMC卡FAT16文件的管理,包括文件的創建、讀寫、刪除等操作。該方法為數據採集系統提供了一種非易失性存儲器的解決方案,採集到的數據會以標準文件的格式記錄到MMC卡上,數據文件可在Windows下用讀卡器讀取,在保證高性價比的同時,又方便了數據的進一步分析、處理。通過在長時間心電圖監測系統中的實際應用,證明了該方法的可行性。該方案也可應用到諸如MP3等與Windows有交互的移動存儲設備中,便於文件的統一管理。
    系統採用SPI介面,佔用較少的I/O資源。由於SD卡也支持SPI模式,故文中的MMC卡也可以用SD卡替代。


[admin via 研發互助社區 ] 單片機與MMC卡的介面已經有1845次圍觀

http://cocdig.com/docs/show-post-42209.html