STM32 HAL库MSC 通过STM32内部Flash实现模拟U盘的功能。
1.配置STM32Cubemx软件生成工程
选择stm32F103RCTx配置好系统时钟,选择USB_DEVICE ,Mass Storage Class(大容量存储设备)
2.生成工程打开工程中的usbd_storage_if.c文件
将修改usbd_storage_if.c文件中代码
#define STORAGE_LUN_NBR 1 //分区数目
#define STORAGE_BLK_NBR 64 //扇区数目
#define STORAGE_BLK_SIZ 0x800 //扇区大小
/* USER CODE BEGIN PRIVATE_DEFINES */
#define FLASH_START_ADDR 0x08010000 // 设置flahs起始地址
/**
* @brief .
* @param lun: .
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
/* USER CODE BEGIN 6 */
uint8_t *s = (uint8_t *)(FLASH_START_ADDR);
uint8_t *p = buf;
s+=(blk_addr*STORAGE_BLK_SIZ);
for(int i=0; i<blk_len*STORAGE_BLK_SIZ ;i++) //读取FLash地址中的数据
{
*(buf++) = *(s++ );
}
}
/**
* @brief .
* @param lun: .
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
/* USER CODE BEGIN 7 */
//内存写函数
uint32_t n,i;
HAL_FLASH_Unlock(); //解锁flash
if(lun == 0)
{
static FLASH_EraseInitTypeDef EraseInitStruct;
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.PageAddress = FLASH_START_ADDR+ blk_addr*STORAGE_BLK_SIZ;
EraseInitStruct.NbPages = blk_len;
uint32_t PageError = 0;
if( HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK) //擦除数据
{
return FAIL;
}
for(i=0;i<blk_len*STORAGE_BLK_SIZ;i+=4) //以四字节写入falsh
{
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,FLASH_START_ADDR +
blk_addr*STORAGE_BLK_SIZ + i , *(uint32_t *)(&buf[i]));
}
HAL_FLASH_Lock();
return USBD_OK;
}
return USBD_FAIL;
/* USER CODE END 7 */
}
3.连接电脑首次需要进行格式化,选择快速格式化
读取成功,后续可以通过跳转实现IAP程序升级