【STM32】STM32 SDIO SD卡读写测试(三)-- SD_Init之Init Card阶段
相關(guān)文章
《【SDIO】SDIO、SD卡、FatFs文件系統(tǒng)相關(guān)文章索引》
1. 前言
本篇文章主要是介紹stm324x9i_eval_sdio_sd.c里面SD_Init()函數(shù)完整的過程。它主要是實(shí)現(xiàn)了SDIO的初始化、SD卡的Power UP、SD卡的初始化和獲取SD卡的相關(guān)信息等,下面會(huì)詳細(xì)介紹SD卡的初始化和獲取SD卡的相關(guān)信息的分析。
2. SD_InitializeCards()
SD_InitializeCards()主要的功能是初始化SD卡獲取CID和RCA的信息,并進(jìn)入Standby狀態(tài)。主要涉及到的函數(shù)如下:
- 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值是卡的唯一標(biāo)識(shí)。在卡發(fā)送CID后,它進(jìn)入識(shí)別狀態(tài)。
#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);發(fā)送出去的波形如下:
發(fā)送CMD2命令后,調(diào)用CmdResp2Error()獲取SDIO 狀態(tài)寄存器 (SDIO_STA) Value,通過返回的狀態(tài)Value來判斷命令響應(yīng)是否已經(jīng)正確被接收。如果響應(yīng)被正確被接受,通過訪問SDIO 響應(yīng) 1…4 寄存器 (SDIO_RESPx)來獲取CID的值。
從SD2.0協(xié)議里面可以了解到CMD2的response格式是R2,R2主要獲取CID或者CSD值。
為什么獲取CID值需要讀取SDIO Response 1…4寄存器?
因?yàn)樵赟TM32的SDIO相關(guān)寄存器可以了解到關(guān)于127 Bit 長響應(yīng)會(huì)用到SDIO_RESP1..4這4個(gè)寄存器拼接成的(如下圖STM32 SDIO Datasheet所示),所以這里需要訪問這4個(gè)寄存器。如果命令響應(yīng)的參數(shù)的長度是32 Bit 短響應(yīng),那么就只需要讀取SDIO_RESP1寄存器的Value。
R1、R2、R3、R6、R7 和 SDIO_RESP1…4 這2個(gè)概率容易弄混:
- R1、R2、R3、R6、R7:這個(gè)是SD2.0《Physical Specification Version 2.00》 協(xié)議規(guī)定CMD響應(yīng)命令格式。
- SDIO_RESP1..4:這個(gè)是STM32寄存器存放命令響應(yīng)參數(shù)的值。
邏輯分析儀抓取波形如下:
從上面的波形可以獲取到CID值為:0x03534453433332478049D204AD012ADF,關(guān)于CID的表格如下:
| Name | Field | Width | CID-slice | Value |
| Manufacturer ID | MID | 8 | [127:120] | 0x03 |
| OEM/Application ID | OID | 16 | [119:104] | 0x5344 |
| Product name | PNM | 40 | [103:64] | "S C 3 2 G" (0x5343333247) |
| Product revision | PRV | 8 | [63:56] | 0x80 |
| Product serial number | PSN | 32 | [55:24] | 0x49D204AD |
| reserved | -- | 4 | [23:20] | 0 |
| Manufacturing date | MDT | 12 | [19:8] | 0x12A (October 2018) |
| CRC7 checksum | CRC | 7 | [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 主機(jī)發(fā)出CMD3 (SEND_RELATIVE_ADDR)請(qǐng)求SD卡發(fā)布一個(gè)新的相對(duì)卡地址(RCA),它比CID短,在未來的數(shù)據(jù)傳輸模式中用于給SD卡尋址。一旦接收到RCA,SD卡狀態(tài)就會(huì)變?yōu)?strong>待機(jī)狀態(tài)。此時(shí),如果主機(jī)希望分配另一個(gè)RCA號(hào)碼,它可以通過向卡發(fā)送另一個(gè)CMD3命令來要求卡發(fā)布一個(gè)新號(hào)碼。最后發(fā)布的RCA是SD卡的實(shí)際RCA號(hào)。
#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);因?yàn)榘l(fā)送命令CMD3的Argument是stuff bits,所以這里需要填寫0x00。實(shí)際發(fā)送出去的波形如下:
發(fā)送CMD3命令后,調(diào)用CmdResp6Error()獲取SDIO 狀態(tài)寄存器 (SDIO_STA) Value,通過返回的狀態(tài)Value來判斷命令響應(yīng)是否已經(jīng)正確被接收。如果響應(yīng)被正確被接受,通過訪問SDIO 命令響應(yīng)寄存器 (SDIO_RESPCMD)來獲取Response Command Index。判斷Response Command Index是否等于CMD3,然后訪問SDIO 響應(yīng) 1 寄存器 (SDIO_RESP1)來獲取RCA的值。
從SD2.0協(xié)議里面可以了解到CMD3的response格式是R6,R6主要獲取RCA和Card Status Bits的值。
邏輯分析儀抓取波形可以了解到 RCA = 0xAAAA,波形如下:
2.3 CMD9: SD_CMD_SEND_CSD
CMD9: SD_CMD_SEND_CSD主機(jī)發(fā)出SEND_CSD(CMD9)以獲取與SD卡有關(guān)的數(shù)據(jù)(CSD寄存器),例如塊長度、卡的儲(chǔ)存容量等。
#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);發(fā)送CMD9命令時(shí),Argument需要填寫RCA。前面已經(jīng)獲取到 RCA = 0xAAAA,所以實(shí)際發(fā)送的命令波形如下:
發(fā)送CMD9命令后,調(diào)用CmdResp2Error()獲取SDIO 狀態(tài)寄存器 (SDIO_STA) Value,通過返回的狀態(tài)Value來判斷命令響應(yīng)是否已經(jīng)正確被接收。如果響應(yīng)被正確被接受,通過訪問SDIO 響應(yīng) 1…4 寄存器 (SDIO_RESPx)來獲取CSD的值。
從SD2.0協(xié)議里面可以了解到CMD2的response格式是R2,R2主要獲取CID或者CSD值。
邏輯分析儀抓取波形如下:
從上面的波形可以獲取到CSD值為:0x400E00325B590000EDC87F800A4040C3,關(guān)于CSD的表格如下:
| Name | Field | Width | Value | Cell Type | CID-slice |
| CSD structure | CSD_STRUCTURE | 2 | 01b | R | [127:126] |
| reserved | - | 6 | 00 0000b | R | [125:120] |
| data read access-time | (TAAC) | 8 | 0Eh | R | [119:112] |
| data read access-time in CLK cycles (NSAC*100) | (NSAC) | 8 | 00h | R | [111:104] |
| max. data transfer rate | (TRAN_SPEED) | 8 | 32h or 5Ah | R | [103:96] |
| card command classes | CCC | 12 | 010110110101b | R | [95:84] |
| max. read data block length | (READ_BL_LEN) | 4 | 9 | R | [83:80] |
| partial blocks for read allowed | (READ_BL_PARTIAL) | 1 | 0 | R | [79:79] |
| write block misalignment | (WRITE_BLK_MISALIGN) | 1 | 0 | R | [78:78] |
| read block misalignment | (READ_BLK_MISALIGN) | 1 | 0 | R | [77:77] |
| DSR implemented | DSR_IMP | 1 | 0 | R | [76:76] |
| reserved | - | 6 | 00 0000b | R | [75:70] |
| device size | C_SIZE | 22 | 00 EDC8h | R | [69:48] |
| reserved | - | 1 | 0 | R | [47:47] |
| erase single block enable | (ERASE_BLK_EN) | 1 | 1 | R | [46:46] |
| erase sector size | (SECTOR_SIZE) | 7 | 7Fh | R | [45:39] |
| write protect group size | (WP_GRP_SIZE) | 7 | 0000000b | R | [38:32] |
| write protect group enable | (WP_GRP_ENABLE) | 1 | 0 | R | [31:31] |
| reserved | - | 2 | 00b | R | [30:29] |
| write speed factor | (R2W_FACTOR) | 3 | 010b | R | [28:26] |
| max. write data block length | (WRITE_BL_LEN) | 4 | 9 | R | [25:22] |
| partial blocks for write allowed | (WRITE_BL_PARTIAL) | 1 | 0 | R | [21:21] |
| reserved | - | 5 | 00000b | R | [20:16] |
| File format group | (FILE_FORMAT_GRP) | 1 | 0 | R | [15:15] |
| copy flag (OTP) | COPY | 1 | 1 | R/W(1) | [14:14] |
| permanent write protection | PERM_WRITE_PROTECT | 1 | 0 | R/W(1) | [13:13] |
| temporary write protection | TMP_WRITE_PROTECT | 1 | 0 | R/W | [12:12] |
| File format | (FILE_FORMAT) | 2 | 00b | R | [11:10] |
| reserved | - | 2 | 00b | R | [9:8] |
| CRC | CRC | 7 | 110 0001b | R/W | [7:1] |
| not used, always’1’ | - | 1 | 1 | - | [0:0] |
-
CSD_STRUCTURE
CSD_STRUCTURE指示了CSD structure version,根據(jù)上面解析的數(shù)據(jù),所以選擇的是CSD Version 2.0。
-
TRAN_SPEED
下表定義了每條數(shù)據(jù)線的最大數(shù)據(jù)傳輸速率- TRAN_SPEED:
當(dāng)時(shí)鐘等于25MHz時(shí),這個(gè)域總是0_0110_010b (032h)。如果時(shí)鐘等于50MHz時(shí),這個(gè)域總是0_1011_010b (05Ah)。 -
READ_BL_LEN
READ_BL_LEN最大讀數(shù)據(jù)塊長度計(jì)算公式為2READ_BL_LEN,最大塊長度應(yīng)該在512…2048個(gè)字節(jié)。注意,在SD存儲(chǔ)卡的WRITE_BL_LEN總是等于READ_BL_LEN。根據(jù)上面數(shù)據(jù)的解析,所以Block Length的值為 29 = 512 Bytes。
3.SDIO_Init()
SDIO_Init()主要是配置SDIO時(shí)鐘控制寄存器(SDIO_CLKCR)。因?yàn)榻酉聛鞸D卡會(huì)進(jìn)入傳輸模式,所以這里需要提高SDIO Clock,這里將SDIO_CK 頻率設(shè)置為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 | 時(shí)鐘分頻系數(shù) (Clock divide factor) 該字段定義輸入時(shí)鐘 (SDIOCLK) 與輸出時(shí)鐘 (SDIO_CK) 之間的分頻系數(shù): SDIO_CK 頻率 = SDIOCLK / [CLKDIV + 2] | 0x00 | SDIO_CK 頻率 = SDIOCLK / [CLKDIV + 2] 24M = 48M / [0x00 + 2] |
設(shè)置SDIO_CK之前,頻率為400KHz左右,如下:
設(shè)置SDIO_CK之后,頻率為25MHz左右,如下:
4.SD_GetCardInfo()
SD_GetCardInfo()主要作用是解析前面獲取到CSD的值,具體可以參考上面的表格,這里不重復(fù)介紹了。
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選擇對(duì)應(yīng)的RCA地址的SD卡進(jìn)入傳輸模式,前面已經(jīng)獲取到RCA地址為 RCA = 0xAAAA。CMD7用于選擇一張SD卡并將其置于傳輸狀態(tài),在同一時(shí)刻只能有一張卡處于傳輸狀態(tài)。如果先前選擇的卡處于傳輸狀態(tài),它與主機(jī)的連接將被釋放,它將返回到 Stand-by 狀態(tài)。
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); }實(shí)際發(fā)送出去的波形如下:
發(fā)送CMD7命令后,調(diào)用CmdResp1Error獲取SDIO 狀態(tài)寄存器 (SDIO_STA)來判斷命令響應(yīng)是否已經(jīng)正確被接收。然后,通過函數(shù)SDIO_GetCommandResponse獲取SDIO 命令響應(yīng)寄存器 (SDIO_RESPCMD) Value來判斷Host接收到的響應(yīng)命令是否是剛剛發(fā)送的命令。最后,通過函數(shù)SDIO_GetResponse獲取SDIO 響應(yīng) 1寄存器 (SDIO_RESP1) SD卡的狀態(tài)。
從SD2.0協(xié)議里面可以了解到CMD7的response是R1b,R1b和R1功能完全相同,主要獲取的Card Status。
通過邏輯分析儀抓取的波形, Card Status指示SD卡當(dāng)前狀態(tài)為Stand-by 狀態(tài), 如下:
6.SD_EnableWideBusOperation()
通過SD_EnableWideBusOperation(SDIO_BusWide_4b)設(shè)置總線寬度為4bit模式,首先需要獲取SCR Register Value(FindSCR())判定SD卡是否支持4bit模式,然后發(fā)送ACMD6設(shè)置SD卡工作在4bit模式,同時(shí)host端STM32也設(shè)置為4bit模式。整體的思維導(dǎo)圖如下:
6.1 CMD16:SD_CMD_SET_BLOCKLEN
在FindSCR()函數(shù)中發(fā)送CMD16:SD_CMD_SET_BLOCKLEN來設(shè)置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);
實(shí)際發(fā)送出去波形如下:
然后SD卡處理完后,以R1的形式Response Card Status,波形如下:
6.2 SDIO_DataConfig()
SDIO_DataConfig()設(shè)置STM32 SDIO寄存器DLEN和DCTRL數(shù)據(jù)長度和塊大小為8Bytes,并設(shè)置傳輸方向?yàn)?#xff1a;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的值,發(fā)送完這個(gè)命令后R1返回Card Status,然后在DATA0數(shù)據(jù)線上返回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);
實(shí)際發(fā)送出去的波形如下:
然后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對(duì)應(yīng)SCR寄存器的表格如下:
| Description | Field | Width | Value | Cell Type | SCR Slice |
| SCR Structure | SCR_STRUCTURE | 4 | 0000b | R | [63:60] |
| SD Memory Card - Spec. Version | SD_SPEC | 4 | 0010b | R | [59:56] |
| data_status_after erases | DATA_STAT_AFTER_ERASE | 1 | 0b | R | [55:55] |
| SD Security Support | SD_SECURITY | 3 | 011b | R | [54:52] |
| DAT Bus widths supported | SD_BUS_WIDTHS | 4 | 0101b | R | [51:48] |
| reserved | - | 16 | R | [47:32] | |
| reserved for manufacturer usage | - | 32 | R | [31:0] |
- SCR_STRUCTURE
- SD_SPEC
SD_SPEC描述了SD卡支持SD協(xié)議版本號(hào)。
- SD_SECURITY
SD_SECURITY描述了Security Specification Version版本號(hào)。
- SD_BUS_WIDTHS
SD_BUS_WIDTHS描述了SDIO總線的寬度,同時(shí)支持1bit和4bit。
6.5 ACMD6:SD_CMD_APP_SD_SET_BUSWIDTH
ACMD6:SD_CMD_APP_SD_SET_BUSWIDTH 通過SCR Value判斷SD卡支持4bit總線,并通過AMCD6設(shè)置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);
實(shí)際發(fā)送出去的波形如下:
6.6 SDIO_Init()
SDIO_Init()配置STM32 SDIO時(shí)鐘控制寄存器(SDIO_CLKCR):時(shí)鐘為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的整個(gè)SD卡初始化完成。
7. 參考資料
SDIO參考的資料如下:
下載地址如下:
https://download.csdn.net/download/ZHONGCAI0901/14975835
移植成功的完整代碼下載地址如下:
https://download.csdn.net/download/ZHONGCAI0901/15265756
總結(jié)
以上是生活随笔為你收集整理的【STM32】STM32 SDIO SD卡读写测试(三)-- SD_Init之Init Card阶段的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 能在路由器里挂载阿里云盘的aliyund
- 下一篇: 安装es报错: max virtual