本帖最后由 z32437089 于 2014-10-31 15:38 编辑
使用SPI2驱动SD卡,发送CMD0命令,SD卡没任何反应,就一直卡到这里了,换V1和V2的卡都没反应,MISO引脚永远是低电平.
这个是SD卡硬件连接图
CDMO对应MCU_MOSI第28个腿PB15,CDMI对应MCU_MISO第27个腿PB14
void SD_SendCmd ( /* Return value: R1 resp (bit7==1:Failed to send) */
BYTE cmd, /* Command index */
DWORD arg, /* Argument */
BYTE crc
)
{
// BYTE n, res;
/* Send command packet */
xchg_spi(0x40 | cmd); /* Start + command index */
xchg_spi((BYTE)(arg >> 24)); /* Argument[31..24] */
xchg_spi((BYTE)(arg >> 16)); /* Argument[23..16] */
xchg_spi((BYTE)(arg >> 8)); /* Argument[15..8] */
xchg_spi((BYTE)arg); /* Argument[7..0] */
xchg_spi(crc);}
SD_Error SD_GetResponse(uint8_t Response)
{
uint32_t Count = 0xFFF;
/*!< Check if response is got or a timeout is happen */
while ((xchg_spi(0xFF) != Response) && Count)
{
Count--;
}
if (Count == 0)
{
/*!< After time out */
return SD_RESPONSE_FAILURE;
}
else
{
/*!< Right response got */
return SD_RESPONSE_NO_ERROR;
}
}
SD_Error SD_Init (void)
{
uint32_t i = 0;
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_0); //SCK
GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_0); //MI
GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_0); //MO
/* SPI CS PIN Configuration --------------------------------------------------*/
/* Configure I/O for Flash Chip select */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* SPI configuration */
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPIx_SD_BAUDRATE_SLOW; // 48000kHz/128=375kHz < 400kHz
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI2, &SPI_InitStructure);
SPI_RxFIFOThresholdConfig(SPI2, SPI_RxFIFOThreshold_QF);
SPI_CalculateCRC(SPI2, DISABLE);
SPI_Cmd(SPI2, ENABLE); /* Enable SPI function */
CS_HIGH(); /* Set CS# high */
/*!< Send dummy byte 0xFF, 10 times with CS high */
/*!< Rise CS and MOSI for 80 clocks cycles */
for (i = 0; i < 10; i++)
{
xchg_spi(0xff);
}
/*-------Put SD in SPI mode----- 设置SD为SPI模式 -----*/
/*!< SD initialized and set to SPI mode properly */
return (SD_GoIdleState());
}
SD_Error SD_GoIdleState(void)
{
/*!< SD chip select low */
CS_LOW();
/*!< Send CMD0 (SD_CMD_GO_IDLE_STATE) to put SD in SPI mode */
do {SD_SendCmd(SD_CMD_GO_IDLE_STATE, 0, 0x95);}
while(SD_GetResponse(SD_IN_IDLE_STATE));
led1_on;while(1);//can't reach here,led1 remains off
/*----------Activates the card initialization process-----------*/
do
{
/*!< SD chip select high */
CS_HIGH();
/*!< Send Dummy byte 0xFF */
xchg_spi(0xff);
/*!< SD chip select low */
CS_LOW();
/*!< Send CMD1 (Activates the card process) until response equal to 0x0 */
SD_SendCmd(SD_CMD_SEND_OP_COND, 0, 0xFF);
/*!< Wait for no error Response (R1 Format) equal to 0x00 */
}
while (SD_GetResponse(SD_RESPONSE_NO_ERROR));
/*!< SD chip select high */
CS_HIGH();
/*!< Send dummy byte 0xFF */
xchg_spi(0xff);
return SD_RESPONSE_NO_ERROR;
}
|