2010-03-02 230 views
8

我看了一下堆棧溢出問題Initialization of a microSD card using an SPI interface並沒有看到與我的問題相匹配的任何答案(即,我還沒有試過的東西)。在SPI問題中初始化SD卡

我有一個類似的問題,我試圖通過微控制器的SPI接口(特別是HC908)訪問SD卡。我已經嘗試遵循物理層簡化規範v2.00中的流程圖,並且似乎在創見1上正確初始化,並且似乎在GB卡上正確初始化。但是我從我的照相機中使用的那些舊存儲卡中的其他三張隨機卡中遇到了問題。

我的代碼全部是HC908彙編器。我確定了SPI時鐘線的範圍,初始化期間它的運行頻率大約爲350   kHz(HC908在我的低MCU時鐘速度下提供的唯一倍速器,落在100 - 400   kHz窗口內)。

這裏有三張牌未完成我的初始化程序的結果(連續全部完成而無需改變任何代碼或定時參數):

Canon 16Meg card (labeled as SD): 
Set card select high 
Send 80 SPI clock cycles (done by writing 0xFF 10 times) 
Set card select low 
Send CMD0 [0x400000000095] and Loop up to 8 times waiting for high bit on response to go low 
R1 = 0x01 (indicates idle) 
Send CMD8 [0x48000001AA87] and Loop up to 8 times waiting for high bit on response to go low 
R1 = 0x05 (idle and illegal command) 
Because illegal command set local flag to indicate v1 or MMC card 
Send CMD58 [0x7A00000000FD] and Loop up to 8 times waiting for high bit on response to go low 
R1 = 0x05 (idle and illegal command) 
because illegal command branch to error routine 
Send CMD13 [0x4D000000000D] (show status buffer) and Loop up to 8 times waiting for high bit on response to go low 
R1= 0x05 (idle and illegal command) 

是非法命令標誌卡?我應該在CMD8之後做些什麼來清除那個標誌?

SanDisk UltraII 256Meg 
Set card select high 
Send 80 SPI clock cycles (done by writing 0xFF 10 times) 
Set card select low 
Send CMD0 [0x400000000095] and Loop up to 8 times waiting for high bit on response to go low 
R1 = 0x01 (idle) 
Send CMD8 [0x48000001AA87] and Loop up to 8 times waiting for high bit on response to go low 
R1 = 0x05 (idle and illegal command) 
Because illegal command set local flag to indicate v1 or MMC card 
Send CMD58 [0x7A00000000FD] and Loop up to 8 times waiting for high bit on response to go low 
R1 = 0x01 (idle) 
Send 0xFF 4 times to read OCR 
OCR = 0xFFFFFFFF 
Send CMD55 [0x770000000065] (1st part of ACMD41) and Loop up to 8 times waiting for high bit on response to go low 
R1 = 0x01 (idle) 
Send CMD41 [0x6900000000E5] (2nd part of ACMD41) and Loop up to 8 times waiting for high bit on response to go low 
R1 = 0x05 (idle and illegal command) 
Because illegal command, assume card is MMC 
Send CMD1 [0x4100000000F9] (for MMC) and Loop up to 8 times waiting for high bit on response to go low 
R1 = 0x05 (idle and illegal command) 
Repeat the CMD1 50 times (my arbitrary number to wait until idle clears) 
Every R1 response is 0x05 (idle and illegal command) 

爲什麼OCR都是F?看起來不合適。另外,爲什麼ACMD41和CMD1會響應非法命令?即使命令響應非法,卡CMD55等待有效的ACMD,CMD1是否失敗?

SanDisk ExtremeIII 2G: 
Set card select high 
Send 80 SPI clock cycles (done by writing 0xFF 10 times) 
Set card select low 
Send CMD0 [0x400000000095] and Loop up to 8 times waiting for high bit on response to go low 
R1 = 0x01 (idle) 
Send CMD8 [0x40000001AA87] and Loop up to 8 times waiting for high bit on response to go low 
R1 = 0x7F (??? My loop shows the responses for each iteration and I got 0xFF 0xFF 0xC1 0x7F... is the card getting out of sync?) 
Send CMD58 [0x7A00000000FD] and Loop up to 8 times waiting for high bit on response to go low 
R1 = 0x01 (idle and back in sync) 
Send 0xFF 4 times to read OCR 
OCR = 0x00FF80 
Send CMD55 [0x770000000065] (1st part of ACMD41) and Loop up to 8 times waiting for high bit on response to go low 
R1 = 0x5F (??? loop responses are 0xFF 0xFF 0xF0 0x5F... again out of sync?) 
Send CMD41 [0x6900000000E5] (2nd part of ACMD41) and Loop up to 8 times waiting for high bit on response to go low 
R1 = 0x05 (idle and illegal command, but back in sync???) 
Because illegal command, assume card is MMC 
Send CMD1 [0x4100000000F9] (for MMC) and Loop up to 8 times waiting for high bit on response to go low 
R1 = 0x7F (??? loop responses are 0xFF 0xFF 0xC1 0x7F... again out of sync?) 
Repeat CMD1 and Loop up to 8 times waiting for high bit on response to go low 
R1 = 0x01 (idle) 
Repeat CMD1 and Loop up to 8 times waiting for high bit on response to go low 
R1 = 0x7F (??? loop responses are 0xFF 0xFF 0xC1 0x7F... again out of sync?) 
Repeat CMD1 and Loop up to 8 times waiting for high bit on response to go low 
R1 = 0x00 (out of idle) 
Send CMD9 [0x4900000000AF] (get CSD) and Loop up to 8 times waiting for high bit on response to go low 
R1 = 0x3F (??? loop responses are 0xFF 0xFF 0xC1 0x3F... again out of sync?) 
Code craps out because Illegal command bit is high. 

