OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 953|回复: 1

STM32CUBEIDE USB Slave 读取SD卡

[复制链接]

53

主题

567

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2099
金钱
2099
注册时间
2017-2-11
在线时间
306 小时
发表于 2020-10-19 20:23:33 | 显示全部楼层 |阅读模式
本帖最后由 jiangyy 于 2021-3-25 13:30 编辑

   使用STM32CUBEIDE软件,生成USB Slave 读取SD卡,直接用该软件烧录到STM32F407中,可以实现热插拔功能。有些细节要注意:
   第一,基于HAL库,对于SDIO时钟的配置,貌似不能0分频(否则SD卡读写文件错误,也无法识别SD卡),必须2分频,代码如下:

  1. /**
  2.   ******************************************************************************
  3.   * File Name          : SDIO.c
  4.   * Description        : This file provides code for the configuration
  5.   *                      of the SDIO instances.
  6.   ******************************************************************************
  7.   * @attention
  8.   *
  9.   * <h2><center>&#169; Copyright (c) 2020 STMicroelectronics.
  10.   * All rights reserved.</center></h2>
  11.   *
  12.   * This software component is licensed by ST under Ultimate Liberty license
  13.   * SLA0044, the "License"; You may not use this file except in compliance with
  14.   * the License. You may obtain a copy of the License at:
  15.   *                             www.st.com/SLA0044
  16.   *
  17.   ******************************************************************************
  18.   */

  19. /* Includes ------------------------------------------------------------------*/
  20. #include "sdio.h"

  21. /* USER CODE BEGIN 0 */
  22. HAL_SD_CardInfoTypeDef  SDCardInfo;         //SD卡信息结构体
  23. /* USER CODE END 0 */

  24. SD_HandleTypeDef hsd;

  25. /* SDIO init function */

  26. void MX_SDIO_SD_Init(void)
  27. {

  28.   hsd.Instance = SDIO;
  29.   hsd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
  30.   hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
  31.   hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
  32.   hsd.Init.BusWide = SDIO_BUS_WIDE_1B;
  33.   hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_ENABLE;
  34.   hsd.Init.ClockDiv = 2;/*这里必须2分频,否则高于2分频SD卡无法读取*/

  35. }

  36. void HAL_SD_MspInit(SD_HandleTypeDef* sdHandle)
  37. {

  38.   GPIO_InitTypeDef GPIO_InitStruct = {0};
  39.   if(sdHandle->Instance==SDIO)
  40.   {
  41.   /* USER CODE BEGIN SDIO_MspInit 0 */

  42.   /* USER CODE END SDIO_MspInit 0 */
  43.     /* SDIO clock enable */
  44.     __HAL_RCC_SDIO_CLK_ENABLE();

  45.     __HAL_RCC_GPIOC_CLK_ENABLE();
  46.     __HAL_RCC_GPIOD_CLK_ENABLE();
  47.     /**SDIO GPIO Configuration
  48.     PC8     ------> SDIO_D0
  49.     PC9     ------> SDIO_D1
  50.     PC10     ------> SDIO_D2
  51.     PC11     ------> SDIO_D3
  52.     PC12     ------> SDIO_CK
  53.     PD2     ------> SDIO_CMD
  54.     */
  55.     GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
  56.                           |GPIO_PIN_12;
  57.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  58.     GPIO_InitStruct.Pull = GPIO_PULLUP;
  59.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  60.     GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
  61.     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  62.     GPIO_InitStruct.Pin = GPIO_PIN_2;
  63.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  64.     GPIO_InitStruct.Pull = GPIO_PULLUP;
  65.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  66.     GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
  67.     HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  68.   /* USER CODE BEGIN SDIO_MspInit 1 */

  69.   /* USER CODE END SDIO_MspInit 1 */
  70.   }
  71. }

  72. void HAL_SD_MspDeInit(SD_HandleTypeDef* sdHandle)
  73. {

  74.   if(sdHandle->Instance==SDIO)
  75.   {
  76.   /* USER CODE BEGIN SDIO_MspDeInit 0 */

  77.   /* USER CODE END SDIO_MspDeInit 0 */
  78.     /* Peripheral clock disable */
  79.     __HAL_RCC_SDIO_CLK_DISABLE();

  80.     /**SDIO GPIO Configuration
  81.     PC8     ------> SDIO_D0
  82.     PC9     ------> SDIO_D1
  83.     PC10     ------> SDIO_D2
  84.     PC11     ------> SDIO_D3
  85.     PC12     ------> SDIO_CK
  86.     PD2     ------> SDIO_CMD
  87.     */
  88.     HAL_GPIO_DeInit(GPIOC, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
  89.                           |GPIO_PIN_12);

  90.     HAL_GPIO_DeInit(GPIOD, GPIO_PIN_2);

  91.   /* USER CODE BEGIN SDIO_MspDeInit 1 */

  92.   /* USER CODE END SDIO_MspDeInit 1 */
  93.   }
  94. }

  95. /* USER CODE BEGIN 1 */

  96. /* USER CODE END 1 */

  97. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
