使用STM32CUBEMX生成USB Mass Storage代码,通过SDIO读写TF卡

首先配置USB为Mass Storage Class,配置SDIO为 SD 4 bits wide bus。

使用STM32CUBEMX生成USB Mass Storage代码,通过SDIO读写TF卡_第1张图片


这里我使用了FreeRTOS和FATFS,用不用和本例无关。有一个坑,就是SDIO的配置界面,MX软件建议不设分频,但这里需要慎重,SDIOCLK的分频要按照自己硬件板子的情况设置,我用的某型号开发板,如果用最高频率,会出现TF卡读写不稳定,设置一下分频才好。

使用STM32CUBEMX生成USB Mass Storage代码,通过SDIO读写TF卡_第2张图片

设置完毕,生成代码和工程。打开工程,在usbd_storage_if.c文件里配置TF卡(SD卡)的基本IO操作。

在文件开头加入

#define BLOCK_SIZE                       512

extern SD_HandleTypeDef hsd;
extern HAL_SD_CardInfoTypedef SDCardInfo;

注意!上面这三行就算写到USER CODE BEGIN... 和USER CODE END...的保护区里MX重新生成貌似也会被自动抹掉。

填充如下函数

int8_t STORAGE_GetCapacity_FS (uint8_t lun, uint32_t *block_num, uint16_t *block_size)
{
  /* USER CODE BEGIN 3 */   
  HAL_SD_Get_CardInfo(&hsd, &SDCardInfo);
  *block_num  = SDCardInfo.CardCapacity / BLOCK_SIZE;
  *block_size = BLOCK_SIZE;
  return (USBD_OK);
  /* USER CODE END 3 */ 
}

int8_t STORAGE_Read_FS (uint8_t lun, 
                        uint8_t *buf, 
                        uint32_t blk_addr,                       
                        uint16_t blk_len)
{
  /* USER CODE BEGIN 6 */
  HAL_SD_ReadBlocks(&hsd, (uint32_t*)buf, (uint64_t)(blk_addr * BLOCK_SIZE), BLOCK_SIZE, blk_len);
  return (USBD_OK);
  /* USER CODE END 6 */ 
}

int8_t STORAGE_Write_FS (uint8_t lun, 
                         uint8_t *buf, 
                         uint32_t blk_addr,
                         uint16_t blk_len)
{
  /* USER CODE BEGIN 7 */ 
  HAL_SD_WriteBlocks(&hsd, (uint32_t*)buf, (uint64_t)(blk_addr * BLOCK_SIZE), BLOCK_SIZE, blk_len);
  return (USBD_OK);
  /* USER CODE END 7 */ 
}


还有一个需要注意的,就是生成的代码中sdio.c文件里有个问题需要手工改

void MX_SDIO_SD_Init(void)
{

  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_1B;
  hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_ENABLE;
  hsd.Init.ClockDiv = 2;

}

这里的

hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_ENABLE;
这句话生成出来的时候是disable的(然而在MX的图形界面中并没有发现怎么配置这段话),要人工改成enable,否则读写会不稳定。另,每一次MX重新生成,这里的enable又会被自动的改回去,老坑爹了。

到此,所有配置完成。

最后说下MX的另一个bug,就是使用FreeRTOS的时候HAL_Delay函数无法使用,最后发现原因是 stm32f1xx_it.c 文件中的SysTick_Handler
只加入了osSystickHandler()没加入HAL_IncTick(),把后者加入就好了。

MX的bug比教程还多。。。ST的攻城狮们可长点心吧。。。

你可能感兴趣的:(使用STM32CUBEMX生成USB Mass Storage代码,通过SDIO读写TF卡)