实际sd卡初始化的时候有的指令要多发几次才有响应,lz可以参考下我这个初始化代码
- /**
- * [url=home.php?mod=space&uid=247401]@brief[/url] SDCard(SPI Mode) Initialization
- * @param None
- * @retval Operation Result Depending on Response Token
- */
- uint8_t SD_SPI_Init(void)
- {
- uint8_t rs = SD_OK;
- uint8_t sd_ver;
- uint32_t i, tick_now;
- SD_CMDTypeDef SD_CMD;
- SD_R1TypeDef R1;
- SD_R3TypeDef R3;
- SD_R7TypeDef R7;
-
- if(SD_InitState != 0)
- {
- goto DONE;
- }
-
- //MSP Initialization
- SD_SPI_MspInit();
-
- //Least then 400KHz
- SD_NormalSpeed();
-
- //Delay for Power up
- HAL_Delay(20);
-
- //In case of SPI mode, CS shall be held to high during 74 clock cycles
- SD_CS_SET();
-
- for(i = 0; i < 8; i++)
- {
- SD_WR_Byte(0xFF);
- }
-
- //CMD0+, Goto idle State
- tick_now = HAL_GetTick();
-
- do
- {
- if((HAL_GetTick() - tick_now) > GOTO_IDLE_TIMEOUT)
- {
- //Timeout and Return
- rs = SD_TIMEOUT;
- goto DONE;
- }
-
- SD_CMD.Cmd = GO_IDLE_STATE;
- SD_CMD.Arg = 0;
- SD_CMD.Crc = 0x95;
- rs = SD_W_CMD_R1(&SD_CMD, &R1);
-
- if(rs == SD_OK)
- {
- if((R1 & R1_IDLE_STATE) == 0)
- {
- rs = SD_ERROR;
- }
- }
- }
- while(rs != SD_OK);
-
- //CMD8, Sends SD Memory Card interface condition
- SD_CMD.Cmd = SEND_IF_COND;
- SD_CMD.Arg = 0x1AA;
- SD_CMD.Crc = 0x87;
- rs = SD_W_CMD_R7(&SD_CMD, &R7);
-
- if(rs != SD_OK)
- {
- goto DONE;
- }
-
- if(R7.R1 & R1_IDLE_STATE)
- {
- if(R7.R1 & R1_ILLEGAL_CMD)
- {
- //Ver1.X SD Menmory Card or Not SD Menmory Card
-
- sd_ver = SD_V1X_STANDARD_CAPACITY;
- }
- else
- {
- if((R7.VoltageAccepted != 0x01)||(R7.CheckPattern != 0xAA))
- {
- rs = SD_ERROR;
- goto DONE;
- }
-
- //Ver2.00 or later SD Memory Card
- }
- }
-
- //Wait Card Ready
- tick_now = HAL_GetTick();
-
- do
- {
- if((HAL_GetTick() - tick_now) > CARD_READY_TIMEOUT)
- {
- rs = SD_TIMEOUT;
- goto DONE;
- }
-
- //CMD55, Defines to the card that the next command is an application
- SD_CMD.Cmd = APP_CMD;
- SD_CMD.Arg = 0;
- SD_CMD.Crc = 0;
- rs = SD_W_CMD_R1(&SD_CMD, &R1);
-
- if(rs != SD_OK)
- {
- goto DONE;
- }
-
- if(R1 != R1_IDLE_STATE)
- {
- rs = SD_ERROR;
- goto DONE;
- }
-
- //ACMD41, Sends host capacity support information and activates the card's initialization process.
- SD_CMD.Cmd = SD_SEND_OP_COND;
- if(sd_ver == SD_V1X_STANDARD_CAPACITY)
- {
- SD_CMD.Arg = 0<<30;
- }
- else
- {
- SD_CMD.Arg = 1<<30;
- }
- SD_CMD.Crc = 0;
- rs = SD_W_CMD_R1(&SD_CMD, &R1);
-
- if(rs == SD_OK)
- {
- if(R1 & R1_IDLE_STATE)
- {
- rs = SD_ERROR;
- }
- }
- }
- while(rs != SD_OK);
-
- //CMD58, Reads the OCR register
- SD_CMD.Cmd = READ_OCR;
- SD_CMD.Arg = 0;
- SD_CMD.Crc = 0;
- rs = SD_W_CMD_R3(&SD_CMD, &R3);
-
- if(rs != SD_OK)
- {
- goto DONE;
- }
-
- if(R3.R1 != 0)
- {
- rs = SD_ERROR;
- goto DONE;
- }
-
- if(R3.Ocr & 0x80000000ul)
- {
- if(sd_ver != SD_V1X_STANDARD_CAPACITY)
- {
- if(R3.Ocr & (1<<30))
- {
- sd_ver = SD_V2X_HIGH_CAPCITY;
- }
- else
- {
- sd_ver = SD_V2X_STANDARD_CAPCITY;
- }
- }
- }
- else
- {
- rs = SD_ERROR;
- goto DONE;
- }
-
- SD_BurstSpeed();
-
- //CMD59, Turns the CRC option on or off.
- SD_CMD.Cmd = CRC_ON_OFF;
- SD_CMD.Arg = 0;
- SD_CMD.Crc = 0;
- rs = SD_W_CMD_R1(&SD_CMD, &R1);
-
- if(sd_ver < SD_V2X_HIGH_CAPCITY)
- {
- //CMD16, In case of SDSC Card, block length is set by this command.
- SD_CMD.Cmd = SET_BLOCKLEN;
- SD_CMD.Arg = SD_BLOCK_SIZE;
- SD_CMD.Crc = 0;
- rs = SD_W_CMD_R1(&SD_CMD, &R1);
- }
-
- SD_CardType = sd_ver;
- SD_InitState = 1;
-
- DONE:
- return rs;
- }
下面是类型定义
- #ifndef __SDCARD_SPI_HW_H
- #define __SDCARD_SPI_HW_H
- typedef struct _SD_CMDTypeDef
- {
- uint8_t Cmd;
- uint32_t Arg;
- uint8_t Crc;
- }SD_CMDTypeDef;
- typedef uint8_t SD_R1TypeDef;
- typedef uint8_t SD_R1bTypeDef;
- typedef struct _SD_R2TypeDef
- {
- SD_R1TypeDef R1;
- uint8_t R2;
- }SD_R2TypeDef;
- typedef struct _SD_R3TypeDef
- {
- SD_R1TypeDef R1;
- uint32_t Ocr;
- }SD_R3TypeDef;
- typedef struct _SD_R7TypeDef
- {
- SD_R1TypeDef R1;
- uint8_t CommandVersion;
- uint8_t Resv;
- uint8_t VoltageAccepted;
- uint8_t CheckPattern;
- }SD_R7TypeDef;
- /* CMD argumant mask */
- #define CMD_START (1<<6)
- #define CMD_END (1<<0)
- /* Normal Command */
- #define GO_IDLE_STATE 0 //R1
- #define SEND_OP_COND 1 //R1
- #define SWITCH_FUNC 6 //R1
- #define SEND_IF_COND 8 //R7
- #define SEND_CSD 9 //R1
- #define SEND_CID 10 //R1
- #define STOP_TRANSMISSION 12 //R1b
- #define SEND_STATUS 13 //R2
- #define SET_BLOCKLEN 16 //R1
- #define READ_SINGLE_BLOCK 17 //R1
- #define READ_MULTIPLE_BLOCK 18 //R1
- #define WRITE_BLOCK 24 //R1
- #define WRITE_MULTIPLE_BLOCK 25 //R1
- #define PROGRAM_CSD 27 //R1
- #define SET_WRITE_PROT 28 //R1b
- #define CLR_WRITE_PROT 29 //R1b
- #define SEND_WRITE_PROT 30 //R1
- #define ERASE_WR_BLK_START_ADDR 32 //R1
- #define ERASE_WR_BLK_END_ADDR 33 //R1
- #define ERASE 38 //R1b
- #define LOCK_UNLOCK 42 //R1
- #define APP_CMD 55 //R1
- #define GEN_CMD 56 //R1
- #define READ_OCR 58 //R3
- #define CRC_ON_OFF 59 //R1
- /* Application Command */
- #define SD_STATUS 13 //R2
- #define SEND_NUM_WR_BLOCKS 22 //R1
- #define SET_WR_BLK_ERASE_COUNT 23 //R1
- #define SD_SEND_OP_COND 41 //R1
- #define SET_CLR_CARD_DETECT 42 //R1
- #define SEND_SCR 51 //R1
- /* R1 Response Bit Define */
- #define R1_IDLE_STATE ((1)<<0)
- #define R1_ERASE_RESET ((1)<<1)
- #define R1_ILLEGAL_CMD ((1)<<2)
- #define R1_CRC_ERROR ((1)<<3)
- #define R1_ERASE_ERROR ((1)<<4)
- #define R1_ADDR_ERROR ((1)<<5)
- #define R1_ARG_ERROR ((1)<<6)
- /* Data Trans Token */
- #define TOKEN_START_WR_BLOCK ((uint8_t)0xFE)
- #define TOKEN_STATR_W_MULTI_BLOCK ((uint8_t)0xFC)
- #define TOKEN_STOP_W_MULTI_BLOCK ((uint8_t)0xFD)
- #endif
|