sujingliang 发表于 2025-1-23 18:55

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

本帖最后由 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大容量存储设备。

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



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




codingtuzi 发表于 2025-1-26 09:49

这个实验的技术含量好高啊

稳稳の幸福 发表于 2025-1-26 18:18

在里面放个PE系统,然后试试能否被电脑启动程序识别。

星辰大海不退缩 发表于 2025-1-30 14:06

eMMC+USB非常经典的控制方式
页: [1]
查看完整版本: 【STM32H745I-DISCO试用】5、eMMC+USB MSC=U盘