最近需要做一個數(shù)據(jù)存儲,發(fā)現(xiàn)SD卡這一塊還不太好弄
現(xiàn)在的單片機(jī)有相當(dāng)一部分還不支持SDIO,比如MSP430(據(jù)我所知,如果有支持的型號了還請及時告訴我~),所以只好用SPI通信來進(jìn)行SD卡的操作,雖然后續(xù)涉及到更為復(fù)雜的FAT等等,但是首先需要解決的仍然是建立通信的問題。
采用的單片機(jī)型號為MSP430F5438A,用了一個開發(fā)板。
SPI通信基本例程
例程及解釋如下:
鑒于CSDN的Markdown代碼高亮做的實在是……唉,這里貼一個容易看的吧:
SPI通信代碼
SD卡通信方式
以上是給出的例程,SD卡有自己的一套通信方法:
這里引述了:
http://elm-chan.org/docs/mmc/mmc_e.html
當(dāng)中的內(nèi)容并予以節(jié)選翻譯,以便日后查找方面。
MMC卡和SD卡先后推出,接口可以說基本差不多,供電是2.7~3.6V,不要供5V點,否則按照原文說法是“馬上壞”(@_@)
SD卡和單片機(jī)的電氣連接方式如下圖其中有一個上拉電阻有點令人費解
SPI通信模式共有0~3四種,他們的區(qū)別是時鐘相位和極性。適用于MMC和SD的模式是mode 0(CPHA=0,CPOL=0),但是mode 3多數(shù)情況下也管用
SD卡初始化
下面的流程是整個初始化的步驟:
為了避免翻譯出現(xiàn)差錯,這里也附上英文原文。
上電或卡剛插入時
當(dāng)供電電壓達(dá)到2.7V以上時,至少等待1ms,將SPI時鐘信號的頻率設(shè)置在100kHz~400kHz之間,并設(shè)置DI和CS(片選信號)為高,并向SCLK輸入74個以上時鐘脈沖,內(nèi)存卡將會進(jìn)入到其默認(rèn)操作模式并做好接收指令準(zhǔn)備
軟件復(fù)位
保持CS(片選信號)為低電平的情況下,發(fā)送一個CMD0指令(就是reset指令,完整指令集的解釋附于文后)。SD卡將會在CMD0指令接收之后采樣CS信號,如果CS信號為低電平,SD卡將會進(jìn)入SPI模式,并回復(fù)0x01。由于CMD0必須作為:“原生指令”(Native Command)發(fā)送,所以CRC部分必須有一個有效(valid)的值(譯者注:原生指令中,CRC是固定格式中的一個部分,這里的有效指的是占位還是必須要校驗計算不清楚,還要再次確認(rèn),這里,CRC作為一個校驗位應(yīng)該和串口的奇偶校驗差不多,是只需要選擇控制位就可以的,并不需要單獨編程計算)。一旦SD卡進(jìn)入SPI模式之后,這個CRC部分將不再被使用,也不會再被檢查。所以,命令中的CRC可以相對固定,但是這個固定值要能夠在發(fā)送CMD0 和 CMD8 這兩個命令(命令參數(shù)argument為0的情況下)時保證正確(CMD0的正確CRC,在argument為0的時候是0x95,CMD8待查)。
另外CRC這個特征也可以使用CMD59進(jìn)行切換,(切換什么和怎樣切換沒有詳細(xì)交代)。
補(bǔ)充說明:CMD8命令的稍微詳細(xì)一些的介紹可以參看:
百度文庫
Power ON or card insersion
After supply voltage reached 2.2 volts, wait for one millisecond at least. Set SPI clock rate between 100 kHz and 400 kHz. Set DI and CS high and apply 74 or more clock pulses to SCLK. The card will enter its native operating mode and go ready to accept native command.
Software reset
Send a CMD0 with CS low to reset the card. The card samples CS signal on a CMD0 is received successfully. If the CS signal is low, the card enters SPI mode and responds R1 with In Idle State bit (0x01)。 Since the CMD0 must be sent as a native command, the CRC field must have a valid value. When once the card enters SPI mode, the CRC feature is disabled and the CRC is not checked by the card, so that command transmission routine can be written with the hardcorded CRC value that valid for only CMD0 and CMD8 with the argument of zero. The CRC feature can also be switched with CMD59.
初始化
SD卡在空閑狀態(tài)下,只接受CMD0,CMD1,ACMD41,CMD58以及CMD59這幾個指令,而拒絕其它任何指令。這是,讀取OCR寄存器并檢查卡片的工作電壓范圍(似乎通過CMD58進(jìn)行查詢),如果供電超出范圍要彈出SD卡。
卡片在接收到CMD1命令時啟動初始化流程,主控芯片需要持續(xù)發(fā)送CMD1并檢測回復(fù)以確定初始化過程完成。R1回復(fù)從0x01變?yōu)?x00(Idle State bit 清零)時,意味著初始化成功。初始化過程可能需要數(shù)百ms(卡片存儲空間越大時間越長),所以需要考慮一個判定超時的閾值。
Idle State bit 清零之后,一般的讀寫命令就可以執(zhí)行了。此外因為在對SDC進(jìn)行操作時,ACMD41被推薦代替CMD1,所以首先嘗試發(fā)送ACMD41,被拒絕之后再試CMD1,這樣的一個流程在理想狀況下應(yīng)該能夠適應(yīng)所有的兩種卡。
Initialization
In idle state, the card accepts only CMD0, CMD1, ACMD41,CMD58 and CMD59. Any other commands will be rejected. In this time, read OCR register and check working voltage range of the card. In case of the system sypply voltage is out of working voltage range, the card must be rejected. Note that all cards work at supply voltage range of 2.7 to 3.6 volts at least, so that the host contoller needs not check the OCR if supply voltage is in this range. The card initiates the initialization process when a CMD1 is received. To detect end of the initialization process, the host controller must send CMD1 and check the response until end of the initialization. When the card is initialized successfuly, In Idle State bit in the R1 response is cleared (R1 resp changes 0x01 to 0x00)。 The initialization process can take hundreds of milliseconds (large cards tend to longer), so that this is a consideration to determin the time out value. After the In Idle State bit cleared, generic read/write commands will able to be accepted.
Because ACMD41 instead of CMD1 is recommended for SDC, trying ACMD41 first and retry with CMD1 if rejected, is ideal to support both type of the cards.
SCLK頻率應(yīng)該設(shè)置的盡可能快,這樣可以使得讀寫的表現(xiàn)更好(應(yīng)該是速度更快吧)。CSD寄存器中的TRAN_SPEED區(qū)域標(biāo)明了卡片的最大時鐘頻率。大部分情況下,MMC為20MHz,SDC則為25MHz。注意時鐘頻率可以是在這兩個值之間的值,沒有中間出現(xiàn)開集的其它限制。
在2GB卡上,初始的讀寫 block length可能是1024,所以block size應(yīng)該被重新初始化到512(使用CMD16命令)以配合FAT文件系統(tǒng)的工作。
The SCLK rate should be changed to fast as possible to maximize the read/write performance. The TRAN_SPEED field in the CSD register indicates the maximum clock rate of the card. The maximum clock rate is 20MHz for MMC, 25MHz for SDC in most case. Note that the clock rate will able to be fixed to 20/25MHz in SPI mode because there is no open-drain condition that restricts the clock rate.
The initial read/write block length can be set 1024 on 2GB cards, so that the block size should be re-initialized to 512 with CMD16 to work with FAT file system.
初始化 high-capacity cards (不知道高級在什么地方)
在發(fā)送給卡片一個CMD0指令使其進(jìn)入空閑模式后,在初始化之前發(fā)送一個CMD8(語句為0x000001AA,需要有正確的校驗位CRC)。如果CMD8被拒絕(表現(xiàn)是會回復(fù)一個命令錯誤提示0x05),那么這個卡片是一個SDC一代卡或者M(jìn)MC三代卡。如果命令被接受,會收到一個R7回復(fù)(R1(0x10)+32位返回值)。這個32位返回值的低12位意味著這個卡是一個SDC二代卡。(接著又絮叨了一遍電壓范圍的事兒,似乎沒什么意義)。在確認(rèn)之后,啟動初始化:利用帶HCS flag(bit30)的ACMD41命令。后面似乎講的是如果這個bit 30 被置位,則這個卡就是眾所周知的SDHC/SDXC卡(但是it is set當(dāng)中的這個it指的是什么還是有些拿不準(zhǔn))。以下描述的數(shù)據(jù)讀取/寫入操作是按照block尋址的而非按照byte尋址。數(shù)據(jù)block大小固定在512bytes。
Initializing high-capacity cards
After the card enters idle state with a CMD0, send a CMD8 with argument of 0x000001AA and correct CRC prior to initialization process. If the CMD8 is rejected with illigal command error (0x05), the card is SDC version 1 or MMC version 3. If accepted, R7 response (R1(0x01) + 32-bit return value) will be returned. The lower 12 bits in the return value 0x1AA means that the card is SDC version 2 and it can work at voltage range of 2.7 to 3.6 volts. If not the case, the card should be rejected. And then initiate initialization with ACMD41 with HCS flag (bit 30)。 After the initialization completed, read OCR register with CMD58 and check CCS flag (bit 30)。 When it is set, the card is a high-capacity card known as SDHC/SDXC. The data read/write operations described below are commanded in block addressing insted of byte addressing. The size of data block at block addressing mode is fixed to 512 bytes
評論
查看更多