日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【STM32】STM32 SDIO SD卡读写测试(三)-- SD_Init之Init Card阶段

發布時間:2024/3/26 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【STM32】STM32 SDIO SD卡读写测试(三)-- SD_Init之Init Card阶段 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

相關文章

《【SDIO】SDIO、SD卡、FatFs文件系統相關文章索引》

1. 前言

本篇文章主要是介紹stm324x9i_eval_sdio_sd.c里面SD_Init()函數完整的過程。它主要是實現了SDIO的初始化SD卡的Power UPSD卡的初始化獲取SD卡的相關信息等,下面會詳細介紹SD卡的初始化獲取SD卡的相關信息的分析。

2. SD_InitializeCards()

SD_InitializeCards()主要的功能是初始化SD卡獲取CID和RCA的信息,并進入Standby狀態。主要涉及到的函數如下:

  • CMD2: SD_CMD_ALL_SEND_CID
  • CMD3: SD_CMD_SET_REL_ADDR
  • CMD9: SD_CMD_SEND_CSD

2.1 CMD2: SD_CMD_ALL_SEND_CID

CMD2: SD_CMD_ALL_SEND_CID是通知所有卡通過 CMD 線返回 CID值,CID值是卡的唯一標識。在卡發送CID后,它進入識別狀態。

#define SD_CMD_ALL_SEND_CID ((uint8_t)2)/*!< Send CMD2 ALL_SEND_CID */ SDIO_CmdInitStructure.SDIO_Argument = 0x0; SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_ALL_SEND_CID; SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Long; SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; SDIO_SendCommand(&SDIO_CmdInitStructure);

發送出去的波形如下:

發送CMD2命令后,調用CmdResp2Error()獲取SDIO 狀態寄存器 (SDIO_STA) Value,通過返回的狀態Value來判斷命令響應是否已經正確被接收。如果響應被正確被接受,通過訪問SDIO 響應 1…4 寄存器 (SDIO_RESPx)來獲取CID的值。

errorstatus = CmdResp2Error();if (SD_OK != errorstatus) {return(errorstatus); }CID_Tab[0] = SDIO_GetResponse(SDIO_RESP1); CID_Tab[1] = SDIO_GetResponse(SDIO_RESP2); CID_Tab[2] = SDIO_GetResponse(SDIO_RESP3); CID_Tab[3] = SDIO_GetResponse(SDIO_RESP4);

從SD2.0協議里面可以了解到CMD2的response格式是R2,R2主要獲取CID或者CSD值。


為什么獲取CID值需要讀取SDIO Response 1…4寄存器?
因為在STM32的SDIO相關寄存器可以了解到關于127 Bit 長響應會用到SDIO_RESP1..4這4個寄存器拼接成的(如下圖STM32 SDIO Datasheet所示),所以這里需要訪問這4個寄存器。如果命令響應的參數的長度是32 Bit 短響應,那么就只需要讀取SDIO_RESP1寄存器的Value。

R1、R2、R3、R6、R7SDIO_RESP1…4 這2個概率容易弄混:

  • R1、R2、R3、R6、R7:這個是SD2.0《Physical Specification Version 2.00》 協議規定CMD響應命令格式。
  • SDIO_RESP1..4:這個是STM32寄存器存放命令響應參數的值。


邏輯分析儀抓取波形如下:

從上面的波形可以獲取到CID值為:0x03534453433332478049D204AD012ADF,關于CID的表格如下:

NameFieldWidthCID-sliceValue
Manufacturer IDMID8[127:120]0x03
OEM/Application IDOID16[119:104]0x5344
Product namePNM40[103:64]"S C 3 2 G"
(0x5343333247)
Product revisionPRV8[63:56]0x80
Product serial numberPSN32[55:24]0x49D204AD
reserved--4[23:20]0
Manufacturing dateMDT12[19:8]0x12A
(October 2018)
CRC7 checksumCRC7[7:1]0x6F
not used, always 1-1[0:0]1

PNM:
The product name is a string, 5-character ASCII string.
MDT:
The “m” field [11:8] is the month code. 1 = January.
The “y” field [19:12] is the year code. 0 = 2000.

