我是靠谱客的博主 纯情钢铁侠,最近开发中收集的这篇文章主要介绍STM32f105写U盘,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

地址       https://blog.csdn.net/qq_36305492/article/details/90438210

 

这几天需要往U盘里读写数据,需要升级单片机和向USB里写入测量数据。所用的芯片是STM32F105RB,注意必须要有OTG的功能的芯片才可以的单板驱动USB向其内部读写数据,没有OTG功能只能做从机我理解为可以和电脑连接后STM32内部flash做为U盘.

从图上看我们知道只有F105/107和F2/4的单片机才具有OTG功能,而且F4还有FS/HS可以选择。

  说明: OTG_FS为 full speed 全速接口,   OTG_HS为 high speed 高速接口,对于全速接口就是我们一般使用最多的USB接口形式了,而高速的USB接口,一般需要配合USB的外部联合使用,但是在不使用外部PHY的情况下,也可以当做全速接口使用(这是在调试的时候,因为硬件已经连接成这样了,没办法最后百度才知道可以这样使用的,而我最终的使用方式也是用HS的接口,当FS使用)

  USB芯片也分为Controller部分和PHY部分。Controller部分主要实现USB的协议和控制。内部逻辑主要有MAC层、CSR层和FIFO控制层,还有其他低功耗管理之类层次。MAC实现按USB协议进行数据包打包和解包,并把数据按照UTMI总线格式发送给PHY(USB3.0为PIPE)。CSR层进行寄存器控制,软件对USB芯片的控制就是通过CSR寄存器,这部分和CPU进行交互访问,主要作为Slave通过AXI或者AHB进行交互。FIFO控制层主要是和DDR进行数据交互,控制USB从DDR搬运数据的通道,主要作为Master通过AXI/AHB进行交互。PHY部分功能主要实现并转串的功能,把UTMI或者PIPE口的并行数据转换成串行数据,再通过差分数据线输出到芯片外部。 

一个关于PHY文章:https://blog.csdn.net/weiwei_xiaoyu/article/details/53347956
  一般来说,如果usb phy封装在芯片内,基本采用UTMI+的接口。不封装到芯片内的一般采用ULPI接口,这样可以降低pin的数量。 
  关于STM32芯片内嵌的OTG FS控制器、OTG HS控制器、OTG FS PHY具体见芯片手册

画原理图时一定要注意。如果只是需要FS的功能画到hs端口还能补救,需要HS功能画到FS就不可以实现了。

注意芯片图上FS/HS接口是定义好的,我使用FS实现STM32做HOST(主机) 实现读写功能。

看一下网上下载的驱动

STSW-STM32046: 主要是针对STM32F105/7, STM32F2 and STM32F4 USB on-the-go Host and device library,对应的说明文档为UM1021。下载地址为https://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32-standard-peripheral-library-expansion/stsw-stm32046.html,该版本的驱动最新版本为2.2.0。下文就是以该驱动为例。
STSW-STM32121: 主要是针对STM32F10x, STM32L1xx and STM32F3xx USB full speed device library,对应的说明文档为UM0424。 
下载地址为https://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32-standard-peripheral-library-expansion/stsw-stm32121.html,该版本的驱动最新版本为4.0.1。STSW-STM32092: 主要是针对STM32F0x2xx USB FS device library,对应的说明为UM1717。下载地址为https://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32-standard-peripheral-library-expansion/stsw-stm32092.html,该版本驱动的最新版本为1.0.0。这里需要注意,该驱动是针对STM32F0x2xx的,但是可以非常方便的移植到STM32F0xx系列得MCU中,需要注意的是,需要根据具体芯片的时钟,修改驱动的usb_conf.h和usb_bsp.c。
 

我们确定自己要用的功能。

先说一下USB功能驱动函数的分类。

USB只有两个功能:1,做驱动device相当于做从机,2,做主机即HOST。

重点在Libraries目录中。其中的USB OTG是USB Device和USB Host 的基础。在实际使用,USB OTG是USB Device和USB Host 的底层驱动。(在一开始学习时,还以为每部分都可以独立使用!!)。 

参考文章 :https://blog.csdn.net/zcshoucsdn/article/details/78944536,做主机即HOST

https://blog.csdn.net/ZCShouCSDN/article/details/78936456  ,做驱动device相当于做从机

 

如果是要做驱动 device相当于做从机 就是OTG+device

如果是坐主机就是OTG+host,

开始移植

个人建议打开库里的例程复制粘贴。

我的移植比较简单。

简单来说USB_HOST文件夹下的文件是不需要修改的只要我们从库里找到这些文件添加进来就好了,我把我的头文件c文件夹给大家看一下。

这些文件不需要修改,直接复制进来就好了。注意不使用USB_device时是不需要调用的。我这个是一开始移植不懂都拉进来实际程序中也没有用到,删除减少代码大小

接下来是六个放在我们主函数中的文件

介绍一下,usb_bsp.c定义了我们USB的IO口和电源。C文件需要修改,H文件不动。

usb_conf.h,

usbh_conf.h, 这两个函数都是配置函数头文件。一定要修改

usbh_usr.c/.h,这里面都是usb的回调函数和中断函数,我在里面添加了和FATFS的接口函数。即对U盘的操作函数。

接下来因为我们要操作U盘因为U盘是FAT的储存介质。很自然要用到FATFS文件

FATFS库下载地址:http://elm-chan.org/fsw/ff/00index_e.html 

接下来移植fatfs文件这个官网上有很多解释我就不多写了

程序里要添加的文件

src文件夹下是我们的文件

option文件夹下都是字库

到此全部移植完成。

修改我们之前提到的文件

/**
  ******************************************************************************
  * @file    usb_bsp.c
  * @author  MCD Application Team
  * @version V1.2.0
  * @date    09-November-2015
  * @brief   This file implements the board support package for the USB host library
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
  *
  * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
  * You may not use this file except in compliance with the License.
  * You may obtain a copy of the License at:
  *
  *        http://www.st.com/software_license_agreement_liberty_v2
  *
  * Unless required by applicable law or agreed to in writing, software 
  * distributed under the License is distributed on an "AS IS" BASIS, 
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
  ******************************************************************************
  */ 
 
/* Includes ------------------------------------------------------------------*/
 
#include "usb_bsp.h"
#include "stm32f10x.h"
#include "delay.h"
#include "stm32f10x_tim.h"
/** @addtogroup USBH_USER
* @{
*/
 
/** @defgroup USB_BSP
  * @brief This file is responsible to offer board support package
  * @{
  */ 
 
/** @defgroup USB_BSP_Private_Defines
  * @{
  */ 
#define USE_ACCURATE_TIME                  0
#define TIM_MSEC_DELAY                     0x01
#define TIM_USEC_DELAY                     0x02
//#define HOST_OVRCURR_PORT                  GPIOE
//#define HOST_OVRCURR_LINE                  GPIO_Pin_1
//#define HOST_OVRCURR_PORT_SOURCE           GPIO_PortSourceGPIOE
//#define HOST_OVRCURR_PIN_SOURCE            GPIO_PinSource1
//#define HOST_OVRCURR_PORT_RCC              RCC_APB2Periph_GPIOE
//#define HOST_OVRCURR_EXTI_LINE             EXTI_Line1
//#define HOST_OVRCURR_IRQn                  EXTI1_IRQn 
 
 
 #define HOST_POWERSW_PORT_RCC             RCC_APB2Periph_GPIOA
 #define HOST_POWERSW_PORT                 GPIOA
 #define HOST_POWERSW_VBUS                 GPIO_Pin_15
 
//#define HOST_SOF_OUTPUT_RCC                RCC_APB2Periph_GPIOA
//#define HOST_SOF_PORT                      GPIOA
//#define HOST_SOF_SIGNAL                    GPIO_Pin_8
 
