精华内容
下载资源
问答
  • STM32F105标准库读写USB写入csv文件

    千次阅读 2019-05-22 11:28:41
    所用的芯片是STM32F105RB,注意必须要有OTG的功能的芯片才可以的单板驱动USB向其内部读写数据,没有OTG功能只能做从机我理解为可以和电脑连接后STM32内部flash做为U盘. 从图上看我们知道只有F105/107和F2/4的...

     

    这几天需要往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 Host\r\n");
    	Debug_Com_printf("> USB Host library started.\r\n");
    	Debug_Com_printf("  USB Host Library v2.1.0\r\n\r\n");
    }
    
    /**
    * @brief  USBH_USR_DeviceAttached 
    *         //检测到U盘插入
    * @param  None
    * @retval None
    */
    void USBH_USR_DeviceAttached(void)
    {
    	Debug_Com_printf("检测到USB设备插入!\r\n");
    }
    
    //获取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设备拔出!\r\n");
    }
    /**
    * @brief  USBH_USR_ResetUSBDevice 
       //复位从机
    * @param  None
    * @retval None
    */
    void USBH_USR_ResetDevice(void)
    {
    		Debug_Com_printf("复位设备...\r\n");
      /* 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设备!\r\n");
     	}  
    	else if(DeviceSpeed==HPRT0_PRTSPD_FULL_SPEED)
    	{
    		Debug_Com_printf("全速(FS)USB设备!\r\n"); 
    	}
    	else if(DeviceSpeed==HPRT0_PRTSPD_LOW_SPEED)
    	{
    		Debug_Com_printf("低速(LS)USB设备!\r\n");  
    	}
    	else
    	{
    		Debug_Com_printf("设备错误!\r\n");  
    	}
    }
    
    /**
    * @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: %04Xh\r\n" , (uint32_t)(*hs).idVendor); 
    	Debug_Com_printf("PID: %04Xh\r\n" , (uint32_t)(*hs).idProduct); 
      
    }
    
    /**
    * @brief  USBH_USR_DeviceAddressAssigned 
    *        //从机地址分配成功
    * @param  None
    * @retval None
    */
    void USBH_USR_DeviceAddressAssigned(void)
    {
      	Debug_Com_printf("从机地址分配成功!\r\n");   
    }
    
    
    /**
    * @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("可移动存储器设备!\r\n"); 
    	}else if((*id).bInterfaceClass==0x03)
    	{
    		Debug_Com_printf("HID 设备!\r\n"); 
    	}    
    }
    
    /**
    * @brief  USBH_USR_Manufacturer_String 
    *         //获取到设备Manufacturer String
    * @param  Manufacturer String 
    * @retval None
    */
    void USBH_USR_Manufacturer_String(void *ManufacturerString)
    {
     Debug_Com_printf("Manufacturer: %s\r\n",(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: %s\r\n",(char *)ProductString); 
    //  LCD_UsrLog("Product : %s\n", (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: %s\r\n",(char *)SerialNumString);  
    	
    } 
    
    
    
    /**
    * @brief  EnumerationDone 
    *       //设备USB枚举完成
    * @param  None
    * @retval None
    */
    void USBH_USR_EnumerationDone(void)
    {
      
    	Debug_Com_printf("设备枚举完成!\r\n\r\n"); 
      
    } 
    
    
    /**
    * @brief  USBH_USR_DeviceNotSupported
    *      //无法识别的USB设备
    * @param  None
    * @retval None
    */
    void USBH_USR_DeviceNotSupported(void)
    {
    		Debug_Com_printf("无法识别的USB设备!\r\n\r\n"); 
    //  LCD_ErrLog ("No registered class for this device. \n\r");
    }  
    
    
    /**
    * @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("跳过用户确认步骤!\r\n");
    	return USBH_USR_RESP_OK;
    }  
    
    /**
    * @brief  USBH_USR_OverCurrentDetected
    *        //USB接口电流过载
    * @param  None
    * @retval Status
    */
    void USBH_USR_OverCurrentDetected (void)
    {
    		Debug_Com_printf("端口电流过大!!!\r\n");
    //  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("写入完成\r\n");
    	while(HCD_IsDeviceConnected(&USB_OTG_Core))//设备连接成功
    	{	
      
    
    	}
    
     	f_mount(0,"35:",1); 	//卸载U盘
      Debug_Com_printf("USB已卸载\r\n");
    	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("开始执行用户程序!!!\r\n");
    			  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("读写错误!!!\r\n");
    				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("读写错误!!!\r\n");
    				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一下实现的图片

    展开全文
  • STM32USB键盘

    2015-07-11 12:39:29
    参考圈圈的USB书,移植STM32USB鼠标例程,实现NumLock键的取反,小键盘1的写入
  • STM32F407 USB连接电脑无反应

    千次阅读 2019-06-29 19:27:32
    1.在KEIL编译时先选择不适用microlib 编译一遍,此时插上USB电脑会显示未识别的USB。...2.选择使用microlib再编译一遍,将程序写入STM32F407,此时再次将USB接口插入PC端,就可识别相应USB接口,原因暂时未知。 ...

    1.在KEIL编译时先选择不适用microlib 编译一遍,此时插上USB电脑会显示未识别的USB。

    2.选择使用microlib再编译一遍,将程序写入STM32F407,此时再次将USB接口插入PC端,就可识别相应USB接口,原因暂时未知。

    展开全文
  • STM32 USB IAP 调试经验

    2019-09-19 21:16:06
    最近在搞USB IAP 遇到很多坎坷,一个个坑 首先是 boot引导 要做好flash 操作, 能够顺利写入flash 写入失败 要注意 解锁 ,写入期间禁止访问,写入期间不要读取, 修改flash 要注意地址 启动地址 以及 跳转...

    最近在搞USB IAP 

    遇到很多坎坷,一个个坑

    首先是 boot引导  要做好flash 操作, 能够顺利写入flash

    写入失败  要注意  解锁  ,写入期间禁止访问,写入期间不要读取,

     

    修改flash 要注意地址 启动地址 以及 跳转函数

    删除扇区的时候要注意扇区号以及扇区的划分地址,这个请查看芯片的参考手册

     

    跳转函数的处理 不注意就会出错  ,不过这个例子网上很多

    跳转前 网上有人说要关中断,我试了 不行 ,这不是最好的处理办法,我没成功

    我没有关中断 反而成功了

    具体操作是 跳转前确保把之前用到的外设全部Deinit,BOOT程序尽量减少外设的使用,减少中断源,

    特别是USB中断源很多,关闭USB ,关闭USB调试,关闭定时器,关闭串口,

    然后跳转,不用关中断

     

     

     

     

     

     

     

    展开全文
  • STM32USB虚拟COM刷新W25XXX数据 单片机需要显示多张图片,以及显示中文,但数据量太大,单片机内部的ROM不够,只能存在外部flash中,所以需要将大量的数据写入flash中。最近一直在查阅资料,怎么更新外部flash中的...

    STM32USB虚拟COM刷新W25XXX数据

    单片机需要显示多张图片,以及显示中文,但数据量太大,单片机内部的ROM不够,只能存在外部flash中,所以需要将大量的数据写入flash中。最近一直在查阅资料,怎么更新外部flash中的数据。

    方法一:将数据存入ROM中,程序执行时,读取ROM中的数据,写入flash。这种方法一次性写入的数据比较少,若是下载一次程序,写入一次,再改动flash地址,再下载程序,再写入~~~~~说不下去了。

    方法二:使用串口调试助手,将图片数据制作成bin文件,发送给单片机,单片机在串口中断中写入flash。当STM32的串口总线被其他设备占用时,这种方法就行不通了。

    方法三:使用USB模拟串口,再如方法二的步骤刷新flash数据。

    本次内容讲述的就是串口总线被其他设备占用,使用方法三刷新flash数据。我也会简单介绍一下怎么使用USB模拟串口回显数据。

    W25XXX写入数据

    flash内部只能由1变为0,所以每次写入数据时,需要先将flash擦除。

    扇区擦除:每个扇区4K大小,擦除的最小单位。
    块擦除:每个块64K大小。
    片擦除:将整个flash擦除。

    步骤如下

    1.打开cube软件

    2.配置USB
    在这里插入图片描述

    3.配置USB_DEVICE
    在这里插入图片描述

    4.时钟那些不作介绍,直接生成文件。

    打开工程

    1.打开usbs_cdc_if.c文件
    在这里插入图片描述

    2.在接收函数里加上发送数据函数,贴上代码

    static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
    {
      /* USER CODE BEGIN 6 */
      USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
      USBD_CDC_ReceivePacket(&hUsbDeviceFS);
    	
    
      USBD_CDC_SetTxBuffer(&hUsbDeviceFS, &Buf[0], *Len);   
      USBD_CDC_TransmitPacket(&hUsbDeviceFS);
      return (USBD_OK);
      /* USER CODE END 6 */
    }
    

    3.如果使用串口回显,就不需要更改其他的了,下载程序。打开串口调试助手发送数据,结果如下图
    在这里插入图片描述
    64字节以内,发送什么数据,返回的也是什么数据。因为USB一次性只能接收64字节数据,所以我发送70字节的数据,只返回了64字节。发送一大串数据,也会返回,只不过我没有仔细核对。

    改动程序,可以返回大量数据

    1.改动接收缓冲区大小

    #define APP_RX_DATA_SIZE  256     //将1000改为256
    #define APP_TX_DATA_SIZE  1000
    

    2.修改CDC_Receive_FS函数

    uint16_t Data_Len, temp, timeout;      //定义的全局变量
    
    static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
    {
    	Data_Len +=*Len;
    	if(Data_Len<APP_RX_DATA_SIZE)
    	{
    		USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS + Data_Len);	   //设置下一次接收数据的位置
    		USBD_CDC_ReceivePacket(&hUsbDeviceFS);                             //准备接收数据
    	}
    	else  //接收缓冲区已满
    	{
    		timeout = 0xffff;
    		temp = !(Data_Len%64);  //判断长度是否为64整数倍
    		while( CDC_Transmit_FS(UserRxBufferFS, Data_Len - temp) != USBD_OK && timeout--);
    		 
    		if(temp)  //当发送数据为64整数倍时,无法发送成功,故分成2次发送
    		{
    			 while( CDC_Transmit_FS(UserRxBufferFS + Data_Len -1, temp) != USBD_OK && timeout--);
    		}
    		
    
    		//发送完毕,再次设置
    		Data_Len = 0;
    		USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS + Data_Len);	   //设置下一次接收数据的位置
    		USBD_CDC_ReceivePacket(&hUsbDeviceFS);                             //准备接收数据
    	}
      return (USBD_OK);
      /* USER CODE END 6 */
    }
    

    当发送的数据为64的整数倍时,需要将数据分为两次发送(经其他博主验证)

    3.下载程序,查看结果
    在这里插入图片描述
    设置的缓冲区大小为256,当缓冲区存满了数据,才会输出。

    步入正题,使用USB虚拟串口刷新flash数据

    1.每次上电,初始化时,就将flash整片擦除。

    2.每满256字节时,就写入一次数据。

    3.修改CDC_Receive_FS函数

    uint32_t FlashAdd = 0x00000;
    static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
    {
    	//将已接收数据长度赋值给USB_S.ReLen
        USB_S.ReLen += *Len;
    	//判断是否有结束标志以及接收数据长度是否达到UserRxBufferFS长度上限
    		if( USB_S.ReLen<APP_RX_DATA_SIZE)
    		{
    		  //设置下一次接收数据的位置
    	        USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS + USB_S.ReLen);
    	        USBD_CDC_ReceivePacket(&hUsbDeviceFS);   //准备接收数据
    		}
    		else  //长度达到,或者检测到标志位,触发数据输出
    		{
    			  SPI_FLASH_PageWrite(UserRxBufferFS, FlashAdd, 256);		
    
    				FlashAdd += 256;
    				USB_S.ReLen = 0;
    
    			 
    				USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS);
    				USBD_CDC_ReceivePacket(&hUsbDeviceFS);
    		}
        return (USBD_OK);
    }
    

    4.打开Image2LCD制作bin文件
    在这里插入图片描述

    5.打开串口调试助手,写入数据
    在这里插入图片描述
    换了个串口调试助手,这个是正点原子的,这一个串口调试助手末尾会发0X0D,0X0A,如有需要可以以这两个数据写协议,或者自己写一个协议,并在程序中进行校验数据是否写入正确。

    flash驱动文件在上一篇文章,也可以直接找野火的例程。

    结尾

    发送数据时,有时候开头的数据写不进flash,暂未找到原因。

    展开全文
  • 但是最近,有一些朋友反映,移植起来有点麻烦,希望提供stmf103的例程,所以前几天我买了正点原子的战舰mini开发板,MCU是stm32f103RCT6。使用串口1和NFC开发板连接。USB读卡器视频演示 :http://...
  • STM32f105写U盘

    千次阅读 2019-08-19 18:45:43
    这几天需要往U盘里读写数据,需要升级...所用的芯片是STM32F105RB,注意必须要有OTG的功能的芯片才可以的单板驱动USB向其内部读写数据,没有OTG功能只能做从机我理解为可以和电脑连接后STM32内部flash做为U盘....
  • 1.主控STM32F103RCT6+...2.stm32USB口连接电脑,电脑识别为USB大容量设备; 3.将Bin文件拖入U盘,当存在多个Bin文件,默认第一个; 4.串口1会打印Flash内的Bin文件,按键1开始写入内部Flash; 5.按键2,跳转至APP运行;
  • STM32F103x为控制核心的产品定制成USB HID设备,通过USB接口可方便地实现上位机与下位机的通信。利用STM32F103x的Flash可编程的特性,将写入的数据保存起来,这样在系统中便可以使用这些设定数据,从而实现产品...
  • STM32_IIC程序_寄存器

    2018-05-02 14:46:17
    学习STM32模拟IIC的使用,驱动24C02实现EEPROM数据读写. 硬件资源: 1,DS0(连接在PA8) 2,串口1(波特率:9600,PA9/PA10连接在板载USB转串口芯片CH340上面) 3,ALIENTEK 2.8/3.5/4.3/7寸TFTLCD模块(通过GPIO驱动,...
  • 但是同样还是需要设计两个程序,在Bootloader程序通过某种通信方式,如 USB、 USART接收APP程序数据,并写入Flash中,然后跳转到APP程序的首地址,开始运行第二个程序。 首先我们来分析只有一个APP程序的时候STM
  • 本编程手册介绍了如何烧写STM32F101xx、STM32F102xx和STM32F103xx微控制器的闪存存储器。为方便起见,在本文中出特别说明外,统称它们为STM32F10xxx。 STM32F10xxx内嵌的闪存存储器可以用于在线编程(ICP)或在程序中...
  • 利用U盘通过FatFs烧写BIN文件到flash实现芯片的在线编程(stm32F407+FatFs+USBdisk+Flash) 取消关注 | 14 ... 修改记录 通过U盘里面的image.bin文件来升级更新flash,实现脱机烧写程序 在昨天Fatfs+usbdisk能够...
  • STM32f103VE学习之预备知识

    千次阅读 2018-08-24 20:31:45
    STM32f103VE 预备知识 ** ISP(In-System Programming):在系统可编程,指电路板上的芯片可以编程写入最终用户代码, 而不需要从电路板上取下器件,已经编程的器件也可以用 ISP 方式擦除或再编程。 即可以...
  • 最近因为学习任务的原因需要使用matlab做上位机程序与stm32单片机通信,可是实现过程中出现了奇怪的问题,具体描述如下: 在烧录好stm32端程序后,可以通过各种串口调试助手实现数据的收发,功能正常。可是在使用...
  • STM32F10xxx参考手册

    热门讨论 2009-04-13 13:39:08
    STM32F10xxx rev7v3参考手册. 南京万利提供的原始翻译文档. 本译文仅供参考,如有翻译错误,请以英文原稿为准。请读者随时注意在ST网站下载更新版本. 本译文仅供参考,如有翻译错误,请以英文原稿为准。请读者随时...
  • ISP 的时候需要用到(bootloader)自举程序,自举程序存储在 STM32 器件的内部自举ROM 存储器(系统存储器)中。其主要任务是通过一种可用的串行外设( USART、 CAN、USB、 I2C 等)将应用程序下载到内部 Flash 中。每...
  • 最近在做STM32F105的U盘升级功能,其中bootloader中的FLASH写入,APP跳转等均参考了正点原子的F1串口IAP实验。值得注意的是F103的USB是不带HOST功能的,上次做的INIT Kit小板就使用了103的芯片,导致没办法加U盘升级...
  • 自从接触STM32的开发以来,为方便程序的调试,开发前期一般使用JLink或STLink仿真器来进行程序的烧写和调试,进而引发了对J-Link烧写固件的原理的疑惑 分析问题: 提出问题: 解决问题: 持续改进: 初步...
  • 3、创建一个TXT文件,并写入STM32 Connectivity line Host Demo application using FAT_FS ”,在电脑端打开该TXT文件,其写入字符串正确。 4、显示一张BMP格式的图片(BMP图片显示最直接,就先弄它了),来自于...
  • STM32 keil mdk启动代码发分析_转2010年01月29日 星期五 13:50 ;// <h> Stack Configuration ;// <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> ;// </h> Stack_Size EQU 0x00000200 ;//定义堆栈大小 AREA ...
  • 使用资源:STM32F407ZGT6芯片,板载DAC1通道1(定时器触发),板载ADC1通道5,板载DMA1数据流5,通道7,CH340串口USB模块。大体思想:使用u16的数组产生原始正弦波数据序列,通过DMA1将原始数据写入DAC寄存器,同时...
  • RFID阅读器基于STM32单片机设计,芯片型号选择为STM32F103RBT6。该芯片为LQFP64封装, 内部有128 KB Flash和20 KB RAM,采用32位的ARM CortexTM-M3内核, 最高支持主频72 MHz,拥有2个SPI接口、 2个USART接口、1个USB...
  • stm32 多级菜单 温湿度数据写入u盘。可以快速入门菜单编写。使用状态机切换菜单显示。采用usb读写芯片对u盘进行控制读写
  • usb_bootloader.zip

    2020-04-29 21:45:33
    抛弃繁琐的USB DFU,抛弃落后的串口升级,让我们来谈谈U盘升级STM32 1. 为什么设计这个BOOT LOADER 在电子产品开发过程中,为了满足市场需要,经常是先开发出一个简单可用的版本,然后逐步迭代升级,修复bug,并...
  • KERNEL=="ttyUSB*", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", MODE:="0777", SYMLINK+="stm32board" 但是如果出现相同id设备,如上面#号开头的两个设备,id号完全一样,就需要...
  • 公司要用STM8S来做东西,量大了需要个脱机烧写器,闲来无事就做了个,用料如下:STM32F101R8主控 SWIM接口 LCD1602显示校验和、烧录状态、故障信息、烧录次数、剩余烧录次数等 3D打印外壳 LED指示状态 蜂鸣器报警 双...
  • 硬件框架主要使用了ART-PI开发板上的STM32H750处理器的SPI,Timer, UART, 板载资源使用了LED,其它硬件模块包括ST的六轴传感器以及自备的USB转串口板。 软件框架说明软件模块说明演示效果视频演示: 比赛感悟通过参与...
  • 如果不能在启动目录(默认为 %systemroot%System32)中找到该文件,将试着在 Windows 安装 CD 中找到它。如果有多引导系统的计算机,必须保证是在包含 Windows 的驱动器上使用该命令。 Diskpart  创建和删除硬盘...

空空如也

空空如也

1 2
收藏数 30
精华内容 12
关键字:

usb写入stm32