SD卡為移動設備提供了安全的,大容量存儲解決方法。它本身可以通過兩種總線模式和MCU進行數據傳輸,一種是稱為SD BUS的4位串行數據模式,另一種就是大家熟知的4線SPI Bus模式。一些廉價,低端的MCU,通過硬件(或軟件)SPI就能和SD卡進行通信,實現大容量存儲的要求,這也是SD卡的魅力所在。
一、引腳定義
| SD BUS模式下,信號包括4根數據線DAT3~DAT0,一根命令傳輸線CMD和一根時鍾同步線;而在SPI模式下,只需要4跟信號線,分別為一根SD卡數據輸出,一根SD卡數據輸入,一根時鍾同步和一根片選線。右圖所示是SD卡的引腳定義,左邊為標准SD卡,右邊為Micro SD卡(也叫TF卡)。 | ![]() |
二、SPI模式
| 在SPI模式下,數據都是以字節(Byte)為單位進行傳輸的。此時SD卡作為從機設備,一般的操作是MCU發送帶有參數的命令,SD卡接收到命令和參數后進行操作,並且返回響應,MCU根據返回的響應進行下一步操作。 |
命令
SD卡的命令有6個字節(48位),由以下幾部分組成:第一字節的最高位b7為起始位,始終為0,接下來為傳輸位,始終為1,b5-b0為命令代碼;第2~5字節為命令的參數,共4個字節;最后一個字節的前7為CRC7校驗位,最后一位為停止位,始終為1。
每一條命令都是從片選信號(CS)的下降沿開始,SD卡接收到指令以后,都需要有一個指令響應時間(NCR),一般需要8個到64個時鍾周期。SPI的指令簡記為CMD<n>,<n>表示指令內容的十進制值,對於沒有參數的指令,參數為內容要用0來填充。下表列出了SPI模式下常用的指令
| 命令 | 參數 | 響應類型 | 簡寫 | 描述 |
| CMD0 | 0 | R1 | GO_IDLE_STATE | 軟件復位 |
| CMD8 | (*1) | R7 | SEND_IF_COND | 發送MCU的電壓范圍,檢測SD卡是否滿足MCU的電壓范圍 |
| ACMD41(*2) | (*3) | R1 | SD_SEND_OP_COND | 開始SD卡初始化和檢測SD卡是否完成初始化 |
| CMD9 | 0 | R1 | SEND_CSD | 讀取CSD寄存器的值 |
| CMD10 | 0 | R1 | SEND_CID | 讀取CID寄存器的值 |
| CMD12 | 0 | R1b | STOP_TRANSMISSION | 停止讀取操作 |
| CMD16 | 數據塊長度[31:0] | R1 | SET_BLOCKLEN | 設置數據塊長度(*4) |
| CMD17 | 地址[31:0] | R1 | READ_SINGLE_BLOCK | 讀取單個數據塊 |
| CMD18 | 地址[31:0] | R1 | READ_MULTIPLE_BLOCK | 讀取多個塊數據 |
| CMD24 | 地址[31:0] | R1 | WRITE_BLOCK | 寫單個塊數據 |
| CMD25 | 地址[31:0] | R1 | WRITE_MULTIPLE_BLOCK | 寫多個塊數據 |
| CMD55 | 0 | R1 | APP_CMD | 定義下一條命令為ACMD<n>命令 |
| CMD58 | 0 | R3 | READ_OCR | 讀取OCR寄存器 |
| *1 : [31:12]為0,[11:8]為VHS值,[7:0]Check Pattern,可以為任意值,用於檢測SD卡通信是否正確的。若該命令的返回值最后一字 節和Check pattern值相同,說明SPI通信成功。 *2 : 發送ACMD<n>之前需要先發送CMD55命令。 *3 : [31],[29:0]為0,[30]位為HCS,若MCU支持SDHC或者SDXC卡類型,HCS為0,支持則為1。 *4 : 對於SDSC卡類型,塊長度有CMD16來設定。而對於SDHC和SDXC卡類型,數據塊長度始終為512字節,此命令不會影響數據塊長度。 |
響應
三、初始化操作
SPI模式下的初始化操作有:上電->進入SPI模式(CMD0)->檢測當前MCU電壓是否符合SD卡的要求(CMD8)->開始初始化(ACMD41)->讀取卡類型(CMD58)
初始化過程中,SD卡時鍾信號周期需為100KHz~400KHz之間,不能大於400KHz。
上電
當電壓達到SD卡的最小工作電壓的后,MCU必須使CS,DI為高電平,輸出最少74個時鍾脈沖后,才能開始發送第一個命令。
初始化過程
SD卡上電后處於SD Bus模式,使CS保持為0,並且發送CMD0命令,SD卡就會進入到SPI模式。在SPI模式下,命令的CRC校驗功能默認是禁止的(CMD8命令
除外),但是發送第一個CMD0命令時,SD卡是處於SD Bus模式,該模式下CRC校驗功能是啟動的,因此第一個CMD0命令必須要有正確的CRC校驗。正確的CMD0命
令應為:0x40, 0x00, 0x00, 0x00, 0x00, 0x95。
CMD8用於檢測SD卡接口電壓是否滿足要求,該命令的參數包括當前MCU接口的電壓范圍VHS([11:8]),以及用於檢測通信的Check Pattern([7:0])。如果SD
卡能滿足當前MCU的接口電壓,它就會返回VHS和Check Pattern的值。需要注意的是,CMD8的CRC校驗值必須正確,假如CRC校驗不對,SD卡返回的R1值中的
CRC錯誤位就會置1。
ACMD41命令用於開始初始化SD卡及檢測其是否完成初始化。該命令的參數HCS([30])表示MCU是否支持SDHC和SDXC,若支持HCS置1,反之置0。如果
ACDM41命令返回R1的值為0x01,說明SD卡正在初始化,MCU需要重復發送ACMD41,直到返回值R1為0。
初始化完成后,通過發送CMD58指令讀取卡的類型(OCR寄存器的CCS位[30]), CCS為1表示當前卡的類型為SDXC或者SDHC,為0表示卡的類型為SDSC。
四、數據讀寫操作
MCU和SD卡間的數據交換都是以數據包為單位進行的。一個完整的數據包包括數據標識符(Token),數據塊內容,CRC校驗值。根據不同的命令,數據的起
始標識符會不一樣,如右圖所示。寫入數據后,SD卡會立即返回一個數據響應(區別於命令響應),MCU可根據該響應來判斷數據是否傳輸正確。
| 對於SDSC卡類型,數據塊的長度(字節為單位)可以通過CMD16來設定,最小1個字節,最大2048個字節。對於SDXC和SDHC卡,數據塊長度始終為512字節,CMD16不會影響數據塊的長度。 SPI模式下,CRC校驗功能是關閉的,因此CRC校驗值可以為任意值。 |
![]() |
讀取單個數據塊