复制代码


   第二,修改usbd_storage_if.c文件,这里好多需要用户自定义,代码 usbd_storage_if.c 更改如下:
  1. /* USER CODE BEGIN Header */
  2. /**
  3.   ******************************************************************************
  4.   * [url=home.php?mod=space&uid=175224]@file[/url]           : usbd_storage_if.c
  5.   * @version        : v1.0_Cube
  6.   * @brief          : Memory management layer.
  7.   ******************************************************************************
  8.   * @attention
  9.   *
  10.   * <h2><center>&#169; Copyright (c) 2020 STMicroelectronics.
  11.   * All rights reserved.</center></h2>
  12.   *
  13.   * This software component is licensed by ST under Ultimate Liberty license
  14.   * SLA0044, the "License"; You may not use this file except in compliance with
  15.   * the License. You may obtain a copy of the License at:
  16.   *                             www.st.com/SLA0044
  17.   *
  18.   ******************************************************************************
  19.   */
  20. /* USER CODE END Header */

  21. /* Includes ------------------------------------------------------------------*/
  22. #include "usbd_storage_if.h"

  23. /* USER CODE BEGIN INCLUDE */

  24. /* USER CODE END INCLUDE */

  25. /* Private typedef -----------------------------------------------------------*/
  26. /* Private define ------------------------------------------------------------*/
  27. /* Private macro -------------------------------------------------------------*/

  28. /* USER CODE BEGIN PV */
  29. /* Private variables ---------------------------------------------------------*/

  30. /* USER CODE END PV */

  31. /** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
  32.   * @brief Usb device.
  33.   * @{
  34.   */

  35. /** @defgroup USBD_STORAGE
  36.   * @brief Usb mass storage device module
  37.   * @{
  38.   */

  39. /** @defgroup USBD_STORAGE_Private_TypesDefinitions
  40.   * @brief Private types.
  41.   * @{
  42.   */

  43. /* USER CODE BEGIN PRIVATE_TYPES */

  44. /* USER CODE END PRIVATE_TYPES */

  45. /**
  46.   * @}
  47.   */

  48. /** @defgroup USBD_STORAGE_Private_Defines
  49.   * @brief Private defines.
  50.   * @{
  51.   */

  52. #define STORAGE_LUN_NBR                  1
  53. #define STORAGE_BLK_NBR                  0x10000
  54. #define STORAGE_BLK_SIZ                  0x200

  55. /* USER CODE BEGIN PRIVATE_DEFINES */

  56. /* USER CODE END PRIVATE_DEFINES */

  57. /**
  58.   * @}
  59.   */

  60. /** @defgroup USBD_STORAGE_Private_Macros
  61.   * @brief Private macros.
  62.   * @{
  63.   */

  64. /* USER CODE BEGIN PRIVATE_MACRO */

  65. /* USER CODE END PRIVATE_MACRO */

  66. /**
  67.   * @}
  68.   */

  69. /** @defgroup USBD_STORAGE_Private_Variables
  70.   * @brief Private variables.
  71.   * @{
  72.   */

  73. /* USER CODE BEGIN INQUIRY_DATA_FS */
  74. /** USB Mass storage Standard Inquiry Data. */
  75. const int8_t STORAGE_Inquirydata_FS[] = {/* 36 */

  76.   /* LUN 0 */
  77.   0x00,
  78.   0x80,
  79.   0x02,
  80.   0x02,
  81.   (STANDARD_INQUIRY_DATA_LEN - 5),
  82.   0x00,
  83.   0x00,
  84.   0x00,
  85.   'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', /* Manufacturer : 8 bytes */
  86.   'P', 'r', 'o', 'd', 'u', 'c', 't', ' ', /* Product      : 16 Bytes */
  87.   ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
  88.   '0', '.', '0' ,'1'                      /* Version      : 4 Bytes */
  89. };
  90. /* USER CODE END INQUIRY_DATA_FS */

  91. /* USER CODE BEGIN PRIVATE_VARIABLES */

  92. /* USER CODE END PRIVATE_VARIABLES */

  93. /**
  94.   * @}
  95.   */

  96. /** @defgroup USBD_STORAGE_Exported_Variables
  97.   * @brief Public variables.
  98.   * @{
  99.   */

  100. extern USBD_HandleTypeDef hUsbDeviceFS;

  101. /* USER CODE BEGIN EXPORTED_VARIABLES */

  102. /* USER CODE END EXPORTED_VARIABLES */

  103. /**
  104.   * @}
  105.   */

  106. /** @defgroup USBD_STORAGE_Private_FunctionPrototypes
  107.   * @brief Private functions declaration.
  108.   * @{
  109.   */

  110. static int8_t STORAGE_Init_FS(uint8_t lun);
  111. static int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num, uint16_t *block_size);
  112. static int8_t STORAGE_IsReady_FS(uint8_t lun);
  113. static int8_t STORAGE_IsWriteProtected_FS(uint8_t lun);
  114. static int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
  115. static int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
  116. static int8_t STORAGE_GetMaxLun_FS(void);

  117. /* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION */

  118. /* USER CODE END PRIVATE_FUNCTIONS_DECLARATION */

  119. /**
  120.   * @}
  121.   */

  122. USBD_StorageTypeDef USBD_Storage_Interface_fops_FS =
  123. {
  124.   STORAGE_Init_FS,
  125.   STORAGE_GetCapacity_FS,
  126.   STORAGE_IsReady_FS,
  127.   STORAGE_IsWriteProtected_FS,
  128.   STORAGE_Read_FS,
  129.   STORAGE_Write_FS,
  130.   STORAGE_GetMaxLun_FS,
  131.   (int8_t *)STORAGE_Inquirydata_FS
  132. };

  133. /* Private functions ---------------------------------------------------------*/
  134. /**
  135.   * @brief  Initializes over USB FS IP
  136.   * [url=home.php?mod=space&uid=271674]@param[/url]  lun:
  137.   * @retval USBD_OK if all operations are OK else USBD_FAIL
  138.   */
  139. int8_t STORAGE_Init_FS(uint8_t lun)
  140. {
  141.   /* USER CODE BEGIN 2 */
  142.   return (USBD_OK);
  143.   /* USER CODE END 2 */
  144. }

  145. /**
  146.   * @brief  .
  147.   * @param  lun: .
  148.   * @param  block_num: .
  149.   * @param  block_size: .
  150.   * @retval USBD_OK if all operations are OK else USBD_FAIL
  151.   */
  152. int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num, uint16_t *block_size)
  153. {
  154.   /* USER CODE BEGIN 3 */

  155.   HAL_SD_CardInfoTypeDef info;
  156.   int8_t ret = USBD_FAIL;

  157.   if(BSP_SD_IsDetected() != SD_NOT_PRESENT)
  158.   {
  159.                 BSP_SD_GetCardInfo(&info);

  160.                 *block_size = 512;
  161.                 *block_num =  ((uint64_t)info.LogBlockNbr*(uint64_t)info.LogBlockSize)/512;
  162.                 ret = USBD_OK;
  163.   }
  164.   return ret;
  165.   /* USER CODE END 3 */
  166. }

  167. /**
  168.   * @brief  .
  169.   * @param  lun: .
  170.   * @retval USBD_OK if all operations are OK else USBD_FAIL
  171.   */
  172. int8_t STORAGE_IsReady_FS(uint8_t lun)
  173. {
  174.   /* USER CODE BEGIN 4 */
  175.         static int8_t prev_status = 0;
  176.         int8_t ret = -1;

  177.         if(BSP_SD_IsDetected() != SD_NOT_PRESENT)
  178.         {
  179.                 if(prev_status < 0)
  180.                 {
  181.                         BSP_SD_Init();
  182.                         prev_status = 0;

  183.                 }
  184.                 if(BSP_SD_GetCardState() == SD_TRANSFER_OK)
  185.                 {
  186.                         ret = USBD_OK;
  187.                 }
  188.         }
  189.         else if(prev_status == 0)
  190.         {
  191.                 prev_status = -1;
  192.         }

  193.         return ret;
  194.   /* USER CODE END 4 */
  195. }

  196. /**
  197.   * @brief  .
  198.   * @param  lun: .
  199.   * @retval USBD_OK if all operations are OK else USBD_FAIL
  200.   */
  201. int8_t STORAGE_IsWriteProtected_FS(uint8_t lun)
  202. {
  203.   /* USER CODE BEGIN 5 */
  204.   return (USBD_OK);
  205.   /* USER CODE END 5 */
  206. }

  207. /**
  208.   * @brief  .
  209.   * @param  lun: .
  210.   * @retval USBD_OK if all operations are OK else USBD_FAIL
  211.   */
  212. int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
  213. {
  214.   /* USER CODE BEGIN 6 */

  215.         #ifdef SD_CARD_READ
  216.         int8_t ret = -1;
  217.         uint32_t timeout = 100000;

  218.         BSP_SD_ReadBlocks((uint32_t *)buf, blk_addr, blk_len, SD_DATATIMEOUT);
  219.         while(BSP_SD_GetCardState() != SD_TRANSFER_OK)
  220.         {
  221.                 if (timeout-- == 0)
  222.                 {
  223.                         return ret;
  224.                 }
  225.         }
  226.         ret = USBD_OK;

  227.         return ret;
  228.         #endif
  229.         #ifdef SD_CARD_READ_DMA
  230.         int8_t ret = USBD_FAIL;

  231.         if( HAL_SD_ReadBlocks_DMA(&hsd, buf, blk_addr, blk_len) == HAL_OK )
  232.         {
  233.                 ret = USBD_OK;
  234.         }

  235.         if( USBD_OK == ret )
  236.         {
  237.                 while(HAL_SD_GetState(&hsd) == HAL_SD_STATE_BUSY){};

  238.                 while( HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER ){};
  239.         }

  240.         return ret;
  241.         #endif

  242.         //BSP_SD_ReadBlocks_DMA((uint32_t *)buf, blk_addr, blk_len);
  243.         // return (USBD_OK);
  244.   /* USER CODE END 6 */
  245. }

  246. /**
  247.   * @brief  .
  248.   * @param  lun: .
  249.   * @retval USBD_OK if all operations are OK else USBD_FAIL
  250.   */
  251. int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
  252. {
  253.   /* USER CODE BEGIN 7 */
  254.         #ifdef SD_CARD_WRITE
  255.         int8_t ret = -1;
  256.         uint32_t timeout = 100000;

  257.         BSP_SD_WriteBlocks((uint32_t *)buf, blk_addr, blk_len, SD_DATATIMEOUT);
  258.         while(BSP_SD_GetCardState() != SD_TRANSFER_OK)
  259.         {
  260.         if (timeout-- == 0)
  261.         {
  262.           return ret;
  263.         }
  264.         }
  265.         ret = USBD_OK;

  266.         return ret;
  267.         #endif
  268.         #ifdef SD_CARD_WRITE_DMA
  269.         int8_t ret = USBD_FAIL;

  270.         if( HAL_SD_WriteBlocks_DMA(&hsd, buf, blk_addr, blk_len) == HAL_OK )
  271.         {
  272.                 ret = USBD_OK;
  273.         }

  274.         if( USBD_OK == ret )
  275.         {
  276.                 while(HAL_SD_GetState(&hsd) == HAL_SD_STATE_BUSY){};

  277.                 while( HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER ){};
  278.         }

  279.         return ret;
  280.         #endif
  281.   /* USER CODE END 7 */
  282. }

  283. /**
  284.   * @brief  .
  285.   * @param  None
  286.   * @retval .
  287.   */
  288. int8_t STORAGE_GetMaxLun_FS(void)
  289. {
  290.   /* USER CODE BEGIN 8 */
  291.   return (STORAGE_LUN_NBR - 1);
  292.   /* USER CODE END 8 */
  293. }

  294. /* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */

  295. /* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */

  296. /**
  297.   * @}
  298.   */

  299. /**
  300.   * @}
  301.   */

  302. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
