历史上的今天
今天是:2025年02月02日(星期日)
2020年02月02日 | STM32F105标准库读写USB写入csv文件
2020-02-02 来源:eefocus
这几天需要往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
*
*
© COPYRIGHT 2012 STMicroelectronics
*
* 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
史海拾趣
|
1、电子技术资料尽量看西方英文原版的 理由:电子技术发源于西方,那边的人对许多电路问题有很深的认识,研究的很细,条理很清晰,对产品开发的指导性强。尽管国内也有人在研究,但有真正指导生产意义的刊物太少,市面上 ...… 查看全部问答> |
|
COMSTAT ComStat ClearCommError(m_hCom,&dwErrorFlags,&ComStat); 这个函数用于清除硬件错误和获取状态(我是的重叠操作) 我WriteFile后,ReadFile前怎么这个结构的cboutbuf永远是0,为什么不是我写入的字节 单步调试N此不知为何?恭请高手解 ...… 查看全部问答> |
|
这是初始化的一段代码,我初始化后,再往芯片发送随机数就不成功,我怀疑是初始化后熔断了熔丝造成的, 熔丝代码: ucData[0]= (uchar)CM_FAB; ucReturn = cm_BurnFuse(ucData[0]); i ...… 查看全部问答> |
|
cmd文件内一段代码如下: _EVENT72 = EVENT72;_EVENT73 = EVENT73;_EVENT74 = EVENT74;_EVENT75 = EVENT75;_EVENT76 = EVENT76;_EVENT77 = EVENT77;_EVENT78 = EVENT78; CCS 4内,debug运行后报错: absolute symbol \"_EVENT72\" being ...… 查看全部问答> |
|
stm8与51核变量定义区域比较: 1)idata与@tiny: 熟悉51核的都知道,idata是定义内部ram地址的,而stm8的@tin ...… 查看全部问答> |