2.2 CMD3: SD_CMD_SET_REL_ADDR

CMD3: SD_CMD_SET_REL_ADDR 主機發出CMD3 (SEND_RELATIVE_ADDR)請求SD卡發布一個新的相對卡地址(RCA),它比CID短,在未來的數據傳輸模式中用于給SD卡尋址。一旦接收到RCA,SD卡狀態就會變為待機狀態。此時,如果主機希望分配另一個RCA號碼,它可以通過向卡發送另一個CMD3命令來要求卡發布一個新號碼。最后發布的RCA是SD卡的實際RCA號。

#define SD_CMD_SET_REL_ADDR ((uint8_t)3) /*!< SDIO_SEND_REL_ADDR for SD Card *//*!< Send CMD3 SET_REL_ADDR with argument 0 */ /*!< SD Card publishes its RCA. */ SDIO_CmdInitStructure.SDIO_Argument = 0x00; SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_REL_ADDR; SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; SDIO_SendCommand(&SDIO_CmdInitStructure);

因為發送命令CMD3的Argument是stuff bits,所以這里需要填寫0x00。實際發送出去的波形如下:

發送CMD3命令后,調用CmdResp6Error()獲取SDIO 狀態寄存器 (SDIO_STA) Value,通過返回的狀態Value來判斷命令響應是否已經正確被接收。如果響應被正確被接受,通過訪問SDIO 命令響應寄存器 (SDIO_RESPCMD)來獲取Response Command Index。判斷Response Command Index是否等于CMD3,然后訪問SDIO 響應 1 寄存器 (SDIO_RESP1)來獲取RCA的值。

static SD_Error CmdResp6Error(uint8_t cmd, uint16_t *prca) {SD_Error errorstatus = SD_OK;uint32_t status;uint32_t response_r1;status = SDIO->STA;while (!(status & (SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CTIMEOUT | SDIO_FLAG_CMDREND))){status = SDIO->STA;}.../*!< Check response received is of desired command */if (SDIO_GetCommandResponse() != cmd){errorstatus = SD_ILLEGAL_CMD;return(errorstatus);}/*!< Clear all the static flags */SDIO_ClearFlag(SDIO_STATIC_FLAGS);/*!< We have received response, retrieve it. */response_r1 = SDIO_GetResponse(SDIO_RESP1);if (SD_ALLZERO == (response_r1 & (SD_R6_GENERAL_UNKNOWN_ERROR | SD_R6_ILLEGAL_CMD | SD_R6_COM_CRC_FAILED))){*prca = (uint16_t) (response_r1 >> 16);return(errorstatus);}...return(errorstatus); }

從SD2.0協議里面可以了解到CMD3的response格式是R6,R6主要獲取RCA和Card Status Bits的值。


邏輯分析儀抓取波形可以了解到 RCA = 0xAAAA,波形如下:

2.3 CMD9: SD_CMD_SEND_CSD

CMD9: SD_CMD_SEND_CSD主機發出SEND_CSD(CMD9)以獲取與SD卡有關的數據(CSD寄存器),例如塊長度、卡的儲存容量等。

#define SD_CMD_SEND_CSD ((uint8_t)9)/*!< Send CMD9 SEND_CSD with argument as card's RCA */ SDIO_CmdInitStructure.SDIO_Argument = (uint32_t)(rca << 16); // RCA = 0xAAAA SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SEND_CSD; SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Long; SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; SDIO_SendCommand(&SDIO_CmdInitStructure);

發送CMD9命令時,Argument需要填寫RCA。前面已經獲取到 RCA = 0xAAAA,所以實際發送的命令波形如下:

發送CMD9命令后,調用CmdResp2Error()獲取SDIO 狀態寄存器 (SDIO_STA) Value,通過返回的狀態Value來判斷命令響應是否已經正確被接收。如果響應被正確被接受,通過訪問SDIO 響應 1…4 寄存器 (SDIO_RESPx)來獲取CSD的值。

