打印
[STM32H7]

【STM32H745I-DISCO试用】5、eMMC+USB MSC=U盘

[复制链接]
109|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 sujingliang 于 2025-1-23 19:04 编辑

本文记录将STM32H745I-DISCO配置为USB DEVICE - MSC设备的过程,U盘存储设备为板载eMMC。


一、电路图



板载eMMC型号为MTFC4GACAJCN,4Gbytes eMMC设备。eMMC是一种将NAND闪存和一个控制器集成在一个单独的封装中的存储设备。

二、STM32CuteMX配置
1、SDMMC1
mode:MMC 8 bits Wide bus,
分频:2或者1


2、USB_OTG_FS
USB MODE:Device only
参数设置保持默认


3、USB_DEVICE_M7
CLASS:Mass Storage Class
参数设置保持默认,注意缓存为512bytes

4、时钟配置

SDMMC配置为50Mhz:


USB固定为48Mhz


生成代码

三、代码修改
为了将USB配置为MSC设备,需要是在usbd_storage_if.c实现以下几个函数,用来和EMMC设备通信:

USBD_StorageTypeDef USBD_Storage_Interface_fops_FS =
{
  STORAGE_Init_FS,
  STORAGE_GetCapacity_FS,//必须实现
  STORAGE_IsReady_FS,//必须实现
  STORAGE_IsWriteProtected_FS,
  STORAGE_Read_FS,//必须实现
  STORAGE_Write_FS,//必须实现
  STORAGE_GetMaxLun_FS,
  (int8_t *)STORAGE_Inquirydata_FS
};


1、STORAGE_Init_FS
SDMMC设备在main()中已经初始化,这里直接返回
int8_t STORAGE_Init_FS(uint8_t lun)
{
  /* USER CODE BEGIN 2 */
  return (USBD_OK);
  /* USER CODE END 2 */
}
2、STORAGE_GetCapacity_FS
这个函数用来获得存储单元block的大小和个数,对于eMMC,每个存储单元block为512bytes
int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num, uint16_t *block_size)
{
  /* USER CODE BEGIN 3 */
        
HAL_MMC_CardInfoTypeDef info;
HAL_MMC_CardStateTypeDef State;

  State = HAL_MMC_GetCardState(&hmmc1);
  if(State == HAL_MMC_CARD_TRANSFER)
  {
    HAL_MMC_GetCardInfo(&hmmc1, &info);
   *block_num = info.LogBlockNbr - 1;
   *block_size = info.LogBlockSize;
    return (USBD_OK);
  }
  else
        while(1);
  /* USER CODE END 3 */
}
3、STORAGE_IsReady_FS
检查存储是否可用
int8_t STORAGE_IsReady_FS(uint8_t lun)
{
  /* USER CODE BEGIN 4 */
  uint8_t state = 0;
  state = HAL_MMC_GetState(&hmmc1) ;
  if(HAL_MMC_STATE_READY != state)
  {
          return USBD_FAIL ;
  }

  return (USBD_OK);
  /* USER CODE END 4 */
}
4、读函数
int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
  /* USER CODE BEGIN 6 */
  int8_t ret = USBD_FAIL;
  uint32_t timeout = 100000;
        if( HAL_MMC_ReadBlocks(&hmmc1,(uint8_t *)buf, blk_addr , blk_len, timeout) == HAL_OK)
        {
                while(((HAL_MMC_GetCardState(&hmmc1)== HAL_MMC_CARD_TRANSFER)?MMC_TRANSFER_OK:MMC_TRANSFER_BUSY)!=HAL_OK)
                {
                        ret=USBD_OK;
                }
        }
        
        return ret;
  /* USER CODE END 6 */
}
5、写函数
int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
  /* USER CODE BEGIN 7 */
        int8_t ret = USBD_FAIL;
  uint32_t timeout = 100000;        
        
        
        if( HAL_MMC_WriteBlocks(&hmmc1,(uint8_t *)buf, blk_addr , blk_len, timeout) == HAL_OK)
        {
                while(((HAL_MMC_GetCardState(&hmmc1)== HAL_MMC_CARD_TRANSFER)?MMC_TRANSFER_OK:MMC_TRANSFER_BUSY)!=HAL_OK)
                {
                        ret=USBD_OK;
                }
        }
                return ret;
        
  /* USER CODE END 7 */
}

三、运行效果


取电跳线改为USB FS,

连接USB FS和电脑:

设备管理器中,多出一个USB大容量存储设备。

第一次使用需要格式化,格式化参数选择如下:



完成后,就可以看到盘符和容量:




使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

45

主题

93

帖子

0

粉丝