STM32 USB学习笔记5

发布者:CyberJolt最新更新时间:2019-05-29 来源: eefocus关键字:STM32  USB  学习笔记 手机看文章 扫描二维码
随时随地手机看文章

主机环境: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;

[1] [2] [3]
关键字:STM32  USB  学习笔记 引用地址:STM32 USB学习笔记5

上一篇:STM32 USB学习笔记6
下一篇:STM32 USB学习笔记4

推荐阅读最新更新时间:2024-11-12 11:03

使用STM32GPIO读取按键实现按键操作(STM32_08)
一、开发板按键设置 在 STM32-PZ6806L 开发板上除了复位按键外,还设计了4个按键,分别标为 UP 、 DOWN 、 LEFT 和 RIGHT ,其电路如下: 根据电路连接得知K_UP按键一端与GPIOA_0连接,另一端通过一个1KΩ电阻接3.3V,所以在对GPIOA_0配置时应设置工作方式为“下拉输入”,当按键松开时为低电平,按键按下时为高电平;K_LEFT、K_DOWN和K_RIGHT三个按键的一端分别与GPIOE_2、GPIOE_3和GPIOE_4相连,另一端接地,所以对GPIOE_2、GPIOE_3和GPIOE_4要配置为“上拉输入”方式,按键松开时为高电平,按键按下时为低电平。 二、项目基本配
[单片机]
使用STM32GPIO读取按键实现按键操作(STM32_08)
STM32——关于在K5中RCC的标志位
STM32的时钟系统框图 STM32 有4个独立时钟源:HSI、HSE、LSI、LSE。 ①、HSI是高速内部时钟,RC振荡器,频率为8MHz,精度不高。 ②、HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz。 ③、LSI是低速内部时钟,RC振荡器,频率为40kHz,提供低功耗时钟。  ④、LSE是低速外部时钟,接频率为32.768kHz的石英晶体。 其中LSI是作为IWDGCLK(独立看门狗)时钟源和RTC时钟源 而独立使用 而HSI高速内部时钟、HSE高速外部时钟、PLL锁相环时钟、这三个经过分频或者倍频 作为系统时钟来使用。 PLL为锁相环倍频输出,其时钟输入源可选
[单片机]
基于STM32F103C8T6 MCU的STM32 Blue Pill Board接口
在本教程中,我将介绍如何将DHT11湿度和温度传感器与基于STM32F103C8T6 MCU的STM32 Blue Pill Board接口。DHT11传感器的值由STM32读取,并显示在I2C LCD显示屏上。 介绍 传感器是很小的设备,可以弥合原始模拟世界与MCU的数字世界之间的鸿沟。传感器可以非常简单,例如非常著名的LM35温度传感器,也可以是一些复杂的数学单元,例如MPU6050陀螺仪和加速度计组合传感器。 简单或复杂,传感器是许多消费,汽车,机器人和工业应用中的关键部分,如果不集成适当的传感器就无法完成某些应用。 让我们从工业应用程序扩展到日常项目和业余爱好者。气象站是一个非常普遍且受欢迎的项目,无论是物联网
[单片机]
STM32-AHB、APB1、APB2的使(失)能函数
一、RCC_AHBPeriphClockCmd函数 其中RCC_AHBPeriph的取值范围: 二、RCC_APB2PeriphClockCmd函数 其中RCC_APB2Periph的取值范围:GPIOx 、高级定时器TIM1,TIM8,高速SPI1,高速异步通信USART1,ADC1,ADC2,ADC3,温度传感器等接口 三、RCC_APB1PeriphClockCmd函数: 其中RCC_APB1Periph的取值范围:备份接口,通用定时器,基本定时器,异步通信USART2,USART3,异步通信USART4,USART5,IIC1,IIC2,SPI2/IIS3,SPI3/IIS3 CAN总线,USB2,0,
[单片机]
STM32-AHB、APB1、APB2的使(失)能函数
STM32 SDIO 报错 SD_RX_OVERRUN
使用STM32官方SDIO 的SDCARD驱动的时候,以前单任务的时候没有出现这种错误,现在使用多任务的时候经常出现,表现为读取文件的时候没有问题,经常点击屏幕的时候就会出问题,最后通过仿真找到出错点就是读取数据向SD卡发送CD17命令时出现 SD_RX_OVERRUN这个错误,产生原因为读取FIFO溢出. 通过仿真与测试发现问题主要出现在读取过程中不能打断,也就是临界点. 在两个读取函数里面 SD_Error SD_ReadMultiBlocks(u32 addr, u32 *readbuff, u16 BlockSize, u32 NumberOfBlocks); SD_Error SD_ReadBlock(u32 addr
[单片机]
USB保护电路的EMC设计
USB是一个外部总线标准,用于规范电脑与外部设备的连接和通讯。USB接口支持设备的即插即用和热插拔功能。USB信号传输电缆通常是双绞屏蔽线,其内部包含3对USB信号线和1对电源线,在传输通道上的输入电压值为4.07-5.25V,传输的最大电流约为900mA.USB接口的传输速率很高,像USB2.0最大的传输速率为480Mbit/s,USB3.0的传输速率更是10倍USB2.0的传输速率。并且USB3.0已经渐渐投入市场,必将是未来发展的趋势!但随着传输速率的增大如何提高USB信号的传输质量,减小电磁干扰EMI和静电放电ESD成为USB设计的关键。瞬雷电子一直致力于这方面的研发,从产品研发到系统设计无不尽心尽力。现以USB3.0为例
[电源管理]
使用STM32单片机点亮LED
有一人,登场于金庸先生的《神雕侠侣》,以大理段氏“一阳指”自成一派,武学修为登峰造极,“天下五绝”之一,号称“南帝”,他就是“一灯大师”。如今,武林中逐渐被遗忘的“一灯大师”,却活跃在另一个行业——嵌入式开发中。 传说,每一个成功的MCU(俗称单片机)开发组中,都有一名“一灯大师”,他精通所有开发板的点灯方法,对于企业引入的新开发板,总是勤学苦练,从点灯开始,快速掌握新开发板的编程要点,带领团队走向胜利。 成为“一灯大师”,离不开持续的修行,离不开对一招一式的勤学苦练。本文将讲解如何通过编程来控制STM32点亮一个LED。 学习环境: 1.软件:Keil5 2.硬件:STM32开发板(笔者使用信盈达公司的M4开发板,芯片型
[单片机]
使用<font color='red'>STM32</font>单片机点亮LED
STM32 | 串口空闲中断接收不定长数据(DMA方式)
在使用STM32的串口接收数据的时候,我们常常会使用接收中断的方式来接收数据,常用的是RXNE。这里分享另一种接收数据的方式——IDLE中断(PS:本文的例子运行在STM32F103ZET6上)。 一、IDLE中断什么时候发生? IDLE就是串口收到一帧数据后,发生的中断。什么是一帧数据呢?比如说给单片机一次发来1个字节,或者一次发来8个字节,这些一次发来的数据,就称为一帧数据,也可以叫做一包数据。 二、RXNE中断和IDLE中断的区别? 当接收到1个字节,就会产生RXNE中断,当接收到一帧数据,就会产生IDLE中断。比如给单片机一次性发送了8个字节,就会产生8次RXNE中断,1次IDLE中断。 三、IDLE中断如何配
[单片机]
<font color='red'>STM32</font> | 串口空闲中断接收不定长数据(DMA方式)
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved