主机环境:Windows 7 SP1
开发环境:MDK5.14
目标板:STM32F103C8T6
开发库:STM32F1Cube库和STM32_USB_Device_Library
STM32Cube库中提供了一些有关USB的例程,在其工程目录下的Applications目录中,这里打开STM3210E_EVAL目录,可以看到如下例程:
这里选取一个简单的例子CDC_Standalone,为一个USB通信例程,具体实现是一个USB转串口的功能,相当于USB串口线。把示例里面的inc和src目录下的文件拷贝到新建工程中,这里是把跟usb通信相关的文件放到了vcp目录下。文件目录结构如下:
其中BSP目录很简单,由于所购买的单板只用到了USB,UART模块以及一个LED灯,原理图如下:
其中PA15引脚连接了一个LED灯,如下:
因此在stm32f103_demo文件中只添加了led的操作,源文件如下:
/**
******************************************************************************
* @file stm32f103_demo.c
* @author MCD Application Team
* @version V6.0.0
* @date 13-October-2015
* @brief This file provides a set of firmware functions to manage Leds,
* for STM32F103_DEMO
******************************************************************************
* @attention
*
* © COPYRIGHT(c) 2014 STMicroelectronics
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "STM32f103_demo.h"
/** @addtogroup BSP
* @{
*/
/** @defgroup STM32F103_DEMO STM32F103-DEMO
* @{
*/
/** @defgroup STM32F103_DEMO_Common STM32F103-DEMO Common
* @{
*/
/** @defgroup STM32F103_DEMO_Private_TypesDefinitions Private Types Definitions
* @{
*/
/**
* @}
*/
/** @defgroup STM32F103_DEMO_Private_Defines Private Defines
* @{
*/
/**
* @brief STM32103 EVAL BSP Driver version number V6.0.0
*/
#define __STM32F103_DEMO_BSP_VERSION_MAIN (0x06) /*!< [31:24] main version */
#define __STM32F103_DEMO_BSP_VERSION_SUB1 (0x00) /*!< [23:16] sub1 version */
#define __STM32F103_DEMO_BSP_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */
#define __STM32F103_DEMO_BSP_VERSION_RC (0x00) /*!< [7:0] release candidate */
#define __STM32F103_DEMO_BSP_VERSION ((__STM32F103_DEMO_BSP_VERSION_MAIN << 24)\
|(__STM32F103_DEMO_BSP_VERSION_SUB1 << 16)\
|(__STM32F103_DEMO_BSP_VERSION_SUB2 << 8 )\
|(__STM32F103_DEMO_BSP_VERSION_RC))
/**
* @}
*/
/** @defgroup STM32F103_DEMO_Private_Variables Private Variables
* @{
*/
/**
* @brief LED variables
*/
GPIO_TypeDef* LED_PORT[LEDn] = {LED_GPIO_PORT};
const uint16_t LED_PINS[LEDn] = {LED_PIN};
/**
* @brief This method returns the STM32103 EVAL BSP Driver revision
* @retval version : 0xXYZR (8bits for each decimal, R for RC)
*/
uint32_t BSP_GetVersion(void)
{
return __STM32F103_DEMO_BSP_VERSION;
}
/**
* @brief Configures LED GPIO.
* @param Led: Specifies the Led to be configured.
* This parameter can be one of following parameters:
* @arg LED
* @retval None
*/
void BSP_LED_Init(Led_TypeDef Led)
{
GPIO_InitTypeDef gpioinitstruct = {0};
/* Enable the GPIO_LED clock */
LED_GPIO_CLK_ENABLE();
__HAL_RCC_AFIO_CLK_ENABLE();
__HAL_AFIO_REMAP_SWJ_DISABLE();
/* Configure the GPIO_LED pin */
gpioinitstruct.Pin = LED_PINS[Led];
gpioinitstruct.Mode = GPIO_MODE_OUTPUT_PP;
gpioinitstruct.Pull = GPIO_NOPULL;
gpioinitstruct.Speed = GPIO_SPEED_HIGH;
HAL_GPIO_Init(LED_PORT[Led], &gpioinitstruct);
HAL_GPIO_WritePin(LED_PORT[Led], LED_PINS[Led], GPIO_PIN_RESET);
}
/**
* @brief Turns selected LED On.
* @param Led: Specifies the Led to be set on.
* This parameter can be one of following parameters:
* @arg LED
* @retval None
*/
void BSP_LED_On(Led_TypeDef Led)
{
HAL_GPIO_WritePin(LED_PORT[Led], LED_PINS[Led], GPIO_PIN_RESET);
}
/**
* @brief Turns selected LED Off.
* @param Led: Specifies the Led to be set off.
* This parameter can be one of following parameters:
* @arg LED
* @retval None
*/
void BSP_LED_Off(Led_TypeDef Led)
{
HAL_GPIO_WritePin(LED_PORT[Led], LED_PINS[Led], GPIO_PIN_SET);
}
/**
* @brief Toggles the selected LED.
* @param Led: Specifies the Led to be toggled.
* This parameter can be one of following parameters:
* @arg LED
* @retval None
*/
void BSP_LED_Toggle(Led_TypeDef Led)
{
HAL_GPIO_TogglePin(LED_PORT[Led], LED_PINS[Led]);
}
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
/**
******************************************************************************
* @file stm32f103_demo.h
* @author MCD Application Team
* @version V6.0.0
* @date 13-October-2015
* @brief This file contains definitions for STM32F103_DEMO's LEDs,
* hardware resources.
******************************************************************************
* @attention
*
* © COPYRIGHT(c) 2014 STMicroelectronics
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F103_DEMO_H
#define __STM32F103_DEMO_H
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup BSP
* @{
*/
/** @addtogroup STM32F103_DEMO
* @{
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32f1xx_hal.h"
/** @addtogroup STM32F103_DEMO_Common STM3210E-EVAL Common
* @{
*/
/** @defgroup STM32F103_DEMO_Exported_Types Exported Types
* @{
*/
/**
* @brief LED Types Definition
*/
typedef enum
{
LED = 0,
LED_GREEN = LED,
} Led_TypeDef;
/**
* @}
*/
/** @defgroup STM32F103_DEMO_Exported_Constants Exported Constants
* @{
*/
/**
* @brief Define for STM32F103_DEMO board
*/
#if !defined (USE_STM32F103_DEMO)
#define USE_STM32F103_DEMO
#endif
/** @addtogroup STM32F103_DEMO_LED
* @{
*/
#define LEDn 1
#define LED_PIN GPIO_PIN_15 /* PA.15*/
#define LED_GPIO_PORT GPIOA
#define LED_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define LED_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()
/** @addtogroup STM32F103_DEMO_Exported_Functions
* @{
*/
uint32_t BSP_GetVersion(void);
void BSP_LED_Init(Led_TypeDef Led);
void BSP_LED_On(Led_TypeDef Led);
void BSP_LED_Off(Led_TypeDef Led);
void BSP_LED_Toggle(Led_TypeDef Led);
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __STM32F103_DEMO_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
其他文件几乎不做改动,只需把引用stm32f10e_eval.h头文件的内容改为stm32f13_demo.h即可。需要注意的是PA15口在STM32正常运行时是用作调试接口的,因此需要禁止调试功能,这在BSP_LED_Init()函数中有体现,编译代码并下载到目标板。
在运行代码之前我们需要安装一个usb串口驱动:VCP_1.40_Setup,这个可以在ST官网上找到,有了它我们的USB在可以在主机上识别成一个串口,并可以使用串口操作,硬件连接完毕后我们可以通过设备管理器来查看到有两个串口,如下:
COM5是单板实际的串口,而COM6看名字就晓得了,是USB虚拟出来的一个串口,打开两个串口终端,可以实现串口通信了,如下:
从COM5发送的信息可以在COM6中收到,同时从COM6中发送的信息可以在COM5中收到。同时该DEMO是支持串口波特率的修改的,我们将COM6和COM5的波特率改为57600,继续进行通信,依然是可以的,如下:
当然除去波特率以外,数据位、停止位、校验位都是可以正常修改的,有了这些直观性的功能描述会方便我们理解USB CDC类的使用,接下来就一步步分析一下VCP的代码实现吧。
首先分析物理硬件的处理吧,即stm32f1xx_hal_msp,c文件,该文件很简单只是初始化UART的IO资源,
/**
******************************************************************************
* @file USB_Device/CDC_Standalone/Src/stm32f1xx_hal_msp.c
* @author MCD Application Team
* @version V1.2.0
* @date 31-July-2015
* @brief HAL MSP module.
******************************************************************************
* @attention
*
* © COPYRIGHT(c) 2015 STMicroelectronics
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/** @addtogroup USBD_USER
* @{
*/
/** @defgroup USBD_USR_MAIN
* @brief This file is the CDC application main file
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/**
* @brief UART MSP Initialization
* This function configures the hardware resources used in this example:
* - Peripheral's clock enable
* - Peripheral's GPIO Configuration
* - DMA configuration for transmission request by peripheral
* - NVIC configuration for DMA interrupt request enable
* @param huart: UART handle pointer
* @retval None
*/
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
static DMA_HandleTypeDef hdma_tx;
GPIO_InitTypeDef GPIO_InitStruct;
/*##-1- Enable peripherals and GPIO Clocks #################################*/
/* Enable GPIO clock */
USARTx_TX_GPIO_CLK_ENABLE();
USARTx_RX_GPIO_CLK_ENABLE();
/* Enable USARTx clock */
USARTx_CLK_ENABLE();
/* Enable DMA clock */
DMAx_CLK_ENABLE();
/*##-2- Configure peripheral GPIO ##########################################*/
/* UART TX GPIO pin configuration */
GPIO_InitStruct.Pin = USARTx_TX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
HAL_GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStruct);
/* UART RX GPIO pin configuration */
GPIO_InitStruct.Pin = USARTx_RX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
HAL_GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStruct);
/*##-3- Configure the NVIC for UART ########################################*/
HAL_NVIC_SetPriority(USARTx_IRQn, 4, 0);
HAL_NVIC_EnableIRQ(USARTx_IRQn);
/*##-4- Configure the DMA channels ##########################################*/
/* Configure the DMA handler for Transmission process */
hdma_tx.Instance = USARTx_TX_DMA_STREAM;
hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_tx.Init.Mode = DMA_NORMAL;
hdma_tx.Init.Priority = DMA_PRIORITY_LOW;
HAL_DMA_Init(&hdma_tx);
/* Associate the initialized DMA handle to the UART handle */
__HAL_LINKDMA(huart, hdmatx, hdma_tx);
/*##-5- Configure the NVIC for DMA #########################################*/
/* NVIC configuration for DMA transfer complete interrupt (USARTx_TX) */
HAL_NVIC_SetPriority(USARTx_DMA_TX_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(USARTx_DMA_TX_IRQn);
/*##-6- Enable TIM peripherals Clock #######################################*/
TIMx_CLK_ENABLE();
/*##-7- Configure the NVIC for TIMx ########################################*/
/* Set Interrupt Group Priority */
HAL_NVIC_SetPriority(TIMx_IRQn, 5, 0);
/* Enable the TIMx global Interrupt */
HAL_NVIC_EnableIRQ(TIMx_IRQn);
}
/**
* @brief UART MSP De-Initialization
* This function frees the hardware resources used in this example:
* - Disable the Peripheral's clock
* - Revert GPIO, DMA and NVIC configuration to their default state
* @param huart: UART handle pointer
* @retval None
*/
void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
{
/*##-1- Reset peripherals ##################################################*/
USARTx_FORCE_RESET();
USARTx_RELEASE_RESET();
/*##-2- Disable peripherals and GPIO Clocks #################################*/
/* Configure UART Tx as alternate function */
HAL_GPIO_DeInit(USARTx_TX_GPIO_PORT, USARTx_TX_PIN);
/* Configure UART Rx as alternate function */
HAL_GPIO_DeInit(USARTx_RX_GPIO_PORT, USARTx_RX_PIN);
/*##-3- Disable the NVIC for UART ##########################################*/
HAL_NVIC_DisableIRQ(USARTx_IRQn);
/*##-4- Disable the NVIC for DMA ###########################################*/
HAL_NVIC_DisableIRQ(USARTx_DMA_TX_IRQn);
/*##-5- Reset TIM peripheral ###############################################*/
TIMx_FORCE_RESET();
TIMx_RELEASE_RESET();
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
在通常情况下USB设备在D+、D-加上上拉电阻来检测设备的连接和断开事件,在例程中是使用一个IO来动态地拉高拉低,而我这里所购买的单板是没有接IO口的直接使用的1.5K上拉电阻,因此不再需要单独的IO口控制,如图:
把usbd_conf.c文件中有关上拉电阻控制的代码去掉即可,涉及到HAL_PCD_MspInit()函数和HAL_PCDEx_SetConnectionState()两个函数,修改如下:
/**
* @brief Initializes the PCD MSP.
* @param hpcd: PCD handle
* @retval None
*/
void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* Enable the GPIOA clock */
__HAL_RCC_GPIOA_CLK_ENABLE();
/* Configure USB DM/DP pins */
GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12);
GPIO_InitStruct.Mode = GPIO_MODE_AF_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Enable USB Clock */
__HAL_RCC_USB_CLK_ENABLE();
/* Set USB Interrupt priority */
HAL_NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn, 7, 0);
/* Enable USB Interrupt */
HAL_NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
}
/**
* @brief Software Device Connection
* @param hpcd: PCD handle
* @param state: connection state (0 : disconnected / 1: connected)
* @retval None
*/
void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state)
{
}
/**
* @brief Toggle LEDs to shows user input state.
* @param None
* @retval None
*/
void Toggle_Leds(void)
{
static uint32_t ticks;
if (ticks++ == 1000)
{
BSP_LED_Toggle(LED);
ticks = 0;
}
}