一、SD卡簡介
SD卡的英文全稱是Secure Digital Card,即安全數字卡(又叫安全數位卡),是在MMC卡(Multimedia Card,多媒體卡)的基礎上發展而來,主要增加了兩個特色:更高的安全性和更快的讀寫速度。
SD卡和MMC卡的長度和寬度都是32mm x 24mm,不同的是,SD卡的厚度為2.1mm,而MMC卡的厚度為1.4mm,SD卡比MMC卡略厚,以容納更大容量的存貯單元,同時SD卡比MMC卡觸點引腳要多,且在側面多了一個寫保護開關。
SD卡與MMC卡保持着向上相容,也就是說,MMC卡可以被新的SD裝置存取,相容性則取決于應用軟體,但SD卡卻不可以被MMC裝置存取。SD卡和MMC卡可通過卡片上面的标注進行區分,如下圖左側圖檔上面标注為“MultiMediaCard”字母樣式的為MMC卡,右側圖檔上面标注為“SD”字母樣式的為SD卡。

SD卡從存儲容量上分為3個級别,分别為:SD卡、SDHC卡(Secure Digital High Capacity,高容量安全數字卡)和SDXC卡(SD eXtended Capacity,容量擴大化的安全存儲卡)。
SD卡在MMC卡的基礎上發展而來,使用FAT12/FAT16檔案系統,SD卡采用SD1.0協定規範,該協定規定了SD卡的最大存儲容量為2GB;SDHC卡是大容量存儲SD卡,使用FAT32檔案系統,SDHC卡采用SD2.0協定規範,該協定規定了SDHC卡的存儲容量範圍為2GB至32GB;SDXC卡是新提出的标準,不同于SD卡和SDHC卡使用的FAT檔案系統,SDXC卡使用exFAT檔案系統,即擴充FAT檔案系統。SDXC卡采用SD3.0協定規範,該協定規定了SDXC卡的存儲容量範圍為32GB至2TB(2048GB),一般用于中高端單反相機和高清錄影機。
不同協定規範的SD卡有着不同速度等級的表示方法:
SD1.0協定規範中(現在用的較少),使用“X”表示不同的速度等級;
SD2.0協定規範中,使用SpeedClass表示不同的速度等級:普通卡(Class2、Class4、Class6)和高速卡(Class10)
SD3.0協定規範使用UHS(Ultra High Speed)表示不同的速度等級:UHS速度等級1和3
SD卡共有9個引腳線,可工作在SDIO模式或者SPI模式。
在SDIO模式下,共用到CLK、CMD、DAT[3:0]六根信号線;
在SPI模式下,共用到CS(SDIO_DAT[3])、CLK(SDIO_CLK)、MISO(SDIO_DAT[0])、MOSI (SDIO_CMD)四根信号線。
市面上除标準SD卡外,還有MicroSD卡(原名TF卡),是一種極細小的快閃存儲器卡,是由SanDisk(閃迪)公司發明,主要用于移動手機。MicroSD卡插入擴充卡(Adapter)可以轉換成SD卡,其操作時序和SD卡是一樣的。
标準SD卡2.0版本中,工作時鐘頻率可以達到50Mhz,在SDIO模式下采用4位資料位寬,理論上可以達到200Mbps(50Mx4bit)的傳輸速率;在SPI模式下采用1位資料位寬,理論上可以達到50Mbps的傳輸速率。是以SD卡在SDIO模式下的傳輸速率更快,同時其操作時序也更複雜。
對于使用SD卡讀取音樂檔案和圖檔來說,SPI模式下的傳輸速度已經能夠滿足我們的需求,是以我們采用SD卡的SPI模式來對SD卡進行讀寫測試。
SD卡在正常讀寫操作之前,必須先對SD卡進行初始化,SD卡的初始化過程就是向SD中寫入指令,使其工作在預期的工作模式。在對SD卡進行讀寫操作時同樣需要先發送寫指令和讀指令。
SD卡的指令格式由6個位元組組成,發送資料時高位在前,SD卡的寫入指令格式如下圖所示:
Byte1:指令字的第一個位元組為指令号(如CMD0、CMD1等),格式為“0 1 x x x x x x”。指令号的最高位始終為0,是指令号的起始位;次高位始終為1,是指令号的發送位;低6位為具體的指令号(如CMD55,8’d55 = 8’b0011_0111,指令号為 0 1 1 1 0 1 1 1 = 0x77)。
Byte2~Byte5:指令參數,有些指令參數是保留位,沒有定義參數的内容,保留位應設定為0。
Byte6:前7位為CRC(循環備援校驗)校驗位,最後一位為停止位0。SD卡在SPI模式下預設不開啟CRC校驗,在SDIO模式下開啟CRC校驗。也就是說在SPI模式下,CRC校驗位必須要發,但是SD卡會在讀到CRC校驗位時自動忽略它,是以校驗位全部設定為1即可。需要注意的是,SD卡上電預設是SDIO模式,在接收SD卡傳回CMD0的響應指令時,拉低片選CS,進入SPI模式。是以在發送CMD0指令的時候,SD卡處于SDIO模式,需要開啟CRC校驗。另外CMD8的CRC校驗是始終啟用的,也需要啟用CRC校驗。除了這兩個指令,其它指令的CRC可以不用做校驗。
SD卡的指令分為标準指令(如CMD0)和應用相關指令(如ACMD41)。ACMD指令是特殊指令,發送方法同标準指令一樣,但是在發送應用相關指令之前,必須先發送CMD55指令,告訴SD卡接下來的指令是應用相關指令,而非标準指令。發送完指令後,SD卡會傳回響應指令的資訊,不同的CMD指令會有不同類型的傳回值,常用的傳回值有R1類型、R3類型和R7類型(R7類型是CMD8指令專用)。SD卡的常用指令說明如下表(表 39.1.2)所示。
SD卡傳回類型R1資料格式如下圖所示:
由上圖可知,SD卡傳回類型R1格式共傳回1個位元組,最高位固定為0,其它位分别表示對應狀态的标志,高電平有效。
SD卡傳回類型R3資料格式如下圖所示:
由上圖可知,SD卡傳回類型R3格式共傳回5個位元組,首先傳回的第一個位元組為前面介紹的R1的内容,其餘位元組為OCR(Operation Conditions Register,操作條件寄存器)寄存器的内容。
SD卡傳回類型R7資料格式如下圖所示:
由上圖可知,SD卡傳回類型R7格式共傳回5個位元組,首先傳回的第一個位元組為前面介紹的R1的内容,其餘位元組包含SD卡操作電壓資訊和校驗位元組等内容。其中電壓範圍是一個比較重要的參數,其具體内容如下所示:
Bit[11:8]:操作電壓回報
0:未定義
1:2.7V~3.6V
2:低電壓
4:保留位
8:保留位
其它:未定義
SD卡在正常讀寫操作之前,必須先對SD卡進行初始化,使其工作在預期的工作模式。SD卡1.0版本協定和2.0版本協定在初始化過程中有差別,隻有SD2.0版本協定的SD卡才支援CMD8指令,是以響應此指令的SD卡可以判斷為SD2.0版本協定的卡,否則為SD1.0版本協定的SD卡或者MMC卡;對于CMD8無響應的情況,可以發送CMD55 + ACMD41指令,如果傳回0,則表示SD1.0協定版本卡初始化成功,如果傳回錯誤,則确定為MMC卡;在确定為MMC卡後,繼續向卡發送CMD1指令,如果傳回0,則MMC卡初始化成功,否則判斷為錯誤卡。
由于市面上大多采用SD2.0版本協定的SD卡,接下來我們僅介紹SD2.0版本協定的初始化流程,以下提到的SD卡均代表基于SD2.0版本協定的SDHC卡,其詳細初始化步驟如下:
SD卡完成上電後,主機FPGA先對從機SD卡發送至少74個以上的同步時鐘,在上電同步期間,片選CS引腳和MOSI引腳必須為高電平(MOSI引腳除發送指令或資料外,其餘時刻都為高電平);
拉低片選CS引腳,發送指令CMD0(0x40)複位SD卡,指令發送完成後等待SD卡傳回響應資料;
SD卡傳回響應資料後,先等待8個時鐘周期再拉高片選CS信号,此時判斷傳回的響應資料。如果傳回的資料為複位完成信号0x01,在接收傳回資訊期間片選CS為低電平,此時SD卡進入SPI模式,并開始進行下一步,如果傳回的值為其它值,則重新執行第2步;
拉低片選CS引腳,發送指令CMD8(0x48)查詢SD卡的版本号,隻有SD2.0版本的卡才支援此指令,指令發送完成後等待SD卡傳回響應資料;
SD卡傳回響應資料後,先等待8個時鐘周期再拉高片選CS信号,此時判斷傳回的響應資料。如果傳回的電壓範圍為4’b0001即2.7V~3.6V,說明此SD卡為2.0版本,進行下一步,否則重新執行第4步;
拉低片選CS引腳,發送指令CMD55(0x77)告訴SD卡下一次發送的指令是應用相關指令,指令發送完成後等待SD卡傳回響應資料;
SD卡傳回響應資料後,先等待8個時鐘周期再拉高片選CS信号,此時判斷傳回的響應資料。如果傳回的資料為空閑信号0x01,開始進行下一步,否則重新執行第6步。
拉低片選CS引腳,發送指令ACMD41(0x69)查詢SD卡是否初始化完成,指令發送完成後等待SD卡傳回響應資料;
SD卡傳回響應資料後,先等待8個時鐘周期再拉高片選CS信号,此時判斷傳回的響應資料。如果傳回的資料為0x00,此時初始化完成,否則重新執行第6步。
SD卡上電及複位指令時序如下圖所示:
至此,SD卡完成了複位以及初始化操作,進入到SPI模式的讀寫操作。需要注意的是:SD卡在初始化的時候,SPI_CLK的時鐘頻率不能超過400KHz,在初始化完成之後,再将SPI_CLK的時鐘頻率切換至SD卡的最大時鐘頻率。
盡管目前市面上的很多SD卡支援以較快的時鐘頻率進行初始化,為了能夠相容更多的SD卡,在SD卡初始化的時候時鐘頻率不能超過400KHz。SD卡讀寫一次的資料量必須為512位元組的整數倍,即對SD卡讀寫操作的最少資料量為512個位元組。我們可以通過指令CMD16來配置單次讀寫操作的資料長度,以使每次讀寫的資料量為(n*512)個位元組(n≥1),本次SD卡的讀寫操作使用SD卡預設配置,即單次讀寫操作的資料量為512個位元組。
SD卡初始化完成後,即可對SD卡進行讀寫測試,SD卡的讀寫測試是先向SD卡中寫入資料,再從SD卡中讀出資料,并驗證資料的正确性。SD卡的寫操作時序圖如下圖所示:
SD卡的寫操作流程如下:
拉低片選CS引腳,發送指令CMD24(0x58)讀取單個資料塊,指令發送完成後等待SD卡傳回響應資料;
SD卡傳回正确響應資料0x00後,等待至少8個時鐘周期,開始發送資料頭0xfe;
發送完資料頭0xfe後,接下來開始發送512個位元組的資料;
資料發送完成後,發送2個位元組的CRC校驗資料。由于SPI模式下不對資料進行CRC校驗,直接發送兩個位元組的0xff即可;
校驗資料發送完成後,等待SD卡響應;
SD卡傳回響應資料後會進入寫忙狀态(MISO引腳為低電平),即此時不允許其它操作。當檢測到MISO引腳為高電平時,SD卡此時退出寫忙狀态;
拉高CS引腳,等待8個時鐘周期後允許進行其它操作。
SD卡的讀操作時序圖如下圖所示:
SD卡的讀操作流程如下:
拉低片選CS引腳,發送指令CMD17(0x51)讀取單個資料塊,指令發送完成後等待SD卡傳回響應資料;
SD卡傳回正确響應資料0x00後,準備開始解析SD卡傳回的資料頭0xfe;
解析到資料頭0xfe後,接下來接收SD卡傳回的512個位元組的資料;
資料解析完成後,接下來接收兩個位元組的CRC校驗值。由于SPI模式下不對資料進行CRC校驗,可直接忽略這兩個位元組;
校驗資料接收完成後,等待8個時鐘周期;
拉高片選CS引腳,等待8個時鐘周期後允許進行其它操作。
對于SD卡的SPI模式而言,采用的SPI的通信模式為模式3,即CPOL = 1,CPHA = 1,在SD
卡2.0版本協定中,SPI_CLK時鐘頻率可達50Mhz。
以上是SD卡簡介部分的全部内容,在這裡還需要補充下FAT檔案系統的知識。如果對SD卡的讀寫測試像EEPROM一樣僅僅是寫資料,讀資料并驗證資料的正确性的話,是不需要FAT檔案系統的。而SD卡經常被用來在Windows作業系統上存取資料,必須使用Windows作業系統支援的FAT檔案系統才能在電腦上正常使用。
FAT(File Allocation Table,檔案配置設定表)是Windows作業系統所使用的一種檔案系統,它的發展過程經曆了FAT12、FAT16、FAT32三個階段。FAT檔案系統用“簇”作為資料單元,一個“簇”由一組連續的扇區組成,而一個扇區由512個位元組組成。簇所包含的扇區數必須是2的整數次幂,其扇區個數最大為64,即32KB(512Byte * 64 = 32KB)。所有的簇從2開始進行編号,每個簇都有一個自己的位址編号,使用者檔案和目錄都存儲在簇中。
FAT檔案系統的基本結構依次為:分區引導記錄、檔案配置設定表(FAT表1和FAT表2)、根目錄和資料區。
分區引導記錄:分區引導記錄區通常占用分區的第一個扇區,共512個位元組。包含四部分内容:BIOS參數記錄塊BPB(BIOS Parameter Block)、磁盤标志記錄表、分區引導記錄代碼區和結束标志0x55AA。
檔案配置設定表(FAT表1和FAT表2):檔案在磁盤上以簇為機關存儲,但是同一個檔案的資料并不一定完整地存放在磁盤的一個連續的區域内,往往會分成若幹簇,FAT表就是記錄檔案存儲中簇與簇之間連接配接的資訊,這就是檔案的鍊式存儲。對于FAT16檔案系統來說,每個簇用16Bit來表示檔案配置設定表,而對于FAT32檔案系統,使用32Bit來表示檔案配置設定表,這是兩者之間的最重要差別。
根目錄:根目錄是檔案或者目錄的首簇号。在FAT32檔案系統中,不再對根目錄的位置做硬性規定,可以存儲在分區内可尋址的任意簇内。不過通常根目錄是最早建立的(格式化就生成了)目錄表,是以我們看到的情況基本上都是根目錄首簇緊鄰FAT2,占簇區順序上的第1個簇(即2号簇)。
資料區:資料區緊跟在根目錄後面,是檔案等資料存放的地方,占用大部分的磁盤空間。