本帖最后由 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大容量存储设备。
第一次使用需要格式化,格式化参数选择如下:
完成后,就可以看到盘符和容量:
|