本帖最后由 andeyqi 于 2018-8-22 11:04 编辑
官方的软件包已经包含了SD卡的驱动
STM32Cube_FW_F7_V1.9.0\Drivers\BSP\STM32F769I-Discovery\stm32f769i_discovery_sd.c
现对主要的函数理解以加深对SDIO的认识,为以后的使用积累经验。
根据电路图可知硬件连接上三个数据线,一根命令传输线,一根时钟线,一根SD卡插入检测线。
- SD_HandleTypeDef uSdHandle;
- /**
- * @brief Initializes the SD card device.
- * @retval SD status
- */
- uint8_t BSP_SD_Init(void)
- {
- uint8_t sd_state = MSD_OK;
- /* PLLSAI is dedicated to LCD periph. Do not use it to get 48MHz*/
- /* uSD device interface configuration */
- uSdHandle.Instance = SDMMC2;
- uSdHandle.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
- uSdHandle.Init.ClockBypass = SDMMC_CLOCK_BYPASS_DISABLE;
- uSdHandle.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
- uSdHandle.Init.BusWide = SDMMC_BUS_WIDE_1B;
- uSdHandle.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
- uSdHandle.Init.ClockDiv = SDMMC_TRANSFER_CLK_DIV;
- /* Msp SD Detect pin initialization */
- BSP_SD_Detect_MspInit(&uSdHandle, NULL);
- if(BSP_SD_IsDetected() != SD_PRESENT) /* Check if SD card is present */
- {
- return MSD_ERROR_SD_NOT_PRESENT;
- }
- /* Msp SD initialization */
- BSP_SD_MspInit(&uSdHandle, NULL);
- /* HAL SD initialization */
- if(HAL_SD_Init(&uSdHandle) != HAL_OK)
- {
- sd_state = MSD_ERROR;
- }
- /* Configure SD Bus width */
- if(sd_state == MSD_OK)
- {
- /* Enable wide operation */
- if(HAL_SD_ConfigWideBusOperation(&uSdHandle, SDMMC_BUS_WIDE_4B) != HAL_OK)
- {
- sd_state = MSD_ERROR;
- }
- else
- {
- sd_state = MSD_OK;
- }
- }
- return sd_state;
- }
复制代码
代码初始化时设置数据位宽为SDMMC_BUS_WIDE_1B,之后又设置为SDMMC_BUS_WIDE_4B,为什么不一开始就设置成4位,而且硬件原理图上也是按照4位模式接的,后来在编程手册上找到如下描述,需要初始化完成之后再设置位宽度,但是还是没有想明白为什么这么设计。
By default SDMMC_D0 is used for data transfer. After initialization, the host can change the databus width.
BSP_SD_IsDetected()函数根据代码注释和内容可判断是,检测SD卡是否插入,检测到低电平是代表SD卡已插入。- /**
- * @brief Detects if SD card is correctly plugged in the memory slot or not.
- * @retval Returns if SD is detected or not
- */
- uint8_t BSP_SD_IsDetected(void)
- {
- __IO uint8_t status = SD_PRESENT;
- /* Check SD card detect pin */
- if (HAL_GPIO_ReadPin(SD_DETECT_GPIO_PORT, SD_DETECT_PIN) == GPIO_PIN_SET)
- {
- status = SD_NOT_PRESENT;
- }
- return status;
- }
复制代码
BSP_SD_Detect_MspInit(&uSdHandle, NULL); 配置sd卡插入检测引脚为输入上拉模式- /**
- * @brief Initializes the SD Detect pin MSP.
- * @param hsd: SD handle
- * @param Params : pointer on additional configuration parameters, can be NULL.
- * @retval None
- */
- __weak void BSP_SD_Detect_MspInit(SD_HandleTypeDef *hsd, void *Params)
- {
- GPIO_InitTypeDef gpio_init_structure;
- SD_DETECT_GPIO_CLK_ENABLE();
- /* GPIO configuration in input for uSD_Detect signal */
- gpio_init_structure.Pin = SD_DETECT_PIN;
- gpio_init_structure.Mode = GPIO_MODE_INPUT;
- gpio_init_structure.Pull = GPIO_PULLUP;
- gpio_init_structure.Speed = GPIO_SPEED_HIGH;
- HAL_GPIO_Init(SD_DETECT_GPIO_PORT, &gpio_init_structure);
- }
复制代码- /**
- * @brief Initializes the SD Card.
- * @param hsd Pointer to SD handle
- * @note This function initializes the SD card. It could be used when a card
- re-initialization is needed.
- * @retval HAL status
- */
- HAL_StatusTypeDef HAL_SD_InitCard(SD_HandleTypeDef *hsd)
- {
- uint32_t errorstate = HAL_SD_ERROR_NONE;
- SD_InitTypeDef Init;
-
- /* Default SDMMC peripheral configuration for SD card initialization */
- Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
- Init.ClockBypass = SDMMC_CLOCK_BYPASS_DISABLE;
- Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
- Init.BusWide = SDMMC_BUS_WIDE_1B;
- Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
- Init.ClockDiv = SDMMC_INIT_CLK_DIV;
- /* Initialize SDMMC peripheral interface with default configuration */
- SDMMC_Init(hsd->Instance, Init);
- /* Disable SDMMC Clock */
- __HAL_SD_DISABLE(hsd);
-
- /* Set Power State to ON */
- SDMMC_PowerState_ON(hsd->Instance);
-
- /* Enable SDMMC Clock */
- __HAL_SD_ENABLE(hsd);
-
- /* Required power up waiting time before starting the SD initialization sequence */
- HAL_Delay(2);
-
- /* Identify card operating voltage */
- errorstate = SD_PowerON(hsd);
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- hsd->State = HAL_SD_STATE_READY;
- hsd->ErrorCode |= errorstate;
- return HAL_ERROR;
- }
- /* Card initialization */
- errorstate = SD_InitCard(hsd);
- if(errorstate != HAL_SD_ERROR_NONE)
- {
- hsd->State = HAL_SD_STATE_READY;
- hsd->ErrorCode |= errorstate;
- return HAL_ERROR;
- }
- return HAL_OK;
- }
复制代码
|