【stm32】stm32CubeMx usb+sd卡做u盘

1 篇文章 0 订阅
1 篇文章 0 订阅

1.HAL时钟要选择定时器,因为后面我们要加入freeRTOS,RTOS系统时钟默认为systick,HAL选择TIM1避免冲突

2. sdio选择为4线模式,分频系数为2,并配置中断和dma。注意中断优先级sd > dma > usb

3.选择USB_OTG_FS,device模式。注意尽量不要启用VBUS,因为它与usart1引脚冲突,当然可以通过重映射避免

4. 选择USB DEVICE,选择Mass Storage Class

5. 选择fatfs,选择SD卡

 

6.加入freeRTOS

7. 补全usbd_storage_if.c中的函数,如下函数

int8_t STORAGE_Init_FS(uint8_t lun)
{
  /* USER CODE BEGIN 2 */
	BSP_SD_Init();
  return (USBD_OK);
  /* USER CODE END 2 */
}

int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num, uint16_t *block_size)
{
  /* USER CODE BEGIN 3 */
	HAL_SD_CardInfoTypeDef info;
  int8_t ret = -1;
 
  if(BSP_SD_IsDetected() != SD_NOT_PRESENT)
  {
		BSP_SD_GetCardInfo(&info);
	 
		*block_num =  info.LogBlockNbr  - 1;
		*block_size = info.LogBlockSize;
		ret = 0;
  }
  return ret;
  /* USER CODE END 3 */
}

int8_t STORAGE_IsReady_FS(uint8_t lun)
{
  /* USER CODE BEGIN 4 */
  static int8_t prev_status = 0;
  int8_t ret = -1;
 
  if(BSP_SD_IsDetected() != SD_NOT_PRESENT)
  {
		if(prev_status < 0)
		{
			BSP_SD_Init();
			prev_status = 0;
	 
		}
		if(BSP_SD_GetCardState() == SD_TRANSFER_OK)
		{
			ret = 0;
		}
  }
  else if(prev_status == 0)
  {
		prev_status = -1;
  }
	
  return ret;

  /* USER CODE END 4 */
}

int8_t STORAGE_IsWriteProtected_FS(uint8_t lun)
{
  /* USER CODE BEGIN 5 */
  return (USBD_OK);
  /* USER CODE END 5 */
}

int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
  /* USER CODE BEGIN 6 */
#ifdef SD_CARD_READ
	int8_t ret = -1;
  uint32_t timeout = 100000;
 
  BSP_SD_ReadBlocks((uint32_t *)buf, blk_addr, blk_len, SD_DATATIMEOUT);
  while(BSP_SD_GetCardState() != SD_TRANSFER_OK)
  {
		if (timeout-- == 0)
		{
			return ret;
		}
  }
  ret = 0;
 
  return ret;
#endif
#ifdef SD_CARD_READ_DMA
	int8_t ret = USBD_FAIL;

    if( HAL_SD_ReadBlocks_DMA(&hsd, buf, blk_addr, blk_len) == HAL_OK )
    {
        ret = USBD_OK;
    }
    
    if( USBD_OK == ret )
    {
        while(HAL_SD_GetState(&hsd) == HAL_SD_STATE_BUSY){};
        
        while( HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER ){};
    }
    
    return ret;
#endif

	//BSP_SD_ReadBlocks_DMA((uint32_t *)buf, blk_addr, blk_len);
// return (USBD_OK);
  /* USER CODE END 6 */
}

/**
  * @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 */
#ifdef SD_CARD_WRITE
	int8_t ret = -1;
  uint32_t timeout = 100000;
 
  BSP_SD_WriteBlocks((uint32_t *)buf, blk_addr, blk_len, SD_DATATIMEOUT);
  while(BSP_SD_GetCardState() != SD_TRANSFER_OK)
  {
	if (timeout-- == 0)
	{
	  return ret;
	}
  }
  ret = 0;
 
  return ret;
#endif
#ifdef SD_CARD_WRITE_DMA
	int8_t ret = USBD_FAIL; 

    if( HAL_SD_WriteBlocks_DMA(&hsd, buf, blk_addr, blk_len) == HAL_OK )
    {
        ret = USBD_OK;
    }
    
    if( USBD_OK == ret )
    {
        while(HAL_SD_GetState(&hsd) == HAL_SD_STATE_BUSY){};
        
        while( HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER ){};
    }

    return ret;
#endif
	
  /* USER CODE END 7 */
}

/**
  * @brief  .
  * @param  None
  * @retval .
  */
int8_t STORAGE_GetMaxLun_FS(void)
{
  /* USER CODE BEGIN 8 */
  return (STORAGE_LUN_NBR - 1);
  /* USER CODE END 8 */
}

8. 插入usb,电脑文件管理中就会显示有u盘了。

9. 如果设备管理器中出现感叹号,设置TIM1的中断优先级为最高,修改stm32f4xx_hal_conf.h中,这样同时也能解决在freertos下不能使用HAL_Delay的问题

#define  TICK_INT_PRIORITY            (0x00U)

 

  • 4
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值