主机环境:Windows 7 SP1
开发环境:MDK5.14
目标板:STM32F103C8T6
开发库:STM32F1Cube库和STM32_USB_Device_Library
承接前文,对于上层应用而言只剩下CDC类接口文件即usbd_cdc_interface,该文件主要为实现CDC类接口所用到的物理资源以及逻辑资源,需要参考通信设备通用串行总线类定义版本1.2以及PSTN设备通用串行总线通信类子类规范版本1.2,这两个文档都可以在USB组织官网上下载得到,首先看下usbd_cdc_interface.h文件,如下:
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_CDC_IF_H
#define __USBD_CDC_IF_H
/* Includes ------------------------------------------------------------------*/
#include "usbd_cdc.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* User can use this section to tailor USARTx/UARTx instance used and associated
resources */
/* Definition for USARTx clock resources */
#define USARTx USART1
#define USARTx_CLK_ENABLE() __HAL_RCC_USART1_CLK_ENABLE();
#define DMAx_CLK_ENABLE() __HAL_RCC_DMA1_CLK_ENABLE()
#define USARTx_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define USARTx_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define USARTx_FORCE_RESET() __HAL_RCC_USART1_FORCE_RESET()
#define USARTx_RELEASE_RESET() __HAL_RCC_USART1_RELEASE_RESET()
/* Definition for USARTx Pins */
#define USARTx_TX_PIN GPIO_PIN_9
#define USARTx_TX_GPIO_PORT GPIOA
#define USARTx_RX_PIN GPIO_PIN_10
#define USARTx_RX_GPIO_PORT GPIOA
/* Definition for USARTx's NVIC: used for receiving data over Rx pin */
#define USARTx_IRQn USART1_IRQn
#define USARTx_IRQHandler USART1_IRQHandler
/* Definition for USARTx's DMA: used for transmitting data over Tx pin */
#define USARTx_TX_DMA_STREAM DMA1_Channel4
#define USARTx_RX_DMA_STREAM DMA1_Channel5
/* Definition for USARTx's NVIC */
#define USARTx_DMA_TX_IRQn DMA1_Channel4_IRQn
#define USARTx_DMA_RX_IRQn DMA1_Channel5_IRQn
#define USARTx_DMA_TX_IRQHandler DMA1_Channel4_IRQHandler
#define USARTx_DMA_RX_IRQHandler DMA1_Channel5_IRQHandler
/* Definition for TIMx clock resources */
#define TIMx TIM3
#define TIMx_CLK_ENABLE __HAL_RCC_TIM3_CLK_ENABLE
#define TIMx_FORCE_RESET() __HAL_RCC_USART1_FORCE_RESET()
#define TIMx_RELEASE_RESET() __HAL_RCC_USART1_RELEASE_RESET()
/* Definition for TIMx's NVIC */
#define TIMx_IRQn TIM3_IRQn
#define TIMx_IRQHandler TIM3_IRQHandler
/* Periodically, the state of the buffer "UserTxBuffer" is checked.
The period depends on CDC_POLLING_INTERVAL */
#define CDC_POLLING_INTERVAL 5 /* in ms. The max is 65 and the min is 1 */
extern USBD_CDC_ItfTypeDef USBD_CDC_fops;
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
#endif /* __USBD_CDC_IF_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
这其中主要是一些物理资源的定义,需要用到一个串口资源(且使用DMA方式发送数据),一个定时器资源(定时读取从串口接收到的数据并发往USB接口)。这里虽然列出了两个DMA通道,但在实现中只用到了TX的DMA发送一个通道,文件末尾有一个CDC类接口数据结构USBD_CDC_ItfTypeDef,如下:
typedef struct _USBD_CDC_Itf
{
int8_t (* Init) (void);
int8_t (* DeInit) (void);
int8_t (* Control) (uint8_t, uint8_t * , uint16_t);
int8_t (* Receive) (uint8_t *, uint32_t *);
}USBD_CDC_ItfTypeDef;
有关该结构的说明可以在USB器件库文档中找到,如下:
由上可以看出这里只有OUT传输而没有IN传输,VCP模型很简单就只有简单的收发数据以及一些属性的修改等,因此这里的CDC接口接口内容不多。下面查看一下usbd_cdc_interface.c文件,其内容是CDC类物理以及逻辑接口的具体实现。文件开头申请了两块缓冲区用于数据的收发,如下:
#define APP_RX_DATA_SIZE 2048
#define APP_TX_DATA_SIZE 2048
uint8_t UserRxBuffer[APP_RX_DATA_SIZE];/* Received Data over USB are stored in this buffer */
uint8_t UserTxBuffer[APP_TX_DATA_SIZE];/* Received Data over UART (CDC interface) are stored in this buffer */
uint32_t BuffLength;
uint32_t UserTxBufPtrIn = 0;/* Increment this pointer or roll it back to
start address when data are received over USART */
uint32_t UserTxBufPtrOut = 0; /* Increment this pointer or roll it back to
start address when data are sent over USB */
两块缓冲区是循环使用,其中的RX、TX是针对USB模块而言,各2K字节。在文件头部还有一个新的数据结构USBD_CDC_LineCodingTypeDef,该结构很简单,如下:
typedef struct
{
uint32_t bitrate;
uint8_t format;
uint8_t paritytype;
uint8_t datatype;
}USBD_CDC_LineCodingTypeDef;
对应着串口的各个属性,有关LineCoding的相关信息可以在PSTN120文档中找到,如下:
并且罗列了各个属性的取值范围,由此可以看出默认状态下串口属性为:115200波特率、1个停止位,8个数据位,无校验。接着查看CDC类接口的实现函数,首先是硬件资源的初始化操作:
USBD_CDC_ItfTypeDef USBD_CDC_fops =
{
CDC_Itf_Init,
CDC_Itf_DeInit,
CDC_Itf_Control,
CDC_Itf_Receive
};
/* Private functions ---------------------------------------------------------*/
/**
* @brief CDC_Itf_Init
* Initializes the CDC media low layer
* @param None
* @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t CDC_Itf_Init(void)
{
/*##-1- Configure the UART peripheral ######################################*/
/* Put the USART peripheral in the Asynchronous mode (UART Mode) */
/* USART configured as follows:
- Word Length = 8 Bits
- Stop Bit = One Stop bit
- Parity = No parity
- BaudRate = 115200 baud
- Hardware flow control disabled (RTS and CTS signals) */
UartHandle.Instance = USARTx;
UartHandle.Init.BaudRate = 115200;
UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_NONE;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
if(HAL_UART_Init(&UartHandle) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
/*##-2- Put UART peripheral in IT reception process ########################*/
/* Any data received will be stored in "UserTxBuffer" buffer */
if(HAL_UART_Receive_IT(&UartHandle, (uint8_t *)UserTxBuffer, 1) != HAL_OK)
{
/* Transfer error in reception process */
Error_Handler();
}
/*##-3- Configure the TIM Base generation #################################*/
TIM_Config();
/*##-4- Start the TIM Base generation in interrupt mode ####################*/
/* Start Channel1 */
if(HAL_TIM_Base_Start_IT(&TimHandle) != HAL_OK)
{
/* Starting Error */
Error_Handler();
}
/*##-5- Set Application Buffers ############################################*/
USBD_CDC_SetTxBuffer(&USBD_Device, UserTxBuffer, 0);
USBD_CDC_SetRxBuffer(&USBD_Device, UserRxBuffer);
return (USBD_OK);
}
/**
* @brief CDC_Itf_DeInit
* DeInitializes the CDC media low layer
* @param None
* @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t CDC_Itf_DeInit(void)
{
/* DeInitialize the UART peripheral */
if(HAL_UART_DeInit(&UartHandle) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
return (USBD_OK);
}
这里主要是串口资源的初始化,按照LineCoding中默认的属性初始化串口资源,并进一步调用之前stm32f1xx_hal_msp.c文件中的HAL_UART_MspInit(),HAL_UART_MspDeInit()方法。此外开启串口接收中断接收字节数据,同时初始化定时器资源,如下:
/**
* @brief TIM_Config: Configure TIMx timer
* @param None.
* @retval None.
*/
static void TIM_Config(void)
{
/* Set TIMx instance */
TimHandle.Instance = TIMx;
/* Initialize TIM3 peripheral as follows:
+ Period = 10000 - 1
+ Prescaler = ((SystemCoreClock/2)/10000) - 1
+ ClockDivision = 0
+ Counter direction = Up
*/
TimHandle.Init.Period = (CDC_POLLING_INTERVAL*1000) - 1;
TimHandle.Init.Prescaler = 84-1;
TimHandle.Init.ClockDivision = 0;
TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
上一篇:STM32 USB学习笔记6
下一篇:STM32 USB学习笔记4
推荐阅读最新更新时间:2024-11-12 11:03
设计资源 培训 开发板 精华推荐
- 将 LT3045IMSE 超低噪声电流源用于 RF 偏置应用的典型应用
- 使用 Richtek Technology Corporation 的 RT8092 的参考设计
- DC1865A,使用 LT3055、500mA、具有精密电流限制和诊断功能的线性稳压器的演示板
- LT3467AIS6 单节锂离子电池至 5V 升压转换器的典型应用
- 3相直流无刷电机驱动IC —— TB6605FTG
- LTM4643MPV 12V 和 5V 两个独立输入轨的典型应用,6A 时为 1.2V,6A 时为 3.3V 输出降压型稳压器
- Gameduino 3X Dazzler:具有 GPU、FPGA、HDMI 和 Python 支持的 Arduino 扩展板,用于游戏和视听
- FRDM-KL82Z: 面向Kinetis超低功耗KL82 MCU的Freedom开发板
- LT3433、4V-60V 至 5V DC/DC 转换器
- -26V, -12V, 3.3V, 5V, 12V AC转DC多输出DVD播放器电源