2011年5月21日 星期六

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

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

將會使用 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. 讀取CID(CMD10)
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. 讀取CSD(CMD9),SD卡信息
返回的 CSD 有兩個版本。

名稱 域 數據寬度 單元類型 CSD劃分
CSD結構 CSD_STRUCTURE 2 R [127:126]
保留 - 6 R [125:120]
資料讀取時間1 TAAC 8 R [119:112]
資料在CLK週期內讀取時間2(NSAC*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]
▲CSD(Card-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 卡的磁區0到buffer如果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[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%  
天氣:微雨



沒有留言:

張貼留言