现象:SDIO读取TF卡,1bit模式正常(一切操作都正常),4bit模式无法读取:
比如在使用函数f_opendir(&DirInf, SDPath)、f_open(&SDFile, path, FA_CREATE_ALWAYS | FA_WRITE)函数时会出现错误:FR_NOT_READY。
调试环境与设置
1. 调试硬件:stm32f407 + sd卡 + usb 虚拟串口,开发环境:stm32cubeide (version1.15.0):
STM32CubeMX V6.12.0 + STM32Cube FW_F4 V1.28.0;
2. sd卡的配置:
都是按照网上资料(见上一篇:sd卡stm32f407移植调试记录-CSDN博客):利用ide中的配置工具进行配置:
选择SD 4bits Wide bus,进行....配置(可以网上搜);
解决方法:
1. 按照SD 4bits Wide bus进行设置,如上面,上面的管脚包括时钟选择上拉(估计不上拉也行,外部硬件已经上拉).....,最后生产代码;
2. 在代码中加了一句:
/* USER CODE BEGIN SDIO_Init 2 */
hsd.Init.BusWide = SDIO_BUS_WIDE_1B;
void MX_SDIO_SD_Init(void)
{
/* USER CODE BEGIN SDIO_Init 0 */
/* USER CODE END SDIO_Init 0 */
/* USER CODE BEGIN SDIO_Init 1 */
/* USER CODE END SDIO_Init 1 */
hsd.Instance = SDIO;
hsd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
hsd.Init.BusWide = SDIO_BUS_WIDE_4B;
hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_ENABLE;
hsd.Init.ClockDiv = 0;
/* USER CODE BEGIN SDIO_Init 2 */
hsd.Init.BusWide = SDIO_BUS_WIDE_1B;
/* USER CODE END SDIO_Init 2 */
}
编译,下载,验证可以。
3. 证明实际的运行不是 SDIO_BUS_WIDE_1B。
尽管改为: hsd.Init.BusWide = SDIO_BUS_WIDE_1B,但是sd卡的执行不是1B,因为若是把sdio.c文件中的void HAL_SD_MspInit(SD_HandleTypeDef* sdHandle)函数中的:SDIO_D2,SDIO_D3,屏蔽掉,执行就不正常。
我们知道若是模式为SDIO_BUS_WIDE_1B,只需下面的io参与:
/**SDIO GPIO Configuration
PC8 ------> SDIO_D0
PC12 ------> SDIO_CK
PD2 ------> SDIO_CMD
*/
若是SDIO_BUS_WIDE_4B,参与的io为:
/**SDIO GPIO Configuration
PC8 ------> SDIO_D0
PC9 ------> SDIO_D1
PC10 ------> SDIO_D2
PC11 ------> SDIO_D3
PC12 ------> SDIO_CK
PD2 ------> SDIO_CMD
*/
把红色io的设置屏蔽掉,sd运行不成功。
结论:
STM32CubeMX V6.12.0 + STM32Cube FW_F4 V1.28.0 环境中sd卡的bug stm还没有完美的消除掉:能用,但是令人费解,有坑。
stm32cubemx生成的代码sd卡运行流程
此过程有一个疑问全局对象disk,与对象hsd是什么关系?拆:
1. 没有包含关于,在定义中没有disk的痕迹;
typedef struct __SD_HandleTypeDef
{
SD_TypeDef *Instance; /*!< SD registers base address */
SD_InitTypeDef Init; /*!< SD required parameters */
HAL_LockTypeDef Lock; /*!< SD locking object */
uint32_t *pTxBuffPtr; /*!< Pointer to SD Tx transfer Buffer */
uint32_t TxXferSize; /*!< SD Tx Transfer size */
uint32_t *pRxBuffPtr; /*!< Pointer to SD Rx transfer Buffer */
uint32_t RxXferSize; /*!< SD Rx Transfer size */
__IO uint32_t Context; /*!< SD transfer context */
__IO HAL_SD_StateTypeDef State; /*!< SD card State */
__IO uint32_t ErrorCode; /*!< SD Card Error codes */
DMA_HandleTypeDef *hdmarx; /*!< SD Rx DMA handle parameters */
DMA_HandleTypeDef *hdmatx; /*!< SD Tx DMA handle parameters */
HAL_SD_CardInfoTypeDef SdCard; /*!< SD Card information */
uint32_t CSD[4]; /*!< SD card specific data table */
uint32_t CID[4]; /*!< SD card identification number table */
#if (USE_HAL_SD_REGISTER_CALLBACKS == 1)
void (* TxCpltCallback) (struct __SD_HandleTypeDef *hsd);
void (* RxCpltCallback) (struct __SD_HandleTypeDef *hsd);
void (* ErrorCallback) (struct __SD_HandleTypeDef *hsd);
void (* AbortCpltCallback) (struct __SD_HandleTypeDef *hsd);
void (* MspInitCallback) (struct __SD_HandleTypeDef *hsd);
void (* MspDeInitCallback) (struct __SD_HandleTypeDef *hsd);
#endif
}SD_HandleTypeDef;
2. 结构体定义与实质化都在stm32f4××_hal_sd.c(.h)中,故是为了支持其文件中的函数。