SD卡和FAT文件系統示例
我現在用的多是SPI模式,所以在這里只討論SPI模式。在SPI模式中,所有的指令都要求先將CS腳置0。所以這點,我在后面就不再強調了。
CMD0,使SD卡從SD模式轉到SPI模式。判斷返回值R0,如果不是CARD IS NOT READY,說明硬件上有問題。
CMD8,參數是0x000001AA,判斷SD卡符合哪個標準。如果返回ILLEGAL COMMAND,說明是ver1.x的卡,否則就是ver2.0的卡。
CMD1,如果是ver2.0的卡,參數是1<<30,否則就是0,讀取SD卡的狀態,反復,直到CARD IS READY或者超時。這里有一個問題,Spec上建議使用ACMD1,說是通用性比CMD1好,而且CMD1并不是一開始就可以使用的。但是我在實際使用中,發現一些老卡對這個指令會返回PARAMETER ERROR。搞不懂是為什么,而且實際使用中CMD1也很好用,并沒有出現SD卡不能初始化的問題,所以我現在都直接用CMD1。
到這里基本上SD卡就初始化完畢了。接下來就可以讀取數據了。
2. 讀取CID(CMD10),SD卡鑒別信息,這一步不是必須的。
鑒別信息中包括了生產商ID,應用ID,產品名稱,產品版本,產品序列號,生產日期。
3. 讀取CSD(CMD9),SD卡信息。
返回的CSD有兩個版本。
if (CSD[0] & 0x40 == 0x40) // ver2.0的卡
容量 = 1024L*(CSD[8]<<8+CSD[9])
這個數字就是這張SD卡里面總共有多少個扇區。
if (CSD[0] & 0x40 != 0x40) // ver1.x的卡
容量 = (((CSD[6]&0x03)<<10) | (CSD[7]<<2) | ((CSD[8]&0xC0)>>6) + 1) * (1 << ((((CSD[9]&0x03)<<1) | ((CSD[10]&0x80)>>7)) + 2))
4. 讀取Partition Table。
讀取SD卡的扇區0到buf。
如果buf[0]不是0xEB或者0xE9,說明這是一個分區表。
buf[454]開始的四個byte是該分區前的扇區數。例如63表示在這個分區前有63個扇區,那么這個分區的第一個扇區就是扇區63。
buf[458]開始的四個byte是該分區的扇區數。例如7990000,不是這個分區有7990000個扇區。那么這個分區的塊地址就是63~7990063。
一個設備可以最多有四個分區,其他三個分區的相關數據是在buf[470]/buf[474],buf[486]/buf[490],buf[502]/buf[506]。
注意,讀取buf的時候檢查最好兩位,應該是55AA。
5. 讀取BPB。
好,到這里我們已經知道第一個分區是在什么位置了。現在需要做的就是讀取這個分區的0扇區。也就是SD卡的第36個扇區。
這個512個byte就是這個分區的詳細資料了。
檢查buf[0],應該是0xEB或者0xE9。如果是的話,那就是BPB表了。接下來比較重要的幾個數字是:
buf[13]的Sectors Per Cluster,就是每個簇的扇區數,也就是你在讀取文件是需要一次讀取的扇區數。例如8。
buf[14-15]的Reserved Sectors,保留扇區數,這個保留扇區是在分區第一個扇區到FAT表之間的扇區數。例如38。
buf[28-31]的Hidden Sectors,隱藏扇區數,這個隱藏扇區指的是在這個分區前面有多少個扇區,這個值在分區表里也有的。就是63。
buf[19-20]和buf[32-35],前者是FAT16格式中的扇區數,后者是FAT32格式中的扇區數。這個值在分區表里也是有的。就是7990000。
buf[16],FAT表數,一般是2。
buf[22-23],buf[36-39],FAT表占用的扇區數,前者是FAT16的,后者是FAT32的。例如7793。
好了,到這里我們就可以讀取FAT文件系統中的數據了。
6. 讀取FAT表。
在上面的例子中,FAT表的位置應該是分區的第一個扇區再偏移隱藏扇區數,就是63+38,等于101。所以從SD卡的101扇區開始,就是分區一的FAT表,一共有7793個扇區。
7. 讀取根目錄。
在FAT16中,根目錄是單獨的。應該是可以建立512個文件,每個文件占用32byte,所以總共是512*32/512=32個扇區。
根目錄是跟在FAT表后面的,所以第一個扇區是在101+7793*2=15687。
對于FAT32系統,這段忽略。
8. 讀取數據區。
FAT16中,數據區是在根目錄后面的,所以第一個扇區是15687+32=15719。就是在SD卡上的第15719個扇區。
而FAT32中,由于沒有根目錄,所以數據區直接跟在FAT表后面的,所以就是第15687個扇區。這個扇區就是LBA=2的地方。所以之后如果上層的文件操作函數,要對LBA=1000寫數據,那就是對1000+15687=16687扇區進行寫操作。
到此,我們就得到了整個FAT系統的結構和數據,接下來就可以開始操作文件了。


評論