errorstatus = CmdResp2Error();if (SD_OK != errorstatus) {return(errorstatus); }CSD_Tab[0] = SDIO_GetResponse(SDIO_RESP1); CSD_Tab[1] = SDIO_GetResponse(SDIO_RESP2); CSD_Tab[2] = SDIO_GetResponse(SDIO_RESP3); CSD_Tab[3] = SDIO_GetResponse(SDIO_RESP4);

從SD2.0協議里面可以了解到CMD2的response格式是R2,R2主要獲取CID或者CSD值。


邏輯分析儀抓取波形如下:

從上面的波形可以獲取到CSD值為:0x400E00325B590000EDC87F800A4040C3,關于CSD的表格如下:

NameFieldWidthValueCell TypeCID-slice
CSD structureCSD_STRUCTURE201bR[127:126]
reserved-600 0000bR[125:120]
data read access-time(TAAC)80EhR[119:112]
data read access-time
in CLK cycles (NSAC*100)
(NSAC)800hR[111:104]
max. data transfer rate(TRAN_SPEED)832h or 5AhR[103:96]
card command classesCCC12010110110101bR[95:84]
max. read data block length(READ_BL_LEN)49R[83:80]
partial blocks for read allowed(READ_BL_PARTIAL)10R[79:79]
write block misalignment(WRITE_BLK_MISALIGN)10R[78:78]
read block misalignment(READ_BLK_MISALIGN)10R[77:77]
DSR implementedDSR_IMP10R[76:76]
reserved -600 0000bR[75:70]
device sizeC_SIZE2200 EDC8hR[69:48]
reserved -10R[47:47]
erase single block enable(ERASE_BLK_EN) 11R[46:46]
erase sector size(SECTOR_SIZE)77FhR[45:39]
write protect group size (WP_GRP_SIZE) 70000000bR[38:32]
write protect group enable(WP_GRP_ENABLE) 10R[31:31]
reserved-200bR[30:29]
write speed factor (R2W_FACTOR)3010bR[28:26]
max. write data block length(WRITE_BL_LEN) 49R[25:22]
partial blocks for write allowed(WRITE_BL_PARTIAL) 10R[21:21]
reserved -500000bR[20:16]
File format group(FILE_FORMAT_GRP)10R[15:15]
copy flag (OTP)COPY11R/W(1)[14:14]
permanent write protectionPERM_WRITE_PROTECT10R/W(1)[13:13]
temporary write protectionTMP_WRITE_PROTECT10R/W[12:12]
File format(FILE_FORMAT) 200bR[11:10]
reserved-200bR[9:8]
CRCCRC7110 0001bR/W[7:1]
not used, always’1’ -11-[0:0]
  • CSD_STRUCTURE
    CSD_STRUCTURE指示了CSD structure version,根據上面解析的數據,所以選擇的是CSD Version 2.0。

  • TRAN_SPEED
    下表定義了每條數據線的最大數據傳輸速率- TRAN_SPEED:

    當時鐘等于25MHz時,這個域總是0_0110_010b (032h)。如果時鐘等于50MHz時,這個域總是0_1011_010b (05Ah)

  • READ_BL_LEN
    READ_BL_LEN最大讀數據塊長度計算公式為2READ_BL_LEN,最大塊長度應該在512…2048個字節。注意,在SD存儲卡的WRITE_BL_LEN總是等于READ_BL_LEN。根據上面數據的解析,所以Block Length的值為 29 = 512 Bytes

3.SDIO_Init()

SDIO_Init()主要是配置SDIO時鐘控制寄存器(SDIO_CLKCR)。因為接下來SD卡會進入傳輸模式,所以這里需要提高SDIO Clock,這里將SDIO_CK 頻率設置為25MHz。