/**
  * @}
  */ 
 
 
/** @defgroup USB_BSP_Private_TypesDefinitions
  * @{
  */ 
/**
  * @}
  */ 
 
 
 
/** @defgroup USB_BSP_Private_Macros
  * @{
  */ 
/**
  * @}
  */ 
 
/** @defgroup USBH_BSP_Private_Variables
  * @{
  */ 
ErrorStatus HSEStartUpStatus;
 
 
#ifdef USE_ACCURATE_TIME 
 
__IO uint32_t BSP_delay = 0;
#endif
/**
  * @}
  */ 
 
/** @defgroup USBH_BSP_Private_FunctionPrototypes
  * @{
  */ 
 
#ifdef USE_ACCURATE_TIME 
static void BSP_SetTime(uint8_t Unit);
static void BSP_Delay(uint32_t nTime,uint8_t Unit);
static void USB_OTG_BSP_TimeInit ( void );
#endif
/**
  * @}
  */ 
 
/** @defgroup USB_BSP_Private_Functions
  * @{
  */ 
 
/**
  * @brief  USB_OTG_BSP_Init
  *         Initializes BSP configurations
  * @param  None
  * @retval None
  */
 
void USB_OTG_BSP_Init(USB_OTG_CORE_HANDLE *pdev)
{
 
  GPIO_InitTypeDef GPIO_InitStructure;
    
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);  
  RCC_OTGFSCLKConfig(RCC_OTGFSCLKSource_PLLVCO_Div3);
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_OTG_FS, ENABLE) ;
  
  
  /* Configure SOF ID DM DP Pins GPIO_Pin_8|*/
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_11 | 
                                GPIO_Pin_12;
  
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP ;
  GPIO_Init(GPIOA, &GPIO_InitStructure);  
 
 
  
  /* Configure  VBUS Pin */
//  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
//  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
//  GPIO_Init(GPIOC, &GPIO_InitStructure);    
//    
 
 
 
 
  /* Initialize Timer for delay function */
 USB_OTG_BSP_TimeInit();   
}
/**
  * @brief  USB_OTG_BSP_EnableInterrupt
  *         Configures USB Global interrupt
  * @param  None
  * @retval None
  */
void USB_OTG_BSP_EnableInterrupt(USB_OTG_CORE_HANDLE *pdev)
{
  NVIC_InitTypeDef NVIC_InitStructure; 
  
//  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
 
  NVIC_InitStructure.NVIC_IRQChannel = OTG_FS_IRQn;  
 
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);  
 
}
 
/**
  * @brief  BSP_Drive_VBUS
  *         Drives the Vbus signal through IO
  * @param  state : VBUS states
  * @retval None
  */
 
void USB_OTG_BSP_DriveVBUS(USB_OTG_CORE_HANDLE *pdev, uint8_t state)
{
  /*
  On-chip 5 V VBUS generation is not supported. For this reason, a charge pump 
  or, if 5 V are available on the application board, a basic power switch, must 
  be added externally to drive the 5 V VBUS line. The external charge pump can 
  be driven by any GPIO output. When the application decides to power on VBUS 
  using the chosen GPIO, it must also set the port power bit in the host port 
  control and status register (PPWR bit in OTG_FS_HPRT).
  
  Bit 12 PPWR: Port power
  The application uses this field to control power to this port, and the core 
  clears this bit on an overcurrent condition.
  */
//这里一定要注意,U盘是要单独供电的一般要5V1A电源,在硬件设计时会做一个开关电源。注意要根据自己的电源使能管教配置,根据你是高低电平使能修改,否则有可能导致你的U盘插上没有反应。
  
  if (0 == state)
  { 
    /* DISABLE is needed on output of the Power Switch */
    GPIO_ResetBits(HOST_POWERSW_PORT, HOST_POWERSW_VBUS);
  }
  else
  { GPIO_SetBits(HOST_POWERSW_PORT, HOST_POWERSW_VBUS);
    /*ENABLE the Power Switch by driving the Enable LOW */
   
  }
}
 
/**
  * @brief  USB_OTG_BSP_ConfigVBUS
  *         Configures the IO for the Vbus and OverCurrent
  * @param  None
  * @retval None
  */
 
void  USB_OTG_BSP_ConfigVBUS(USB_OTG_CORE_HANDLE *pdev)
{
 
  
  GPIO_InitTypeDef GPIO_InitStructure; 
  
 
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA , ENABLE);  
    
  GPIO_InitStructure.GPIO_Pin = HOST_POWERSW_VBUS;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
 
  GPIO_Init(HOST_POWERSW_PORT,&GPIO_InitStructure);
 
 
  /* By Default, DISABLE is needed on output of the Power Switch */
  GPIO_SetBits(HOST_POWERSW_PORT, HOST_POWERSW_VBUS);
  
  USB_OTG_BSP_mDelay(200);   /* Delay is need for stabilising the Vbus Low 
  in Reset Condition, when Vbus=1 and Reset-button is pressed by user */
 
}
 
/**
  * @brief  USB_OTG_BSP_TimeInit
  *         Initializes delay unit using Timer2
  * @param  None
  * @retval None
  */
static void USB_OTG_BSP_TimeInit ( void )
{
#ifdef USE_ACCURATE_TIME   
  NVIC_InitTypeDef NVIC_InitStructure;
  
  /* Set the Vector Table base address at 0x08000000 */
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x00);
  
  /* Configure the Priority Group to 2 bits */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  
  /* Enable the TIM2 global Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  
  NVIC_Init(&NVIC_InitStructure);
  
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);  
#endif  
}
 
/**
  * @brief  USB_OTG_BSP_uDelay
  *         This function provides delay time in micro sec
  * @param  usec : Value of delay required in micro sec
  * @retval None
  */
void USB_OTG_BSP_uDelay (const uint32_t usec)
{
  
    Delay_us(usec);
  
}
 
 
/**
  * @brief  USB_OTG_BSP_mDelay
  *          This function provides delay time in milli sec
  * @param  msec : Value of delay required in milli sec
  * @retval None
  */
void USB_OTG_BSP_mDelay (const uint32_t msec)

    Delay_ms(msec);  
 
}
 
 
/**
  * @brief  USB_OTG_BSP_TimerIRQ
  *         Time base IRQ
  * @param  None
  * @retval None
  */
 