MCU發出讀取單個數據塊命令CMD17,若SD卡返回響應無錯誤(返回0),則開始等待數據塊起始標識符0xFE, 然后開始讀取數據塊和CRC校驗。
讀取多個數據塊

讀取多個數據塊操作和讀取單個數據塊的相似,先發送命令CMD18,然后開始等待數據塊的起始標識符。需要停止讀取操作時,發送CMD12命令,返回響應為0表示
SD卡處於忙碌狀態,只有返回任何不為0的值后,MCU才能發送下一條命令。
寫入單個數據塊

當SD卡接收到寫入單個數據塊的命令CMD24后,首先發送數據塊起始標識(0xFE),然后發送發送數據塊內容和CRC校驗,如果未啟用CRC校驗功能,CRC可以為
任意值。SD卡在接收到數據包后回返回數據響應,若無錯誤,則SD卡就開始寫入數據,此時DO信號將被拉低,表示SD卡正處於忙碌狀態,不能接收命令。只有當
DO不為0時,MCU才能發送下一條命令。
寫入多個數據塊

和寫入單個數據塊不同的是,當SD卡接收到寫入多個數據塊命令CMD25后,發送數據包起始符為(0xFC), 只有當DO不為0時,才能繼續發送第二個數據包。如果要
結束寫入操作,則發送停止發送標識符(0xFD)。
讀取CID和CSD
讀取CID和CSD寄存器的操作和讀取單個數據塊的操作相似,僅僅是命令和數據塊長度不同。CID和CSD寄存器的定義請參照SD卡協議。
四、鏈接
2. [PDF]SD卡協議
3. SD/MMC時序圖