/** * @brief SDIO Data Transfer Frequency (25MHz max) */ #define SDIO_TRANSFER_CLK_DIV ((uint8_t)0x0)/*!< Configure the SDIO peripheral */ /*!< SDIO_CK = SDIOCLK / (SDIO_TRANSFER_CLK_DIV + 2) */ /*!< on STM32F4xx devices, SDIOCLK is fixed to 48MHz */ SDIO_InitStructure.SDIO_ClockDiv = SDIO_TRANSFER_CLK_DIV; SDIO_InitStructure.SDIO_ClockEdge = SDIO_ClockEdge_Rising; SDIO_InitStructure.SDIO_ClockBypass = SDIO_ClockBypass_Disable; SDIO_InitStructure.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable; SDIO_InitStructure.SDIO_BusWide = SDIO_BusWide_1b; SDIO_InitStructure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable; SDIO_Init(&SDIO_InitStructure);

名稱描述Value備注
CLKDIV時鐘分頻系數 (Clock divide factor)
該字段定義輸入時鐘 (SDIOCLK) 與輸出時鐘 (SDIO_CK) 之間的分頻系數:
SDIO_CK 頻率 = SDIOCLK / [CLKDIV + 2]
0x00SDIO_CK 頻率 = SDIOCLK / [CLKDIV + 2]
24M = 48M / [0x00 + 2]

設置SDIO_CK之前,頻率為400KHz左右,如下:

設置SDIO_CK之后,頻率為25MHz左右,如下:

4.SD_GetCardInfo()

SD_GetCardInfo()主要作用是解析前面獲取到CSD的值,具體可以參考上面的表格,這里不重復介紹了。

SD_Error SD_GetCardInfo(SD_CardInfo *cardinfo) {SD_Error errorstatus = SD_OK;uint8_t tmp = 0;cardinfo->CardType = (uint8_t)CardType;cardinfo->RCA = (uint16_t)RCA;/*!< Byte 0 */tmp = (uint8_t)((CSD_Tab[0] & 0xFF000000) >> 24);cardinfo->SD_csd.CSDStruct = (tmp & 0xC0) >> 6;cardinfo->SD_csd.SysSpecVersion = (tmp & 0x3C) >> 2;cardinfo->SD_csd.Reserved1 = tmp & 0x03;/*!< Byte 1 */tmp = (uint8_t)((CSD_Tab[0] & 0x00FF0000) >> 16);cardinfo->SD_csd.TAAC = tmp;/*!< Byte 2 */tmp = (uint8_t)((CSD_Tab[0] & 0x0000FF00) >> 8);cardinfo->SD_csd.NSAC = tmp;/*!< Byte 3 */tmp = (uint8_t)(CSD_Tab[0] & 0x000000FF);cardinfo->SD_csd.MaxBusClkFrec = tmp;/*!< Byte 4 */tmp = (uint8_t)((CSD_Tab[1] & 0xFF000000) >> 24);cardinfo->SD_csd.CardComdClasses = tmp << 4;/*!< Byte 5 */tmp = (uint8_t)((CSD_Tab[1] & 0x00FF0000) >> 16);cardinfo->SD_csd.CardComdClasses |= (tmp & 0xF0) >> 4;cardinfo->SD_csd.RdBlockLen = tmp & 0x0F;/*!< Byte 6 */tmp = (uint8_t)((CSD_Tab[1] & 0x0000FF00) >> 8);cardinfo->SD_csd.PartBlockRead = (tmp & 0x80) >> 7;cardinfo->SD_csd.WrBlockMisalign = (tmp & 0x40) >> 6;cardinfo->SD_csd.RdBlockMisalign = (tmp & 0x20) >> 5;cardinfo->SD_csd.DSRImpl = (tmp & 0x10) >> 4;cardinfo->SD_csd.Reserved2 = 0; /*!< Reserved */...}

5.SD_SelectDeselect()

SD_SelectDeselect()主要作用是通過CMD7選擇對應的RCA地址的SD卡進入傳輸模式,前面已經獲取到RCA地址為 RCA = 0xAAAA。CMD7用于選擇一張SD卡并將其置于傳輸狀態,在同一時刻只能有一張卡處于傳輸狀態。如果先前選擇的卡處于傳輸狀態,它與主機的連接將被釋放,它將返回到 Stand-by 狀態。

