2011年5月21日 星期六

DIY - PIC:SD 記憶卡初始化 (七十三)

DIY - PICSD 記憶卡初始化 (十三)

將會使用 Microchip PIC18F4550 SPI 模式 SPI 模式中所有的指令都要求先將 CS 腳置 0 (低電位)。命令格式是個一個字節的命令格式為 01xx xxxx 後六位是 CMD  後面的數字的二進制值,如 CMD1=0100 0001=0x41。需要註意初始化時SPI速率不能超過 400K

SD 記憶卡初始化程式流程圖
 1. SD卡初始化

Secure Digital 卡內的存儲器
Secure Digital 卡的 CMD指令
CMD0 SD 卡從 SD 模式轉到 SPI 模式。判斷返回值 R0,如果不是 CARD IS NOT READY,說明硬體上有問題。CMD0 之前要向 SD 卡發送至少 74 個時鐘周期,只有 CMD0 需要這樣特殊要求。

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

Secure Digital 卡識別模式的狀態圖
  基本上 SD 卡就初始化完畢了,接下來就可以讀取資料了。

2. 讀取CIDCMD10
SD 卡鑒別資訊,這一步不是必須的。鑒別資訊中包括了生產商 ID,應用 ID,產品名稱,產品版本,產品序列號,生產日期。

名稱 數據寬度 CID劃分
生產標識號 MID 8 [127:120]
OEM/應用標識 OID 16 [119:104]
產品名稱 PNM 40 [103:64]
產品版本 PRV 8 [63:56]
產品序列號 PSN 32 [55:24]
保留 4 [23:20]
生產日期 MDT 12 [19:8]
CRC7校驗合 CRC 7 [7:1]
未使用,始終為1 1 [0:0]
CID 寄存器長度為 128 位。它的寄存器結構

3. 讀取CSDCMD9),SD卡信息
返回的 CSD 有兩個版本。

名稱 數據寬度 單元類型 CSD劃分
CSD結構 CSD_STRUCTURE 2 R [127:126]
保留 - 6 R [125:120]
資料讀取時間1 TAAC 8 R [119:112]
資料在CLK週期內讀取時間2NSAC*100 NSAC 8 R [111:104]
最大資料傳輸率 TRAN_SPEED 8 R [103:96]
卡命令集合 CCC 12 R [95:84]
最大讀取資料塊長 READ_BL_LEN 4 R [83:80]
允許讀的部分塊 READ_BL_PARTIAL 1 R [79:79]
非線寫塊 WRITE_BLK_MISALIGN 1 R [78:78]
非線讀塊 READ_BLK_MISALIGN 1 R [77:77]
DSR條件 DSR_IMP 1 R [76:76]
保留 - 2 R [75:74]
設備容量 C_SIZE 12 R [73:62]
最大讀取電流@VDD min VDD_R_CURR_MIN 3 R [61:59]
最大讀取電流@VDD max VDD_R_CURR_MAX 3 R [58:56]
最大寫電流@VDD min VDD_W_CURR_MIN 3 R [55:53]
最大寫電流@VDD max VDD_W_CURR_MAX 3 R [52:50]
設備容量乘子 C_SIZE_MULT 3 R [49:47]
擦除單塊使能 ERASE_BLK_EN 1 R [46:46]
擦除磁區大小 SECTOR_SIZE 7 R [45:39]
防寫群大小 WP_GRP_SIZE 7 R [38:32]
防寫群使能 WP_GRP_ENABLE 1 R [31:31]
保留 - 2 R [30:29]
寫速度因數 R2W_FACTOR 3 R [28:26]
最大寫資料塊長度 WRITE_BL_LEN 4 R [25:22]
允許寫的部分部 WRITE_BL_PARTIAL 1 R [21:21]
保留 - 5 R [20:16]
檔系統群 FILE_OFRMAT_GRP 1 R/W [15:15]
拷貝標誌 COPY 1 R/W [14:14]
永久防寫 PERM_WRITE_PROTECT 1 R/W [13:13]
暫時防寫 TMP_WRITE_PROTECT 1 R/W [12:12]
檔系統 FIL_FORMAT 2 R/W [11:10]
保留 - 2 R/W [9:8]
CRC CRC 7 R/W [7:1]
未用,始終為1 - 1
[0:0]
CSDCard-Specific Data)寄存器





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 卡的磁區0buffer如果buf[0] 不是 0xEB 或者 0xE9,說明這是一個分區表。buf[454] 開始的四個 byte是該分區前的磁區數。例如 63 表示在這個分區前有 63 個磁區,那麼這個分區的第一個磁區就是磁區 63buf[458] 開始的四個 byte 是該分區的磁區數。例如 7990000,不是這個分區有 7990000 個磁區。那麼這個分區的塊位址就是 637990063一個設備可以最多有四個分區,其他三個分區的相關資料是在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[16]FAT表數,一般是2 

buf[19-20] buf[32-35],前者是 FAT16 格式中的磁區數,後者是 FAT32 格式中的磁區數。這個值在分區表裏也是有的。就是 7990000 

buf[22-23]buf[36-39]FAT 表佔用的磁區數,前者是 FAT16 的,後者是 FAT32 的。例如 7793 

buf[28-31] Hidden Sectors,隱藏磁區數,這個隱藏磁區指的是在這個分區前面有多少個磁區,這個值在分區表裏也有的。就是 63

好了,到這裏我們就可以讀取 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 系統的結構和資料,接下來就可以開始操作檔了。 

參考網址http://blog.sina.com.cn/s/blog_44153f8f0100eq0u.html 

相關網址:
※ DIY - PIC:SD 記憶卡規格 (七十)
※ DIY - PIC: FAT 表檔案配置表種類 (七十一)
※ DIY - PIC:SD 記憶卡 FAT 表 (七十二)
※ DIY - PIC:SD 記憶卡初始化 (七十三)
※ DIY - PIC:PIC18F4550 SD 記憶卡電路 (七十四)
※ DIY - PIC:PIC18F4550 SD 記憶卡穩壓電路 (七十五)
※ DIY - PIC:PIC18F4550 SD 記憶卡程式 (七十六)
※ DIY - PIC:PIC18F4550 MCHPMSD 實驗板 (七十七)
※ DIY - PIC:PIC18F4550 MCHPMSD 程式介紹 (七十八)
※ DIY - PIC:PIC18F4550 MCHPMSD 編程開始 (七十九)
※ DIY - PIC:PIC18F4550 MCHPMSD 初始化 (八十)
※ DIY - PIC:PIC18F4550 MCHPMSD 讀取 SD 記憶卡程式 (八十一)
※ DIY - PIC:PIC18F4550 MCHPMSD 寫入 SD 記憶卡程式 (八十二)
※ DIY - PIC:PIC18F4550 MCHPMSD SD 記憶卡程式 (八十三)

相關網址:
※ SD 記憶卡
※ SDHC 記憶卡
※ SDXC 記憶卡

2011 5 21 天氣報告
氣溫:24.5 @ 22:00 
相對濕度:百分之96%  
天氣:微雨



沒有留言:

張貼留言