那張卡在地上有什麼問題?

有時它是同步的,其他時間不是。 (上面的模式可重複。)我已經確定了這一點,並且我沒有看到MOSI/MISO傳輸之間有任何流氓時鐘週期。

+0

忘了提。在這些嘗試初始化3張卡失敗後,我將它們放入筆記本電腦的SD卡讀卡器中,我仍然可以將它們作爲標準SD卡(讀取和寫入)不帶任何問題進行訪問。 – Sembazuru 2010-03-02 19:27:46

+0

在「SanDisk ExtremeIII」的命令列表中發現了一個錯誤:發送CMD8 [0x40000001AA87] - 它應該是0x48,而不是0x40。 – 2014-04-19 15:06:55

回答

20

好的......我發現我的問題。對於遇到此問題的其他人,請記住在收到回覆後發送額外的0xFF。這爲卡提供了額外的八個時鐘週期,爲下一個命令做好準備。有些卡片似乎並不需要它(例如我使用的Transcends),但其他卡片則需要它。

我實際上在我的'寫入命令'例程的開始處發送了一個簡單的循環,它發送0xFF,直到它得到0xFF作爲響應,因此我不必去所有讀取響應的不同地方當然我會額外發送0xFF。因爲就SD卡而言(通常)在SPI模式下,如果沒有時鐘週期進入,時間依然存在。

有一件事我注意到並且還沒有找到答案(但是到目前爲止它沒有傷害任何東西),在我讀了CSR的16個字節之後,似乎還有另外2個字節的非零字節, 0xFF出來...這是一個CRC16?因爲CSR有內置的CRC ...

+3

感謝您分享。 – 2010-03-04 23:22:37

+1

謝謝,你救我幾個小時! – 2013-02-19 16:30:46

+1

同上,這是非常有用的,特別是發送0xFF,直到返回0xFF。我有一個Class 2 Transcend卡可以正常工作,但是當我切換到Class 4 Transcend卡時,我可以初始化但不能讀取它。現在我能。謝謝。 – David 2013-04-05 22:12:02

3

如果您啓用了CRC(與CMD59),那麼是的,數據塊將添加CRC16。

欲瞭解更多信息,請參閱「物理層簡化規格版本2.00」,章節「總線傳輸保護」和「數據讀取」。

+0

對不起,這麼晚的迴應......(忙於其他項目......)我想我沒有在概念上將CSR視爲「數據塊」。我只是把它想成一個狀態寄存器。 – Sembazuru 2011-03-17 16:31:18

1

這一點很重要:我已經受夠了SD/MMC卡非常大的麻煩,直到我發現我不得不選擇的工作電壓。 你這樣做,通過發送ACMD41的位設置爲電壓你提供的卡。 注:只能選擇一個位。 如果您沒有選擇電壓或選擇多個電壓,它將保持循環處於空閒狀態,並且永遠不會退出某些SD卡。

即:如果您的ACMD41一直髮送響應0x01,您沒有選擇電壓。 電壓在ACMD41的32位參數位23 ... 8中。 對於3.2V ... 3.3V,這是第20位,因此,例如你可以:

acmdSDAppOpCond[2] = (1 << (20 & 7));   /* 3.2V .. 3.3V */ 

這是十六進制值0x10的,所以你的ACMD41是這樣的...... ×69 0x40的0x10的0×00 0×00 0XCD ...或者如果它是一個SDSC卡... ×69 0×00 0×10 0×00 0×00 0x5F的

這裏是最常見的值的短(或不完全)表:

Bit23: 3.5V..3.6V 
Bit22: 3.4V..3.5V 
Bit21: 3.3V..3.4V 
Bit20: 3.2V..3.3V 
Bit19: 3.1V..3.2V 
Bit18: 3.0V..3.1V 
Bit17: 2.9V..3.0V 
Bit16: 2.8V..2.9V 
Bit15: 2.7V..2.8V 

你做不是必須在任何時間點將CS切換爲高電平。你可以一直保持低點。

+1

Sandisk SDCard規範說明如下: 「在SPI模式下,與SD模式相反,ACMD41(或CMD1以及2.1mm-SD卡)沒有操作數,並且不返回OCR寄存器的內容。 ,主機可以使用CMD58(僅在SPI模式下)讀取OCR寄存器,此外,主機有責任避免訪問不支持其電壓範圍的卡。「官方規範並沒有反對這一點,並明確表示ACMD 41應該有一個標準容量卡的0x0參數。 – thenickdude 2015-10-21 23:15:31

+1

但是,在SD模式下,將需要該參數: 「[...]主機發送所需的VDD電壓窗口作爲[SD_SEND_OP_COND(ACMD41)]命令的操作數無法執行數據傳輸的SD卡指定的範圍必須放棄進一步的總線操作並進入非活動狀態 通過省略命令中的電壓範圍,主機可以查詢每張卡並確定是否在將超出範圍的卡發送到無效狀態「。 – thenickdude 2015-10-21 23:20:44