errorstatus = SD_SelectDeselect((uint32_t) (SDCardInfo.RCA << 16)); // RCA = 0xAAAA-------------------------------------------------->SD_Error SD_SelectDeselect(uint64_t addr) {SD_Error errorstatus = SD_OK;/*!< Send CMD7 SDIO_SEL_DESEL_CARD */SDIO_CmdInitStructure.SDIO_Argument = (uint32_t)addr;SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SEL_DESEL_CARD;SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;SDIO_SendCommand(&SDIO_CmdInitStructure);errorstatus = CmdResp1Error(SD_CMD_SEL_DESEL_CARD);return(errorstatus); }

實際發送出去的波形如下:

發送CMD7命令后,調用CmdResp1Error獲取SDIO 狀態寄存器 (SDIO_STA)來判斷命令響應是否已經正確被接收。然后,通過函數SDIO_GetCommandResponse獲取SDIO 命令響應寄存器 (SDIO_RESPCMD) Value來判斷Host接收到的響應命令是否是剛剛發送的命令。最后,通過函數SDIO_GetResponse獲取SDIO 響應 1寄存器 (SDIO_RESP1) SD卡的狀態。

static SD_Error CmdResp1Error(uint8_t cmd) {SD_Error errorstatus = SD_OK;uint32_t status;uint32_t response_r1;status = SDIO->STA;while (!(status & (SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT))){status = SDIO->STA;}.../*!< Check response received is of desired command */if (SDIO_GetCommandResponse() != cmd){errorstatus = SD_ILLEGAL_CMD;return(errorstatus);}/*!< Clear all the static flags */SDIO_ClearFlag(SDIO_STATIC_FLAGS);/*!< We have received response, retrieve it for analysis */response_r1 = SDIO_GetResponse(SDIO_RESP1);if ((response_r1 & SD_OCR_ERRORBITS) == SD_ALLZERO){return(errorstatus);}if (response_r1 & SD_OCR_ADDR_OUT_OF_RANGE){return(SD_ADDR_OUT_OF_RANGE);}...return(errorstatus); }

從SD2.0協議里面可以了解到CMD7的response是R1b,R1b和R1功能完全相同,主要獲取的Card Status。


通過邏輯分析儀抓取的波形, Card Status指示SD卡當前狀態為Stand-by 狀態, 如下:

6.SD_EnableWideBusOperation()

通過SD_EnableWideBusOperation(SDIO_BusWide_4b)設置總線寬度為4bit模式,首先需要獲取SCR Register Value(FindSCR())判定SD卡是否支持4bit模式,然后發送ACMD6設置SD卡工作在4bit模式,同時host端STM32也設置為4bit模式。整體的思維導圖如下:

6.1 CMD16:SD_CMD_SET_BLOCKLEN

在FindSCR()函數中發送CMD16:SD_CMD_SET_BLOCKLEN來設置SD卡Block Size為8 Bytes

#define SD_CMD_SET_BLOCKLEN ((uint8_t)16)/*!< Set Block Size To 8 Bytes */ SDIO_CmdInitStructure.SDIO_Argument = (uint32_t)8; SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_BLOCKLEN; SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; SDIO_SendCommand(&SDIO_CmdInitStructure);errorstatus = CmdResp1Error(SD_CMD_SET_BLOCKLEN);


實際發送出去波形如下:

然后SD卡處理完后,以R1的形式Response Card Status,波形如下:

6.2 SDIO_DataConfig()

SDIO_DataConfig()設置STM32 SDIO寄存器DLEN和DCTRL數據長度和塊大小為8Bytes,并設置傳輸方向為:SD Card -> Host SDIO。

SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;SDIO_DataInitStructure.SDIO_DataLength = 8;SDIO_DataInitStructure.SDIO_DataBlockSize = SDIO_DataBlockSize_8b;SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToSDIO;SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block;SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Enable;SDIO_DataConfig(&SDIO_DataInitStructure);

6.3 ACMD51:SD_CMD_SD_APP_SEND_SCR

ACMD51:SD_CMD_SD_APP_SEND_SCR主要是讀取配置寄存器 SCR的值,發送完這個命令后R1返回Card Status,然后在DATA0數據線上返回SCR的值。

