STM32F3HAL USB HID设备免驱动

STM32F3HAL USB设备免驱动

USB现在变得越来越重要了,最近在修改的过程中发现了很多坑,而且这个方面的很多资料在网络上都没有讲得很清楚,这里使用hal库操作一下。

1.STM32F1和F3系列带USB的IO口内部没有上拉或下拉电阻(F4的自带)。想要达到全速或者检测得到,就得在外部加 1.5K上拉电阻,使用一个IO口来控制。CubeMX在生成USB代码后,还需要手动添加控制代码,这部分在标准库的USB demo中,使用了一个默认接口,也可以手动修改更换。

硬件电路参考
STM32F3HAL USB HID设备免驱动_第1张图片
初始化代码,这里使用了PF10脚

void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  
  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOF_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOF, GPIO_PIN_10, GPIO_PIN_RESET);

  /*Configure GPIO pin : PE3 */
  GPIO_InitStruct.Pin = GPIO_PIN_10;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
  HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);	
}

然后在usbd_conf.c里找到void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state)函数,在里面添加

void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state)
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
{
  /* USER CODE BEGIN 6 */
  if (state == 1)
  {
    /* Configure Low connection state. */
	HAL_GPIO_WritePin(GPIOF, GPIO_PIN_10, GPIO_PIN_RESET);//使能下拉
  }
  else
  {
    /* Configure High connection state. */
	HAL_GPIO_WritePin(GPIOF, GPIO_PIN_10, GPIO_PIN_SET);//使能上拉
  }
  /* USER CODE END 6 */
}

然后USB就能正常检测到了

下面的就是我自己的笔记了,做的是HID设备免驱动。
首先使用cubeMX生成一个HID设备,可以不用更改里面的参数。
STM32F3HAL USB HID设备免驱动_第2张图片

  1. 增加断点
    在对应的数组里面添加,例如

     __ALIGN_BEGIN static uint8_t USBD_HID_CfgDesc[USB_HID_CONFIG_DESC_SIZ]  __ALIGN_END 
    

STM32F3HAL USB HID设备免驱动_第3张图片
第一个就是节点数,第二个不能修改,第3个和第4个可以自己定义。

增加完毕后需要在下面描述这个端点,这里定义为中断模式,大小16。

  0x07,          /*bLength: Endpoint Descriptor size*/
  USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/
  
  HID_EPOUT_ADDR,     /*bEndpointAddress: Endpoint Address (OUT)*/
  USB_ENDPOINT_TYPE_INTERRUPT,          /*bmAttributes: Interrupt endpoint*/
  HID_EPIN_SIZE, /*wMaxPacketSize: 16 Byte max */
  0x00,
  0x02,          /*bInterval: Polling Interval (2 ms)*/  

以下是模式类别,控制,同步,批量,中断。在HID模式下只能中断。如果选批量,需要驱动,而这个驱动,可以通过一些软件做出来,但是没有数字签名,如果自己用还可以,商用还是找微软集成一个吧,就是费钱。。。

#define USB_ENDPOINT_TYPE_CONTROL                 0x00
#define USB_ENDPOINT_TYPE_ISOCHRONOUS             0x01
#define USB_ENDPOINT_TYPE_BULK                    0x02
#define USB_ENDPOINT_TYPE_INTERRUPT               0x03

同样,HID设备还需要端点报告
这是是一个鼠标的

__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END 

里面增加
//输出报告

   0x09, 0x05,//用法(vendor defined)
   0x09, 0x06,//用法(vendor defined)
   0x15, 0x80,//逻辑最小值(0x80 or -128)
   0x25, 0x7F,//逻辑最大值(0x7F or 127)
   0x35, 0x00,//物理最小值(0)
   0x45, 0xFF,//物理最大值(255)
   0x75, 0x08,//报告长度(8位)
   0x95, 0x40,//报告数值(64 fields)
   0x91, 0x02,//输出(data, variable, absolute)

接下来就是初始化和相关控制函数里添加这个端点了,这里的端点是HID_EPOUT_ADDR
(1) 在static uint8_t USBD_HID_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx)函数里添加,第二个参数是端点,依次是传输类型,大小

USBD_LL_OpenEP(pdev,HID_EPOUT_ADDR,USBD_EP_TYPE_INTR,HID_EPIN_SIZE);  

(2) 在static uint8_t USBD_HID_DeInit (USBD_HandleTypeDef *pdev, uint8_t cfgidx)函数里添加;就是加一个关闭端点地址

USBD_LL_CloseEP(pdev,HID_EPOUT_ADDR);

(3) 在usbd_conf.c里,函数USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)里添加,最后一个参数根据实际情况添加

 HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , HID_EPOUT_ADDR, PCD_SNG_BUF, 0x140);

HAL库里面都是集成好的

例如判断USB状态

while(((USBD_HID_HandleTypeDef *)(&hUsbDeviceFS)->pClassData)->state == HID_BUSY){;}

然后调用USBD_LL_Transmit函数就可以发送数据了

你可能感兴趣的:(单片机,CubeMX,USB)