SD_Error SD_Init(void)
{
GPIO_InitType GPIO_InitStructure = {0};
GPIO_StructInit(&GPIO_InitStructure);
u16 clkdiv = 0;
SD_Error errorstatus = SD_OK;
/*!< GPIOC and GPIOD Periph clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOC | RCC_APB2PERIPH_GPIOD, ENABLE);
/*!< SDIO clock enable */
RCC_AHBPeriphClockCmd(RCC_AHBPERIPH_SDIO1, ENABLE);
/*!< Configure PC.08, PC.09, PC.10, PC.11, PC.12 pin: D0, D1, D2, D3, CLK pin */
GPIO_InitStructure.GPIO_Pins = GPIO_Pins_8 | GPIO_Pins_9 | GPIO_Pins_10 | GPIO_Pins_11 | GPIO_Pins_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/*!< Configure PD.02 CMD line */
GPIO_InitStructure.GPIO_Pins = GPIO_Pins_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* Reset SDIO */
SDIO_Reset(SDIO1);
errorstatus = SD_PowerON(); //上电
if(errorstatus == SD_OK)
{
errorstatus = SD_InitializeCards(); //初始化SD卡
}
if(errorstatus == SD_OK)
{
errorstatus = SD_GetCardInfo(&SDCardInfo); //获取SD卡信息
}
if(SDIO_MULTIMEDIA_CARD == CardType && SDCardInfo.SD_csd.SysSpecVersion >= 4)
{
CardType = SDIO_HIGH_SPEED_MULTIMEDIA_CARD;
}
if(errorstatus == SD_OK)
{
errorstatus = SD_SelectDeselect((u32)(SDCardInfo.RCA << 16)); //选中SD卡
}
if(errorstatus == SD_OK && ((SDIO_STD_CAPACITY_SD_CARD_V1_1 == CardType) || (SDIO_STD_CAPACITY_SD_CARD_V2_0 == CardType) || (SDIO_SECURE_DIGITAL_IO_COMBO_CARD == CardType) || (SDIO_HIGH_CAPACITY_SD_CARD == CardType)))
{
errorstatus = FindSCR();
}
if(errorstatus == SD_OK)
{
errorstatus = ChangeSpeed(0); //Set to Normal Speed
}
if((errorstatus == SD_OK) || (SDIO_MULTIMEDIA_CARD == CardType))
{
if(SDCardInfo.CardType == SDIO_STD_CAPACITY_SD_CARD_V1_1 || SDCardInfo.CardType == SDIO_STD_CAPACITY_SD_CARD_V2_0)
{
clkdiv = SystemCoreClock / 6000000; //设置SD卡时钟为6MHz
if (clkdiv > 2)
{
clkdiv -= 2;
}
}
else
{
clkdiv = SystemCoreClock / 6000000; //设置SD卡时钟为6MHz
if (clkdiv > 2)
{
clkdiv -= 2;
}
}
SDIO_Clock_Set(clkdiv); //设置SDIO Clock分频系数
errorstatus = SD_SetDeviceMode(SD_POLLING_MODE); //设置为轮询模式
}
return errorstatus;
}
|