USB -- STM32-FS-USB-Device驱动代码简述(二)

目录

链接快速定位 

前沿

1 STM32-FS-USB驱动程序下载

2 STM32-USB-FS设备固件库

2.1 USB应用程序层次结构

2.2 USB-FS_Device peripheral interface

2.3 USB-FS-Device_Driver medium layer

2.3 Application interface

3 代码讲解

3.1 初始化代码讲解

3.2 描述符讲解

3.3 中断处理函数

3.3.1 复位函数

3.3.2 正确传输完成函数

3.3.2.1 枚举过程正确传输完成函数

3.3.2.2 非端点0正确传输完成函数


链接快速定位 

USB -- 初识USB协议(一)

前沿

        本小节主要讲述STM32F103USB设备模式下的标准库驱动程序结构,代码比较复杂,需要读者对USB协议有一个全面的了解,这里只讲述一下比较浅显的东西。

      

1 STM32-FS-USB驱动程序下载

        每个芯片厂商都会提供一套属于自己的外设驱动及应用程序,这也是我们所说的生态的一部分,可以通过顶部置顶资源下载。

2 STM32-USB-FS设备固件库

2.1 USB应用程序层次结构

        下图显示了典型USB的不同组件之间的交互应用程序和USB FS设备库。

        从上图可知,USB设备固件库被分为两层:

  • STM32_USB-FS_Device_Driver:该层管理与USB-FS_ Device外围设备和USB标准协议的直接通信。STM32_USBFS_ Device_Driver符合USB 2.0规范,与标准STM32标准外设库分离。
  • Application Interface layer:该层为用户提供了库核心和最终应用程序之间的完整接口。

        下图显示了USB FS设备库的程序包组织以及所有演示和子文件夹。

2.2 USB-FS_Device peripheral interface

        USB全速设备外设接口层主要由以下部分组成:

  • 硬件抽象层
  • 正确传输中断服务例程
  • 数据传输管理

2.3 USB-FS-Device_Driver medium layer

        USB全速设备驱动中间层主要由以下部分组成:

  • USB设备全局变量初始化
  • USB协议管理
  • 简化了对端点的读写访问功能(USB-FS_Device外围设备的抽象层)
  • 库中使用的USB定义和类型
  • 根据使用的评估板定义硬件

2.3 Application interface

        应用接口主要由以下部分组成:

  • USB全速设备配置文件
  • USB设备描述符
  • USB设备应用程序特定属性
  • 不带控制端点的正确传输中断例程
  • USB设备中断处理函数
  • USB设备电源和连接管理函数

3 代码讲解

        代码讲解主要涉及以下几个方面:

  • 初始化
  • 描述符
  • 中断处理函数
    • 复位函数
    • 正确传输完成函数

        这里以“VirtualComport_Loopback”工程为例进行讲解。

3.1 初始化代码讲解

  • GPIO初始化

        GPIO初始化程序主要是初始化通信所使用的DM和DP引脚以及USB全速设备的DP上拉引脚。

void Set_System(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;  

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  
  /********************************************/
  /*  Configure USB DM/DP pins                */
  /********************************************/
  
  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);
  
  /* USB_DISCONNECT used as USB pull-up */
  GPIO_InitStructure.GPIO_Pin = USB_DISCONNECT_PIN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
  GPIO_Init(USB_DISCONNECT, &GPIO_InitStructure);
  
  /* Enable the USB disconnect GPIO clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIO_DISCONNECT, ENABLE);
}
  • USB时钟配置

        USB时钟配置主要是配置USB的PHY时钟,运行在48MHz的时钟下(系统时钟72M),并使能USB时钟。

void Set_USBClock(void)
{
  /* Select USBCLK source */
  RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_1Div5);
  
  /* Enable the USB clock */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE);
}

  • USB中断初始化

        USB中断初始化,主要是使能USB的中断,并且使能中断屏蔽位。

void USB_Interrupts_Config(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;

    /* 2 bit for pre-emption priority, 2 bits for subpriority */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);


    /* Enable the USB interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    /* Enable the USB Wake-up interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = USBWakeUp_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_Init(&NVIC_InitStructure);   

}
RESULT PowerOn(void)
{
  uint16_t wRegVal;
  
#if !defined (USE_NUCLEO)
  /*** cable plugged-in ? ***/
  USB_Cable_Config(ENABLE);
#endif

  /*** CNTR_PWDN = 0 ***/
  wRegVal = CNTR_FRES;
  _SetCNTR(wRegVal);

  /* The following sequence is recommended:
    1- FRES = 0
    2- Wait until RESET flag = 1 (polling)
    3- clear ISTR register */

  /*** CNTR_FRES = 0 ***/
  wInterrupt_Mask = 0;
  
  _SetCNTR(wInterrupt_Mask);
  
  /* Wait until RESET flag = 1 (polling) */
  while((_GetISTR()&ISTR_RESET) == 1);
  
  /*** Clear pending interrupts ***/
  SetISTR(0);
  
  /*** Set interrupt mask ***/
  wInterrupt_Mask = CNTR_RESETM | CNTR_SUSPM | CNTR_WKUPM;
  _SetCNTR(wInterrupt_Mask);
  
  return USB_SUCCESS;
}

uint32_t USB_SIL_Init(void)
{
  /* USB interrupts initialization */
  /* clear pending interrupts */
  _SetISTR(0);
  wInterrupt_Mask = IMR_MSK;
  /* set interrupts mask */
  _SetCNTR(wInterrupt_Mask);
  return 0;
}

void Virtual_Com_Port_init(void)
{

  /* Update the serial number string descriptor with the data from the unique
  ID*/
  Get_SerialNum();

  pInformation->Current_Configuration = 0;

  /* Connect the device */
  PowerOn();

  /* Perform basic device initialization operations */
  USB_SIL_Init();

  bDeviceState = UNCONNECTED;
}

        经过上面的配置,当USB设备端接入主机的时候,设备端的中断处理函数就能响应相应的中断请求,开始建立通信。

3.2 描述符讲解

        描述符放在“usb_desc.c”和“usb_desc.h”文件中,更多细节参见

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰糖葫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值