void USB_OTG_BSP_TimerIRQ (void)
{
#ifdef USE_ACCURATE_TIME 
    
  if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
  {
   TIM_ClearITPendingBit(TIM2, TIM_IT_Update);    
    if (BSP_delay > 0x00)
    { 
      BSP_delay--;
    }
    else
    {
      TIM_Cmd(TIM2,DISABLE);
    }
  }
#endif  

 
/**
  * @brief  BSP_Delay
  *         Delay routine based on TIM2
  * @param  nTime : Delay Time 
  * @param  unit : Delay Time unit : mili sec / micro sec
  * @retval None
  */
static void BSP_Delay(uint32_t nTime, uint8_t unit)
{
  
  BSP_delay = nTime;
  BSP_SetTime(unit);  
  while(BSP_delay != 0);
  TIM_Cmd(TIM2,DISABLE);
}
 
/**
  * @brief  BSP_SetTime
  *         Configures TIM2 for delay routine based on TIM2
  * @param  unit : msec /usec
  * @retval None
  */
static void BSP_SetTime(uint8_t unit)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  
  TIM_Cmd(TIM2,DISABLE);
  TIM_ITConfig(TIM2, TIM_IT_Update, DISABLE); 
  
  
  if(unit == TIM_USEC_DELAY)
  {  
    TIM_TimeBaseStructure.TIM_Period = 11;
  }
  else if(unit == TIM_MSEC_DELAY)
  {
    TIM_TimeBaseStructure.TIM_Period = 11999;
  }
  TIM_TimeBaseStructure.TIM_Prescaler = 5;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
  TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
  
  TIM_ARRPreloadConfig(TIM2, ENABLE);
  
  /* TIM IT enable */
  TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
  
  /* TIM2 enable counter */ 
  TIM_Cmd(TIM2, ENABLE);  

 
 
 
/**
* @}
*/ 
 
/**
* @}
*/ 
 
/**
* @}
*/
 
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
/**
  ******************************************************************************
  * @file    usbh_usr.c
  * @author  MCD Application Team
  * @version V1.2.0
  * @date    09-November-2015
  * @brief   This file includes the usb host library user callbacks
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2015 STMicroelectronics</center></h2>
  *
  * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
  * You may not use this file except in compliance with the License.
  * You may obtain a copy of the License at:
  *
  *        http://www.st.com/software_license_agreement_liberty_v2
  *
  * Unless required by applicable law or agreed to in writing, software 
  * distributed under the License is distributed on an "AS IS" BASIS, 
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
  ******************************************************************************
  */
 
/* Includes ------------------------------------------------------------------*/
 
 
#include "usbh_usr.h"
#include "usb_hcd_int.h"
#include "stm32f10x.h"
#include "ff.h"       /* FATFS */
#include "my_printf.h"
 
 
系统配置结构体//
 
extern USB_OTG_CORE_HANDLE    USB_OTG_Core;
extern USBH_HOST              USB_Host;
 
/** @defgroup USBH_USR_Private_Variables
* @{
*/ 
uint8_t USBH_USR_ApplicationState = USH_USR_FS_INIT;
 
 
FATFS fatfs;
FIL file;
static u8 AppState; 
 
 
 
/*  Points to the DEVICE_PROP structure of current device */
/*  The purpose of this register is to speed up the execution */
 
USBH_Usr_cb_TypeDef USR_cb =
{
  USBH_USR_Init,
  USBH_USR_DeInit,
  USBH_USR_DeviceAttached,
  USBH_USR_ResetDevice,
  USBH_USR_DeviceDisconnected,
  USBH_USR_OverCurrentDetected,
  USBH_USR_DeviceSpeedDetected,
  USBH_USR_Device_DescAvailable,
  USBH_USR_DeviceAddressAssigned,
  USBH_USR_Configuration_DescAvailable,
  USBH_USR_Manufacturer_String,
  USBH_USR_Product_String,
  USBH_USR_SerialNum_String,
  USBH_USR_EnumerationDone,
  USBH_USR_UserInput,
  USBH_USR_MSC_Application,
  USBH_USR_DeviceNotSupported,
  USBH_USR_UnrecoveredError
    
};
 
 
 
 
/** @defgroup USBH_USR_Private_Functions
* @{
*/ 
 
 
void OTG_FS_IRQHandler(void)
{
      USBH_OTG_ISR_Handler(&USB_OTG_Core);

 
/**
* @brief  USBH_USR_Init 
*         USB HOST 初始化 
* @param  None
* @retval None
*/
void USBH_USR_Init(void)
{
    Debug_Com_printf("USB OTG HS MSC Hostrn");
    Debug_Com_printf("> USB Host library started.rn");
    Debug_Com_printf("  USB Host Library v2.1.0rnrn");
}
 
/**
* @brief  USBH_USR_DeviceAttached 
*         //检测到U盘插入
* @param  None
* @retval None
*/
void USBH_USR_DeviceAttached(void)
{
    Debug_Com_printf("检测到USB设备插入!rn");
}
 
//获取U盘状态
//返回值:0,U盘未就绪
//      1,就绪
 
uint8_t USBH_UDISK_Status(void)
{
    return HCD_IsDeviceConnected(&USB_OTG_Core);//返回U盘状态
}
 
 
/**
* @brief  USBH_USR_UnrecoveredError
* @param  None
* @retval None
*/
void USBH_USR_UnrecoveredError (void)
{
  
}
 
 
/**
* @brief  USBH_DisconnectEvent
*         //检测到U盘拔出
* @param  None
* @retval Status
*/
void USBH_USR_DeviceDisconnected (void)
{
  Debug_Com_printf("检测到USB设备拔出!rn");
}
/**
* @brief  USBH_USR_ResetUSBDevice 
   //复位从机
* @param  None
* @retval None
*/
void USBH_USR_ResetDevice(void)
{
        Debug_Com_printf("复位设备...rn");
  /* callback for USB-Reset */
}
 
 
/**
* @brief  USBH_USR_DeviceSpeedDetected 
*         //检测到从机速度
            //DeviceSpeed:从机速度(0,1,2 / 其他)
* @param  Device speed
* @retval None
*/
void USBH_USR_DeviceSpeedDetected(uint8_t DeviceSpeed)
{
      if(DeviceSpeed==HPRT0_PRTSPD_HIGH_SPEED)
    {
        Debug_Com_printf("高速(HS)USB设备!rn");
     }  
    else if(DeviceSpeed==HPRT0_PRTSPD_FULL_SPEED)
    {
        Debug_Com_printf("全速(FS)USB设备!rn"); 
    }
    else if(DeviceSpeed==HPRT0_PRTSPD_LOW_SPEED)
    {
        Debug_Com_printf("低速(LS)USB设备!rn");  
    }
    else
    {
        Debug_Com_printf("设备错误!rn");  
    }
}
 
/**
* @brief  USBH_USR_Device_DescAvailable 
*        //检测到从机的描述符
/          /DeviceDesc:设备描述符指针
* @param  device descriptor
* @retval None
*/
void USBH_USR_Device_DescAvailable(void *DeviceDesc)

    USBH_DevDesc_TypeDef *hs;
    hs=DeviceDesc;   
    Debug_Com_printf("VID: %04Xhrn" , (uint32_t)(*hs).idVendor); 
    Debug_Com_printf("PID: %04Xhrn" , (uint32_t)(*hs).idProduct); 
  
}
 
/**
* @brief  USBH_USR_DeviceAddressAssigned 
*        //从机地址分配成功
* @param  None
* @retval None
*/
void USBH_USR_DeviceAddressAssigned(void)
{
      Debug_Com_printf("从机地址分配成功!rn");   
}
 
 
/**
* @brief  USBH_USR_Conf_Desc 
*         //配置描述符获有效
* @param  Configuration descriptor
* @retval None
*/
void USBH_USR_Configuration_DescAvailable(USBH_CfgDesc_TypeDef * cfgDesc,
                                          USBH_InterfaceDesc_TypeDef *itfDesc,
                                          USBH_EpDesc_TypeDef *epDesc)
{
    USBH_InterfaceDesc_TypeDef *id; 
    id = itfDesc;   
    if((*id).bInterfaceClass==0x08)
    {
        Debug_Com_printf("可移动存储器设备!rn"); 
    }else if((*id).bInterfaceClass==0x03)
    {
        Debug_Com_printf("HID 设备!rn"); 
    }    
}
 
/**
* @brief  USBH_USR_Manufacturer_String 
*         //获取到设备Manufacturer String
* @param  Manufacturer String 
* @retval None
*/
void USBH_USR_Manufacturer_String(void *ManufacturerString)
{
 Debug_Com_printf("Manufacturer: %srn",(char *)ManufacturerString);
}
 
/**
* @brief  USBH_USR_Product_String 
*         //获取到设备Product String 
* @param  Product String
* @retval None
*/
void USBH_USR_Product_String(void *ProductString)
{
        Debug_Com_printf("Product: %srn",(char *)ProductString); 
//  LCD_UsrLog("Product : %sn", (char *)ProductString);  
}
 
/**
* @brief  USBH_USR_SerialNum_String 
*       //获取到设备SerialNum String 
* @param  SerialNum_String 
* @retval None
*/
void USBH_USR_SerialNum_String(void *SerialNumString)
{
Debug_Com_printf("Serial Number: %srn",(char *)SerialNumString);  
    

 
 
 
/**
* @brief  EnumerationDone 
*       //设备USB枚举完成
* @param  None
* @retval None
*/
void USBH_USR_EnumerationDone(void)
{
  
    Debug_Com_printf("设备枚举完成!rnrn"); 
  

 
 
/**
* @brief  USBH_USR_DeviceNotSupported
*      //无法识别的USB设备
* @param  None
* @retval None
*/
void USBH_USR_DeviceNotSupported(void)
{
        Debug_Com_printf("无法识别的USB设备!rnrn"); 
//  LCD_ErrLog ("No registered class for this device. nr");
}  
 
 
/**
* @brief  USBH_USR_UserInput
*        //等待用户输入按键,执行下一步操作
* @param  None
* @retval USBH_USR_Status : User response for key button
*/
USBH_USR_Status USBH_USR_UserInput(void)
{
        Debug_Com_printf("跳过用户确认步骤!rn");
    return USBH_USR_RESP_OK;
}  
 
/**
* @brief  USBH_USR_OverCurrentDetected
*        //USB接口电流过载
* @param  None
* @retval Status
*/
void USBH_USR_OverCurrentDetected (void)
{
        Debug_Com_printf("端口电流过大!!!rn");
//  LCD_ErrLog ("Overcurrent detected.");
}
 
 
 
 
 
u8  text_buffer[50] = "hospital,bednumber,name,age,sex,n1,2,3,4,5,n";
 
 
 
 
u8 USH_User_App(void)

    FATFS fs[_VOLUMES];//逻辑磁盘工作区. 
    u8 f_res;
  FIL filescr1;    
  UINT br;
      f_res=f_mount(&fs[0],"0:",1);     //重新挂载U盘
      
  f_res=f_mkdir("0:DATA");//新建文件夹,其中DATA是文件夹名称
      f_res=f_open(&filescr1,"0:20190522.csv", FA_CREATE_ALWAYS|FA_WRITE);
     
       f_res= f_write(&filescr1, text_buffer, sizeof(text_buffer), &br);
    
    //在新建的文件夹下创建新的txt文本文件新建完成之后要记得关闭该文件,否则就会出错。
   f_res = f_close(&filescr1);
    Debug_Com_printf("写入完成rn");
    while(HCD_IsDeviceConnected(&USB_OTG_Core))//设备连接成功
    {    
  
 
    }
 
     f_mount(0,"35:",1);     //卸载U盘
  Debug_Com_printf("USB已卸载rn");
    return 1;

 
 
 
 
/**
* @brief  USBH_USR_MSC_Application 
*       //USB HOST MSC类用户应用程序
* @param  None
* @retval Status
*/
int USBH_USR_MSC_Application(void)
{
     u8 res=0;
      switch(AppState)
      {
        case USH_USR_FS_INIT://初始化文件系统 
               Debug_Com_printf("开始执行用户程序!!!rn");
              AppState=1;
              break;
        case 1 :    //执行USB OTG 测试主程序
                
            
            res=USH_User_App(); //用户主程序
             res=0;
            if(res)AppState=USH_USR_FS_INIT;
              break;
        default:break;
      } 
    return res;
}
 
 
/* @brief  USBH_USR_DeInit
*         Deinit User state and associated variables
* @param  None
* @retval None
*/
void USBH_USR_DeInit(void)
{
  USBH_USR_ApplicationState = USH_USR_FS_INIT;
}
 
 

//用户定义函数,实现fatfs diskio的接口函数 
 
 
 
//读U盘
//buf:读数据缓存区
//sector:扇区地址
//cnt:扇区个数    
//返回值:错误状态;0,正常;其他,错误代码;         
u8 USBH_UDISK_Read(u8* buf,u32 sector,u32 cnt)
{
    u8 res=1;
    if(HCD_IsDeviceConnected(&USB_OTG_Core)&&AppState==USH_USR_FS_TEST)//连接还存在,且是APP测试状态
    {              
        do
        {
            res=USBH_MSC_Read10(&USB_OTG_Core,buf,sector,512*cnt);
            USBH_MSC_HandleBOTXfer(&USB_OTG_Core ,&USB_Host);              
            if(!HCD_IsDeviceConnected(&USB_OTG_Core))
            {
                res=1;//读写错误
                Debug_Com_printf("读写错误!!!rn");
                break;
            };   
        }while(res==USBH_MSC_BUSY);
    }else res=1;          
    if(res==USBH_MSC_OK)res=0;    
    return res;
}
 
//写U盘
//buf:写数据缓存区
//sector:扇区地址
//cnt:扇区个数    
//返回值:错误状态;0,正常;其他,错误代码;         
u8 USBH_UDISK_Write(u8* buf,u32 sector,u32 cnt)
{
    u8 res=1;
    if(HCD_IsDeviceConnected(&USB_OTG_Core)&&AppState==USH_USR_FS_TEST)//连接还存在,且是APP测试状态
    {              
        do
        {
            res=USBH_MSC_Write10(&USB_OTG_Core,buf,sector,512*cnt); 
            USBH_MSC_HandleBOTXfer(&USB_OTG_Core ,&USB_Host);              
            if(!HCD_IsDeviceConnected(&USB_OTG_Core))
            {
                res=1;//读写错误
                Debug_Com_printf("读写错误!!!rn");
                break;
            };   
        }while(res==USBH_MSC_BUSY);
    }else res=1;          
    if(res==USBH_MSC_OK)res=0;    
    return res;
}
 
 
/**
* @}
*/ 
 
/**
* @}
*/ 
 
/**
* @}
*/
 
/**
* @}
*/
 
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
 
/**
  ******************************************************************************
  * @file    usbh_usr.h
  * @author  MCD Application Team
  * @version V1.2.0
  * @date    09-November-2015
  * @brief   Header file for usbh_usr.c
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2015 STMicroelectronics</center></h2>
  *
  * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
  * You may not use this file except in compliance with the License.
  * You may obtain a copy of the License at:
  *
  *        http://www.st.com/software_license_agreement_liberty_v2
  *
  * Unless required by applicable law or agreed to in writing, software 
  * distributed under the License is distributed on an "AS IS" BASIS, 
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
  ******************************************************************************
  */ 
 
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USH_USR_H__
#define __USH_USR_H__
 
/* Includes ------------------------------------------------------------------*/
#include "ff.h"
#include "usbh_core.h"
#include "usb_conf.h"
#include <stdio.h>
#include "usbh_msc_core.h"
 
/** @addtogroup USBH_USER
  * @{
  */
 
/** @addtogroup USBH_MSC_DEMO_USER_CALLBACKS
  * @{
  */
 
/** @defgroup USBH_USR
  * @brief This file is the Header file for usbh_usr.c
  * @{
  */ 
 
 
/** @defgroup USBH_USR_Exported_Types
  * @{
  */ 
 
 
extern  USBH_Usr_cb_TypeDef USR_cb;
 
 
 
/**
  * @}
  */ 
 
 
 
/** @defgroup USBH_USR_Exported_Defines
  * @{
  */ 
/* State Machine for the USBH_USR_ApplicationState */
#define USH_USR_FS_INIT       0
 
#define USH_USR_FS_TEST           1  
#define USH_USR_FS_READLIST   1
#define USH_USR_FS_WRITEFILE  2
#define USH_USR_FS_DRAW       3
/**
  * @}
  */ 
 
/** @defgroup USBH_USR_Exported_Macros
  * @{
  */ 
/**
  * @}
  */ 
 
/** @defgroup USBH_USR_Exported_Variables
  * @{
  */ 
extern  uint8_t USBH_USR_ApplicationState ;
/**
  * @}
  */ 
 
/** @defgroup USBH_USR_Exported_FunctionsPrototype
  * @{
  */ 
void USBH_USR_ApplicationSelected(void);
void USBH_USR_Init(void);
void USBH_USR_DeInit(void);
void USBH_USR_DeviceAttached(void);
void USBH_USR_ResetDevice(void);
void USBH_USR_DeviceDisconnected (void);
void USBH_USR_OverCurrentDetected (void);
void USBH_USR_DeviceSpeedDetected(uint8_t DeviceSpeed); 
void USBH_USR_Device_DescAvailable(void *);
void USBH_USR_DeviceAddressAssigned(void);
void USBH_USR_Configuration_DescAvailable(USBH_CfgDesc_TypeDef * cfgDesc,
                                          USBH_InterfaceDesc_TypeDef *itfDesc,
                                          USBH_EpDesc_TypeDef *epDesc);
void USBH_USR_Manufacturer_String(void *);
void USBH_USR_Product_String(void *);
void USBH_USR_SerialNum_String(void *);
void USBH_USR_EnumerationDone(void);
USBH_USR_Status USBH_USR_UserInput(void);
void USBH_USR_DeInit(void);
void USBH_USR_DeviceNotSupported(void);
void USBH_USR_UnrecoveredError(void);
int USBH_USR_MSC_Application(void);
 
uint8_t USBH_UDISK_Status(void);
u8 USBH_UDISK_Write(u8* buf,u32 sector,u32 cnt);
u8 USBH_UDISK_Read(u8* buf,u32 sector,u32 cnt);
/**
  * @}
  */ 
 
#endif /*__USH_USR_H__*/
 
/**
  * @}
  */ 
 
/**
  * @}
  */ 
 
/**
  * @}
  */ 
 
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
 
注意一点这个C文件我是这样修改的。

/**
  ******************************************************************************
  * @file    usbh_conf_template
  * @author  MCD Application Team
  * @version V2.2.0
  * @date    09-November-2015
  * @brief   General USB Host library configuration
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2015 STMicroelectronics</center></h2>
  *
  * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
  * You may not use this file except in compliance with the License.
  * You may obtain a copy of the License at:
  *
  *        http://www.st.com/software_license_agreement_liberty_v2
  *
  * Unless required by applicable law or agreed to in writing, software 
  * distributed under the License is distributed on an "AS IS" BASIS, 
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
  ******************************************************************************
  */
 
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBH_CONF__H__
#define __USBH_CONF__H__
 
/* Includes ------------------------------------------------------------------*/
 
/** @addtogroup USBH_OTG_DRIVER
  * @{
  */
  
/** @defgroup USBH_CONF
  * @brief usb otg low level driver configuration file
  * @{
  */ 
 
/** @defgroup USBH_CONF_Exported_Defines
  * @{
  */ 
 
#define USBH_MAX_NUM_ENDPOINTS                2
#define USBH_MAX_NUM_INTERFACES               2
 
 
#ifdef USE_USB_OTG_FS 
#define USBH_MSC_MPS_SIZE                 0x40
#else
#define USBH_MSC_MPS_SIZE                 0x200
#endif
 
///检测U盘大小的问价默认是2 一定要修改否则无法通过枚举过程
 
#define USBH_MAX_DATA_BUFFER              0x400///
/**
  * @}
  */ 
 
 
/** @defgroup USBH_CONF_Exported_Types
  * @{
  */ 
/**
  * @}
  */ 
 
 
/** @defgroup USBH_CONF_Exported_Macros
  * @{
  */ 
/**
  * @}
  */ 
 
/** @defgroup USBH_CONF_Exported_Variables
  * @{
  */ 
/**
  * @}
  */ 
 
/** @defgroup USBH_CONF_Exported_FunctionsPrototype
  * @{
  */ 
/**
  * @}
  */ 
 
 
#endif //__USBH_CONF__H__
 
 
/**
  * @}
  */ 
 
/**
  * @}
  */ 
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
 
/**
  ******************************************************************************
  * @file    usb_conf.h
  * @author  MCD Application Team
  * @version V2.2.0
  * @date    09-November-2015
  * @brief   General low level driver configuration
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2015 STMicroelectronics</center></h2>
  *
  * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
  * You may not use this file except in compliance with the License.
  * You may obtain a copy of the License at:
  *
  *        http://www.st.com/software_license_agreement_liberty_v2
  *
  * Unless required by applicable law or agreed to in writing, software 
  * distributed under the License is distributed on an "AS IS" BASIS, 
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
  ******************************************************************************
  */
 
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_CONF__H__
#define __USB_CONF__H__
 
/* Includes ------------------------------------------------------------------*/
 
 
/** @addtogroup USB_OTG_DRIVER
  * @{
  */
  
/** @defgroup USB_CONF
  * @brief USB low level driver configuration file
  * @{
  */ 
 
/** @defgroup USB_CONF_Exported_Defines
  * @{
  */ 
 
/* USB Core and PHY interface configuration.
   Tip: To avoid modifying these defines each time you need to change the USB
        configuration, you can declare the needed define in your toolchain
        compiler preprocessor.
   */
/****************** USB OTG FS PHY CONFIGURATION *******************************
*  The USB OTG FS Core supports one on-chip Full Speed PHY.
*  
*  The USE_EMBEDDED_PHY symbol is defined in the project compiler preprocessor 
*  when FS core is used.
*******************************************************************************/
 
 
 
//一定要在 Option for Target ->c++->define 中添加  ,USE_USB_OTG_FS
 
 
#ifdef USE_USB_OTG_FS 
 #define USB_OTG_FS_CORE
#endif
 
/****************** USB OTG HS PHY CONFIGURATION *******************************
*  The USB OTG HS Core supports two PHY interfaces:
*   (i)  An ULPI interface for the external High Speed PHY: the USB HS Core will 
*        operate in High speed mode
*   (ii) An on-chip Full Speed PHY: the USB HS Core will operate in Full speed mode
*
*  You can select the PHY to be used using one of these two defines:
*   (i)  USE_ULPI_PHY: if the USB OTG HS Core is to be used in High speed mode 
*   (ii) USE_EMBEDDED_PHY: if the USB OTG HS Core is to be used in Full speed mode
*
*  Notes: 
*   - The USE_ULPI_PHY symbol is defined in the project compiler preprocessor as 
*     default PHY when HS core is used.
*   - On STM322xG-EVAL and STM324xG-EVAL boards, only configuration(i) is available.
*     Configuration (ii) need a different hardware, for more details refer to your
*     STM32 device datasheet.
*******************************************************************************/
//#ifndef USE_USB_OTG_HS
// //#define USE_USB_OTG_HS
//#endif /* USE_USB_OTG_HS */
 
//#ifndef USE_ULPI_PHY
// //#define USE_ULPI_PHY
//#endif /* USE_ULPI_PHY */
 
//#ifndef USE_EMBEDDED_PHY
// //#define USE_EMBEDDED_PHY
//#endif /* USE_EMBEDDED_PHY */
 
//#ifdef USE_USB_OTG_HS 
// #define USB_OTG_HS_CORE
//#endif
 
/*******************************************************************************
*                      FIFO Size Configuration in Device mode
*  
*  (i) Receive data FIFO size = RAM for setup packets + 
*                   OUT endpoint control information +
*                   data OUT packets + miscellaneous
*      Space = ONE 32-bits words
*     --> RAM for setup packets = 10 spaces
*        (n is the nbr of CTRL EPs the device core supports) 
*     --> OUT EP CTRL info      = 1 space
*        (one space for status information written to the FIFO along with each 
*        received packet)
*     --> data OUT packets      = (Largest Packet Size / 4) + 1 spaces 
*        (MINIMUM to receive packets)
*     --> OR data OUT packets  = at least 2*(Largest Packet Size / 4) + 1 spaces 
*        (if high-bandwidth EP is enabled or multiple isochronous EPs)
*     --> miscellaneous = 1 space per OUT EP
*        (one space for transfer complete status information also pushed to the 
*        FIFO with each endpoint's last packet)
*
*  (ii)MINIMUM RAM space required for each IN EP Tx FIFO = MAX packet size for 
*       that particular IN EP. More space allocated in the IN EP Tx FIFO results
*       in a better performance on the USB and can hide latencies on the AHB.
*
*  (iii) TXn min size = 16 words. (n  : Transmit FIFO index)
*   (iv) When a TxFIFO is not used, the Configuration should be as follows: 
*       case 1 :  n > m    and Txn is not used    (n,m  : Transmit FIFO indexes)
*       --> Txm can use the space allocated for Txn.
*       case2  :  n < m    and Txn is not used    (n,m  : Transmit FIFO indexes)
*       --> Txn should be configured with the minimum space of 16 words
*  (v) The FIFO is used optimally when used TxFIFOs are allocated in the top 
*       of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones.
*******************************************************************************/
 
/*******************************************************************************
*                     FIFO Size Configuration in Host mode
*  
*  (i) Receive data FIFO size = (Largest Packet Size / 4) + 1 or 
*                             2x (Largest Packet Size / 4) + 1,  If a 
*                             high-bandwidth channel or multiple isochronous 
*                             channels are enabled
*
*  (ii) For the host nonperiodic Transmit FIFO is the largest maximum packet size 
*      for all supported nonperiodic OUT channels. Typically, a space 
*      corresponding to two Largest Packet Size is recommended.
*
*  (iii) The minimum amount of RAM required for Host periodic Transmit FIFO is 
*        the largest maximum packet size for all supported periodic OUT channels.
*        If there is at least one High Bandwidth Isochronous OUT endpoint, 
*        then the space must be at least two times the maximum packet size for 
*        that channel.
*******************************************************************************/
 
/****************** USB OTG HS CONFIGURATION不使用 **********************************/
#ifdef USB_OTG_HS_CORE
 #define RX_FIFO_HS_SIZE                          512
 #define TX0_FIFO_HS_SIZE                         512
 #define TX1_FIFO_HS_SIZE                         512
 #define TX2_FIFO_HS_SIZE                          0
 #define TX3_FIFO_HS_SIZE                          0
 #define TX4_FIFO_HS_SIZE                          0
 #define TX5_FIFO_HS_SIZE                          0
 #define TXH_NP_HS_FIFOSIZ                         96
 #define TXH_P_HS_FIFOSIZ                          96
 
// #define USB_OTG_HS_LOW_PWR_MGMT_SUPPORT
// #define USB_OTG_HS_SOF_OUTPUT_ENABLED
 
// #define USB_OTG_INTERNAL_VBUS_ENABLED
 
 
// #define USB_OTG_EXTERNAL_VBUS_ENABLED
 
 #ifdef USE_ULPI_PHY
  #define USB_OTG_ULPI_PHY_ENABLED
 #endif
 #ifdef USE_EMBEDDED_PHY
   #define USB_OTG_EMBEDDED_PHY_ENABLED
 #endif
 #define USB_OTG_HS_INTERNAL_DMA_ENABLED
 #define USB_OTG_HS_DEDICATED_EP1_ENABLED
#endif
 
/****************** USB OTG FS CONFIGURATION 我用的USB HOST模式 **********************************/
#ifdef USB_OTG_FS_CORE
 #define RX_FIFO_FS_SIZE                          128
 #define TX0_FIFO_FS_SIZE                          64
 #define TX1_FIFO_FS_SIZE                         128
 #define TX2_FIFO_FS_SIZE                          0
 #define TX3_FIFO_FS_SIZE                          0
 #define TXH_NP_FS_FIFOSIZ                         96
 #define TXH_P_FS_FIFOSIZ                          96
 
// #define USB_OTG_FS_LOW_PWR_MGMT_SUPPORT
// #define USB_OTG_FS_SOF_OUTPUT_ENABLED
#endif
 
/****************** USB OTG MISC CONFIGURATION ********************************/
//#define VBUS_SENSING_ENABLED
 
/****************** USB OTG MODE CONFIGURATION ********************************/
#define USE_HOST_MODE
//#define USE_DEVICE_MODE
//#define USE_OTG_MODE
 
#ifndef USB_OTG_FS_CORE
 #ifndef USB_OTG_HS_CORE
    #error  "USB_OTG_HS_CORE or USB_OTG_FS_CORE should be defined"
 #endif
#endif
 
#ifndef USE_DEVICE_MODE
 #ifndef USE_HOST_MODE
    #error  "USE_DEVICE_MODE or USE_HOST_MODE should be defined"
 #endif
#endif
 
#ifndef USE_USB_OTG_HS
 #ifndef USE_USB_OTG_FS
    #error  "USE_USB_OTG_HS or USE_USB_OTG_FS should be defined"
 #endif
#else //USE_USB_OTG_HS
 #ifndef USE_ULPI_PHY
  #ifndef USE_EMBEDDED_PHY
     #error  "USE_ULPI_PHY or USE_EMBEDDED_PHY should be defined"
  #endif
 #endif
#endif
 
/****************** C Compilers dependant keywords ****************************/
/* In HS mode and when the DMA is used, all variables and data structures dealing
   with the DMA during the transaction process should be 4-bytes aligned */    
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
  #if defined   (__GNUC__)        /* GNU Compiler */
    #define __ALIGN_END    __attribute__ ((aligned (4)))
    #define __ALIGN_BEGIN         
  #else                           
    #define __ALIGN_END
    #if defined   (__CC_ARM)      /* ARM Compiler */
      #define __ALIGN_BEGIN    __align(4)  
    #elif defined (__ICCARM__)    /* IAR Compiler */
      #define __ALIGN_BEGIN 
    #elif defined  (__TASKING__)  /* TASKING Compiler */
      #define __ALIGN_BEGIN    __align(4) 
    #endif /* __CC_ARM */  
  #endif /* __GNUC__ */ 
#else
  #define __ALIGN_BEGIN
  #define __ALIGN_END   
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
 
/* __packed keyword used to decrease the data type alignment to 1-byte */
#if defined (__CC_ARM)         /* ARM Compiler */
  #define __packed    __packed
#elif defined (__ICCARM__)     /* IAR Compiler */
  #define __packed    __packed
#elif defined   ( __GNUC__ )   /* GNU Compiler */                        
  #define __packed    __attribute__ ((__packed__))
#elif defined   (__TASKING__)  /* TASKING Compiler */
  #define __packed    __unaligned
#endif /* __CC_ARM */
 
/**
  * @}
  */ 
 
 
/** @defgroup USB_CONF_Exported_Types
  * @{
  */ 
/**
  * @}
  */ 
 
 
/** @defgroup USB_CONF_Exported_Macros
  * @{
  */ 
/**
  * @}
  */ 
 
/** @defgroup USB_CONF_Exported_Variables
  * @{
  */ 
/**
  * @}
  */ 
 
/** @defgroup USB_CONF_Exported_FunctionsPrototype
  * @{
  */ 
/**
  * @}
  */ 
 
 
#endif //__USB_CONF__H__
 
 
/**
  * @}
  */ 
 
/**
  * @}
  */ 
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
 
修改dikio.c

/*-----------------------------------------------------------------------*/
/* Low level disk I/O module skeleton for FatFs     (C)ChaN, 2016        */
/*-----------------------------------------------------------------------*/
/* If a working storage control module is available, it should be        */
/* attached to the FatFs via a glue function rather than modifying it.   */
/* This is an example of glue functions to attach various exsisting      */
/* storage control modules to the FatFs module with a defined API.       */
/*-----------------------------------------------------------------------*/
#include "diskio.h"            /* FatFs lower layer API */
 
//#include "ftl.h"     
#include "usbh_usr.h" 
 
 
//V1.1 20160124
//新增对U盘的支持                              
// 
 
//#define SD_CARD     3              //SD卡,卷标为0
//#define EX_FLASH     1            //外部spi flash,卷标为1
//#define EX_NAND      2            //外部nand flash,卷标为2
 
#define USB_DISK    0            //U盘,卷标为0
 
//对于W25Q256
//前25M字节给fatfs用,25M字节后,用于存放字库,字库占用6.01M.    剩余部分,给客户自己用     
#define FLASH_SECTOR_SIZE     512    
#define FLASH_SECTOR_COUNT     1024*25*2    //W25Q256,前25M字节给FATFS占用    
#define FLASH_BLOCK_SIZE       8             //每个BLOCK有8个扇区        
  
 
//获得磁盘状态
DSTATUS disk_status (
    BYTE pdrv        /* Physical drive nmuber to identify the drive */
)

    return RES_OK;
}  
//初始化磁盘
DSTATUS disk_initialize (
    BYTE pdrv                /* Physical drive nmuber to identify the drive */
)
{
    u8 res=0;        
    switch(pdrv)
    {
 
        case USB_DISK:        //U盘  
              res=!USBH_UDISK_Status();//U盘连接成功,则返回1.否则返回0    
            break;
        default:
            res=1; 
    }         
    if(res)return  STA_NOINIT;
    else return 0; //初始化成功 

//读扇区
//pdrv:磁盘编号0~9
//*buff:数据接收缓冲首地址
//sector:扇区地址
//count:需要读取的扇区数
DRESULT disk_read (
    BYTE pdrv,        /* Physical drive nmuber to identify the drive */
    BYTE *buff,        /* Data buffer to store read data */
    DWORD sector,    /* Sector address in LBA */
    UINT count        /* Number of sectors to read */
)
{
    u8 res=0; 
    if (!count)return RES_PARERR;//count不能等于0,否则返回参数错误              
    switch(pdrv)
    {
          case USB_DISK:    //U盘    
            res=USBH_UDISK_Read(buff,sector,count);                                      
            break;
        default:
            res=1; 
    }
   //处理返回值,将SPI_SD_driver.c的返回值转成ff.c的返回值
    if(res==0x00)return RES_OK;     
    else return RES_ERROR;       
}
//写扇区
//pdrv:磁盘编号0~9
//*buff:发送数据首地址
//sector:扇区地址
//count:需要写入的扇区数
DRESULT disk_write (
    BYTE pdrv,            /* Physical drive nmuber to identify the drive */
    const BYTE *buff,    /* Data to be written */
    DWORD sector,        /* Sector address in LBA */
    UINT count            /* Number of sectors to write */
)
{
    u8 res=0;  
    if (!count)return RES_PARERR;//count不能等于0,否则返回参数错误              
    switch(pdrv)
    {
        
        case USB_DISK:    //U盘 
            res=USBH_UDISK_Write((u8*)buff,sector,count); 
            break;
        default:
            res=1; 
    }
    //处理返回值,将SPI_SD_driver.c的返回值转成ff.c的返回值
    if(res == 0x00)return RES_OK;     
    else return RES_ERROR;    
}
//其他表参数的获得
//pdrv:磁盘编号0~9
//ctrl:控制代码
//*buff:发送/接收缓冲区指针
DRESULT disk_ioctl (
    BYTE pdrv,        /* Physical drive nmuber (0..) */
    BYTE cmd,        /* Control code */
    void *buff        /* Buffer to send/receive control data */
)
{
DRESULT res;                                           
     if(pdrv==USB_DISK)    //U盘
    {
        switch(cmd)
        {
            case CTRL_SYNC:
                res = RES_OK; 
                break;     
            case GET_SECTOR_SIZE:
                *(WORD*)buff=512;
                res = RES_OK;
                break;     
            case GET_BLOCK_SIZE:
                *(WORD*)buff=512;
                res = RES_OK;
                break;     
            case GET_SECTOR_COUNT:
                *(DWORD*)buff=USBH_MSC_Param.MSCapacity;
                res = RES_OK;
                break;
            default:
                res = RES_PARERR;
                break;
        }        
    }else res=RES_ERROR;//其他的不支持
    return res;
}
//获得时间
//User defined function to give a current time to fatfs module      */
//31-25: Year(0-127 org.1980), 24-21: Month(1-12), 20-16: Day(1-31) */                                                                                                                                                                                                                                          
//15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */                                                                                                                                                                                                                                                
DWORD get_fattime (void)
{                 
    return 0;
}             
//动态分配内存
void *ff_memalloc (UINT size)            
{
//    return (void*)mymalloc(SRAMIN,size);
}
//释放内存
void ff_memfree (void* mf)         
{
//    myfree(SRAMIN,mf);
}
 
 
 
 
 
 
 
 
 
最后我的ffconf配置

/*---------------------------------------------------------------------------/
/  FatFs - FAT file system module configuration file  R0.12  (C)ChaN, 2016
/---------------------------------------------------------------------------*/
 
#define _FFCONF 88100    /* Revision ID */
 
/*---------------------------------------------------------------------------/
/ Function Configurations
/---------------------------------------------------------------------------*/
 
#define _FS_READONLY    0
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
/  Read-only configuration removes writing API functions, f_write(), f_sync(),
/  f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
/  and optional writing functions as well. */
 
 
#define _FS_MINIMIZE    0
/* This option defines minimization level to remove some basic API functions.
/
/   0: All basic functions are enabled.
/   1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
/      are removed.
/   2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
/   3: f_lseek() function is removed in addition to 2. */
 
 
#define    _USE_STRFUNC    1
/* This option switches string functions, f_gets(), f_putc(), f_puts() and
/  f_printf().
/
/  0: Disable string functions.
/  1: Enable without LF-CRLF conversion.
/  2: Enable with LF-CRLF conversion. */
 
 
#define _USE_FIND        0
/* This option switches filtered directory read functions, f_findfirst() and
/  f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
 
 
#define    _USE_MKFS        1
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
 
 
#define    _USE_FASTSEEK    1
/* This option switches fast seek function. (0:Disable or 1:Enable) */
 
 
#define    _USE_EXPAND        0
/* This option switches f_expand function. (0:Disable or 1:Enable) */
 
 
#define _USE_CHMOD        0
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
/  (0:Disable or 1:Enable) Also _FS_READONLY needs to be 0 to enable this option. */
 
 
#define _USE_LABEL        1
/* This option switches volume label functions, f_getlabel() and f_setlabel().
/  (0:Disable or 1:Enable) */
 
 
#define    _USE_FORWARD    0
/* This option switches f_forward() function. (0:Disable or 1:Enable)
/  To enable it, also _FS_TINY need to be 1. */
 
 
/*---------------------------------------------------------------------------/
/ Locale and Namespace Configurations
/---------------------------------------------------------------------------*/
 
#define _CODE_PAGE    437    
/* This option specifies the OEM code page to be used on the target system.
/  Incorrect setting of the code page can cause a file open failure.
/
/   1   - ASCII (No extended character. Non-LFN cfg. only)
/   437 - U.S.
/   720 - Arabic
/   737 - Greek
/   771 - KBL
/   775 - Baltic
/   850 - Latin 1
/   852 - Latin 2
/   855 - Cyrillic
/   857 - Turkish
/   860 - Portuguese
/   861 - Icelandic
/   862 - Hebrew
/   863 - Canadian French
/   864 - Arabic
/   865 - Nordic
/   866 - Russian
/   869 - Greek 2
/   932 - Japanese (DBCS)
/   936 - Simplified Chinese (DBCS)
/   949 - Korean (DBCS)
/   950 - Traditional Chinese (DBCS)
*/
 
 
#define    _USE_LFN    1
#define    _MAX_LFN    255
/* The _USE_LFN switches the support of long file name (LFN).
/
/   0: Disable support of LFN. _MAX_LFN has no effect.
/   1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
/   2: Enable LFN with dynamic working buffer on the STACK.
/   3: Enable LFN with dynamic working buffer on the HEAP.
/
/  To enable the LFN, Unicode handling functions (option/unicode.c) must be added
/  to the project. The working buffer occupies (_MAX_LFN + 1) * 2 bytes and
/  additional 608 bytes at exFAT enabled. _MAX_LFN can be in range from 12 to 255.
/  It should be set 255 to support full featured LFN operations.
/  When use stack for the working buffer, take care on stack overflow. When use heap
/  memory for the working buffer, memory management functions, ff_memalloc() and
/  ff_memfree(), must be added to the project. */
 
 
#define    _LFN_UNICODE    0
/* This option switches character encoding on the API. (0:ANSI/OEM or 1:Unicode)
/  To use Unicode string for the path name, enable LFN and set _LFN_UNICODE = 1.
/  This option also affects behavior of string I/O functions. */
 
 
#define _STRF_ENCODE    0
/* When _LFN_UNICODE == 1, this option selects the character encoding on the file to
/  be read/written via string I/O functions, f_gets(), f_putc(), f_puts and f_printf().
/
/  0: ANSI/OEM
/  1: UTF-16LE
/  2: UTF-16BE
/  3: UTF-8
/
/  This option has no effect when _LFN_UNICODE == 0. */
 
 
#define _FS_RPATH    0
/* This option configures support of relative path.
/
/   0: Disable relative path and remove related functions.
/   1: Enable relative path. f_chdir() and f_chdrive() are available.
/   2: f_getcwd() function is available in addition to 1.
*/
 
 
/*---------------------------------------------------------------------------/
/ Drive/Volume Configurations
/---------------------------------------------------------------------------*/
 
#define _VOLUMES    4//支持4个磁盘
/* Number of volumes (logical drives) to be used. */
 
 
#define _STR_VOLUME_ID    0
#define _VOLUME_STRS    "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3"
/* _STR_VOLUME_ID switches string support of volume ID.
/  When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
/  number in the path name. _VOLUME_STRS defines the drive ID strings for each
/  logical drives. Number of items must be equal to _VOLUMES. Valid characters for
/  the drive ID strings are: A-Z and 0-9. */
 
 
#define    _MULTI_PARTITION    0
/* This option switches support of multi-partition on a physical drive.
/  By default (0), each logical drive number is bound to the same physical drive
/  number and only an FAT volume found on the physical drive will be mounted.
/  When multi-partition is enabled (1), each logical drive number can be bound to
/  arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
/  funciton will be available. */
 
 
#define    _MIN_SS        512
#define    _MAX_SS        512
/* These options configure the range of sector size to be supported. (512, 1024,
/  2048 or 4096) Always set both 512 for most systems, all type of memory cards and
/  harddisk. But a larger value may be required for on-board flash memory and some
/  type of optical media. When _MAX_SS is larger than _MIN_SS, FatFs is configured
/  to variable sector size and GET_SECTOR_SIZE command must be implemented to the
/  disk_ioctl() function. */
 
 
#define    _USE_TRIM    0
/* This option switches support of ATA-TRIM. (0:Disable or 1:Enable)
/  To enable Trim function, also CTRL_TRIM command should be implemented to the
/  disk_ioctl() function. */
 
 
#define _FS_NOFSINFO    0
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
/  option, and f_getfree() function at first time after volume mount will force
/  a full FAT scan. Bit 1 controls the use of last allocated cluster number.
/
/  bit0=0: Use free cluster count in the FSINFO if available.
/  bit0=1: Do not trust free cluster count in the FSINFO.
/  bit1=0: Use last allocated cluster number in the FSINFO if available.
/  bit1=1: Do not trust last allocated cluster number in the FSINFO.
*/
 
 
 
/*---------------------------------------------------------------------------/
/ System Configurations
/---------------------------------------------------------------------------*/
 
#define    _FS_TINY    0
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
/  At the tiny configuration, size of the file object (FIL) is reduced _MAX_SS bytes.
/  Instead of private sector buffer eliminated from the file object, common sector
/  buffer in the file system object (FATFS) is used for the file data transfer. */
 
 
#define _FS_EXFAT    1
/* This option switches support of exFAT file system in addition to the traditional
/  FAT file system. (0:Disable or 1:Enable) To enable exFAT, also LFN must be enabled.
/  Note that enabling exFAT discards C89 compatibility. */
 
 
#define _FS_NORTC    0
#define _NORTC_MON    3
#define _NORTC_MDAY    1
#define _NORTC_YEAR    2016
/* The option _FS_NORTC switches timestamp functiton. If the system does not have
/  any RTC function or valid timestamp is not needed, set _FS_NORTC = 1 to disable
/  the timestamp function. All objects modified by FatFs will have a fixed timestamp
/  defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR in local time.
/  To enable timestamp function (_FS_NORTC = 0), get_fattime() function need to be
/  added to the project to get current time form real-time clock. _NORTC_MON,
/  _NORTC_MDAY and _NORTC_YEAR have no effect. 
/  These options have no effect at read-only configuration (_FS_READONLY = 1). */
 
 
#define    _FS_LOCK    0
/* The option _FS_LOCK switches file lock function to control duplicated file open
/  and illegal operation to open objects. This option must be 0 when _FS_READONLY
/  is 1.
/
/  0:  Disable file lock function. To avoid volume corruption, application program
/      should avoid illegal open, remove and rename to the open objects.
/  >0: Enable file lock function. The value defines how many files/sub-directories
/      can be opened simultaneously under file lock control. Note that the file
/      lock control is independent of re-entrancy. */
 
 
#define _FS_REENTRANT    0
#define _FS_TIMEOUT        1000
#define    _SYNC_t            HANDLE
/* The option _FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
/  module itself. Note that regardless of this option, file access to different
/  volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
/  and f_fdisk() function, are always not re-entrant. Only file/directory access
/  to the same volume is under control of this function.
/
/   0: Disable re-entrancy. _FS_TIMEOUT and _SYNC_t have no effect.
/   1: Enable re-entrancy. Also user provided synchronization handlers,
/      ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
/      function, must be added to the project. Samples are available in
/      option/syscall.c.
/
/  The _FS_TIMEOUT defines timeout period in unit of time tick.
/  The _SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
/  SemaphoreHandle_t and etc.. A header file for O/S definitions needs to be
/  included somewhere in the scope of ff.c. */
 
 
/*--- End of configuration options ---*/
注意我没有支持中文,所以创建的名字,目录写的数据是不能写中文的否则会乱码,最后po一下实现的图片


 ———————————————— 
版权声明:本文为CSDN博主「云漂」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_36305492/article/details/90438210

最后

以上就是纯情钢铁侠为你收集整理的STM32f105写U盘的全部内容,希望文章能够帮你解决STM32f105写U盘所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部