#define SD_CMD_SD_APP_SEND_SCR ((uint8_t)51) /*!< For SD Card only *//*!< Send ACMD51 SD_APP_SEND_SCR with argument as 0 */ SDIO_CmdInitStructure.SDIO_Argument = 0x0; SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SD_APP_SEND_SCR; SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; SDIO_SendCommand(&SDIO_CmdInitStructure);errorstatus = CmdResp1Error(SD_CMD_SD_APP_SEND_SCR);


實際發送出去的波形如下:

然后SD卡處理完后,以R1的形式Response Card Status,波形如下:

6.4 SDIO_ReadData()

SDIO_ReadData()從SDIO FIFO中獲取DATA0 SD卡返回的SCR Value:

while (!(SDIO->STA & (SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND | SDIO_FLAG_STBITERR))){if (SDIO_GetFlagStatus(SDIO_FLAG_RXDAVL) != RESET){*(tempscr + index) = SDIO_ReadData();index++;}}

在SDIO DATA0上面返回SCR Value為:0x0235804300000000,波形如下:

SCR Value為:0x0235804300000000對應SCR寄存器的表格如下:

DescriptionFieldWidthValueCell
Type
SCR
Slice
SCR Structure SCR_STRUCTURE40000bR[63:60]
SD Memory Card - Spec. VersionSD_SPEC40010bR[59:56]
data_status_after erasesDATA_STAT_AFTER_ERASE10bR[55:55]
SD Security SupportSD_SECURITY3011bR[54:52]
DAT Bus widths supportedSD_BUS_WIDTHS40101bR[51:48]
reserved-16 R[47:32]
reserved for manufacturer usage-32 R[31:0]
  • SCR_STRUCTURE
  • SD_SPEC
    SD_SPEC描述了SD卡支持SD協議版本號。
  • SD_SECURITY
    SD_SECURITY描述了Security Specification Version版本號。
  • SD_BUS_WIDTHS
    SD_BUS_WIDTHS描述了SDIO總線的寬度,同時支持1bit和4bit。

6.5 ACMD6:SD_CMD_APP_SD_SET_BUSWIDTH

ACMD6:SD_CMD_APP_SD_SET_BUSWIDTH 通過SCR Value判斷SD卡支持4bit總線,并通過AMCD6設置SD卡總線寬度為4bit。

#define SD_CMD_APP_SD_SET_BUSWIDTH ((uint8_t)6) /*!< For SD Card only *//*!< Send ACMD6 APP_CMD with argument as 2 for wide bus mode */ SDIO_CmdInitStructure.SDIO_Argument = 0x2; SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_APP_SD_SET_BUSWIDTH; SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; SDIO_SendCommand(&SDIO_CmdInitStructure);errorstatus = CmdResp1Error(SD_CMD_APP_SD_SET_BUSWIDTH);


實際發送出去的波形如下:

6.6 SDIO_Init()

SDIO_Init()配置STM32 SDIO時鐘控制寄存器(SDIO_CLKCR):時鐘為25MHz和總線寬度為4bit模式

/*!< Configure the SDIO peripheral */ SDIO_InitStructure.SDIO_ClockDiv = SDIO_TRANSFER_CLK_DIV; SDIO_InitStructure.SDIO_ClockEdge = SDIO_ClockEdge_Rising; SDIO_InitStructure.SDIO_ClockBypass = SDIO_ClockBypass_Disable; SDIO_InitStructure.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable; SDIO_InitStructure.SDIO_BusWide = SDIO_BusWide_4b; SDIO_InitStructure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable; SDIO_Init(&SDIO_InitStructure);

Note:到此SD_Init的整個SD卡初始化完成。

7. 參考資料

SDIO參考的資料如下:

下載地址如下:
https://download.csdn.net/download/ZHONGCAI0901/14975835

移植成功的完整代碼下載地址如下:
https://download.csdn.net/download/ZHONGCAI0901/15265756

總結

以上是生活随笔為你收集整理的【STM32】STM32 SDIO SD卡读写测试(三)-- SD_Init之Init Card阶段的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。