复制代码


头文件 usbd_storage_if.h
  1. /* USER CODE BEGIN Header */
  2. /**
  3.   ******************************************************************************
  4.   * @file           : usbd_storage_if.h
  5.   * @version        : v1.0_Cube
  6.   * @brief          : Header for usbd_storage_if.c file.
  7.   ******************************************************************************
  8.   * @attention
  9.   *
  10.   * <h2><center>&#169; Copyright (c) 2020 STMicroelectronics.
  11.   * All rights reserved.</center></h2>
  12.   *
  13.   * This software component is licensed by ST under Ultimate Liberty license
  14.   * SLA0044, the "License"; You may not use this file except in compliance with
  15.   * the License. You may obtain a copy of the License at:
  16.   *                             www.st.com/SLA0044
  17.   *
  18.   ******************************************************************************
  19.   */
  20. /* USER CODE END Header */

  21. /* Define to prevent recursive inclusion -------------------------------------*/
  22. #ifndef __USBD_STORAGE_IF_H__
  23. #define __USBD_STORAGE_IF_H__

  24. #ifdef __cplusplus
  25. extern "C" {
  26. #endif

  27. /* Includes ------------------------------------------------------------------*/
  28. #include "usbd_msc.h"

  29. /* USER CODE BEGIN INCLUDE */
  30. #include "bsp_driver_sd.h"
  31. /* USER CODE END INCLUDE */

  32. /** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
  33.   * @brief For Usb device.
  34.   * @{
  35.   */

  36. /** @defgroup USBD_STORAGE USBD_STORAGE
  37.   * @brief Header file for the usb_storage_if.c file
  38.   * @{
  39.   */

  40. /** @defgroup USBD_STORAGE_Exported_Defines USBD_STORAGE_Exported_Defines
  41.   * @brief Defines.
  42.   * @{
  43.   */

  44. /* USER CODE BEGIN EXPORTED_DEFINES */
  45. #define SD_CARD_READ
  46. #define SD_CARD_WRITE
  47. /* USER CODE END EXPORTED_DEFINES */

  48. /**
  49.   * @}
  50.   */

  51. /** @defgroup USBD_STORAGE_Exported_Types USBD_STORAGE_Exported_Types
  52.   * @brief Types.
  53.   * @{
  54.   */

  55. /* USER CODE BEGIN EXPORTED_TYPES */

  56. /* USER CODE END EXPORTED_TYPES */

  57. /**
  58.   * @}
  59.   */

  60. /** @defgroup USBD_STORAGE_Exported_Macros USBD_STORAGE_Exported_Macros
  61.   * @brief Aliases.
  62.   * @{
  63.   */

  64. /* USER CODE BEGIN EXPORTED_MACRO */

  65. /* USER CODE END EXPORTED_MACRO */

  66. /**
  67.   * @}
  68.   */

  69. /** @defgroup USBD_STORAGE_Exported_Variables USBD_STORAGE_Exported_Variables
  70.   * @brief Public variables.
  71.   * @{
  72.   */

  73. /** STORAGE Interface callback. */
  74. extern USBD_StorageTypeDef USBD_Storage_Interface_fops_FS;

  75. /* USER CODE BEGIN EXPORTED_VARIABLES */

  76. /* USER CODE END EXPORTED_VARIABLES */

  77. /**
  78.   * @}
  79.   */

  80. /** @defgroup USBD_STORAGE_Exported_FunctionsPrototype USBD_STORAGE_Exported_FunctionsPrototype
  81.   * @brief Public functions declaration.
  82.   * @{
  83.   */

  84. /* USER CODE BEGIN EXPORTED_FUNCTIONS */

  85. /* USER CODE END EXPORTED_FUNCTIONS */

  86. /**
  87.   * @}
  88.   */

  89. /**
  90.   * @}
  91.   */

  92. /**
  93.   * @}
  94.   */

  95. #ifdef __cplusplus
  96. }
  97. #endif

  98. #endif /* __USBD_STORAGE_IF_H__ */

  99. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
复制代码


我这里没有使用高速USB,只是普通的USB,速度最高只能达到 355KB/秒,而且很稳定,但是没有达到预期的1MKB/秒,测试发现与SDIO时钟分频有关,但是无法提速上去,贴友有没有办法提速上去???
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

53

主题

567

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2099
金钱
2099
注册时间
2017-2-11
在线时间
306 小时
 楼主| 发表于 2020-10-19 20:31:28 来自手机 | 显示全部楼层

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-4-29 22:14

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表