STM32CubeMX学习(一) USB HID 双向通信

简介

利用正点原子F407探索者开发板,测试基于USB HID的双向数据通信。

CubeMX新建工程(串口+LED)

设置时钟源
在这里插入图片描述
在这里插入图片描述

设置调试器
在这里插入图片描述
设置LED
在这里插入图片描述
设置串口
在这里插入图片描述
设置USB OTG
在这里插入图片描述
在这里插入图片描述
Pinout预览
在这里插入图片描述
工程管理
在这里插入图片描述
在上图里,可以把Heap Size和Stack Size改大点,使得USB数据通信更流畅。

在这里插入图片描述
选中红框里的选项主要是为了工程打包后给他人直接使用。

最后点击GENERATE CODE生成工程。

测试串口和LED

usart.h中引入头文件stdio.h

/* USER CODE BEGIN Includes */
#include "stdio.h"	//引入此文件,为重定向printf
/* USER CODE END Includes */

usart.c中添加重定向代码

/* USER CODE BEGIN 1 */
// 重定向printf函数
int fputc(int ch,FILE *f)
{
    uint8_t temp[1]={ch};
    HAL_UART_Transmit(&huart1,temp,1,2);
		return 0;
}
/* USER CODE END 1 */

为了方便调试,在main.c中加入以下宏定义

/* USER CODE BEGIN PD */
#define USER_MAIN_DEBUG

#ifdef USER_MAIN_DEBUG
#define user_main_printf(format, ...) printf( format "\r\n",##__VA_ARGS__)
#define user_main_info(format, ...)   printf("main.info:" format "\r\n",##__VA_ARGS__)
#define user_main_debug(format, ...)  printf("main.debug:" format "\r\n",##__VA_ARGS__)
#define user_main_error(format, ...)  printf("main.error:" format "\r\n",##__VA_ARGS__)
#else
#define user_main_printf(format, ...)
#define user_main_info(format, ...)
#define user_main_debug(format, ...)
#define user_main_error(format, ...)
#endif
/* USER CODE END PD */

main.c中添加代码

  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
      printf("Enter main while loop!\r\n");
      user_main_debug("Main debug!\n");
      HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_RESET);
      HAL_Delay(500);
      HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_SET);
      HAL_Delay(500);
  }
  /* USER CODE END 3 */

设置下载后自动运行,编译运行,连接串口调试助手,观察现象
在这里插入图片描述
编译下载后,重启发现LED1(绿灯)在闪烁,串口收到字符数据。

如果程序没有反应或者仿真后发现程序一直卡死在 BEAB BKPT 0xAB,解决方法:MDK选择设置,TARGET ,勾选Use MicroLIB
在这里插入图片描述

设置USB HID

利用HID descriptor Tool软件生成发送接收64byte的报文描述符数据,添加到usbd_custom_hid_if.c文件的CUSTOM_HID_ReportDesc_FS函数中


/** Usb HID report descriptor. */
__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
{
  /* USER CODE BEGIN 0 */    
    0x05, 0x8c, // USAGE_PAGE (ST Page) /
    0x09, 0x01, // USAGE (Demo Kit) /
    0xa1, 0x01, // COLLECTION (Application) /
    /* 6 */
    // The Input report
    0x09,0x03, // USAGE ID - Vendor defined
    0x15,0x00, // LOGICAL_MINIMUM (0)
    0x26,0x00, 0xFF, // LOGICAL_MAXIMUM (255)
    0x75,0x08, // REPORT_SIZE (8)
    0x95,CUSTOM_HID_EPIN_SIZE, //0x95,0x16, REPORT_COUNT (20)
    0x81,0x02, // INPUT (Data,Var,Abs)
    //19
    // The Output report
    0x09,0x04, // USAGE ID - Vendor defined
    0x15,0x00, // LOGICAL_MINIMUM (0)
    0x26,0x00,0xFF, // LOGICAL_MAXIMUM (255)
    0x75,0x08, // REPORT_SIZE (8)
    0x95,CUSTOM_HID_EPOUT_SIZE, //0x95,0x16, REPORT_COUNT (20)
    0x91,0x02, // OUTPUT (Data,Var,Abs)
    //32
  /* USER CODE END 0 */
  0xC0    /*     END_COLLECTION	             */
};

usbd_desc.c中修改USB HID参数

** @defgroup USBD_DESC_Private_Defines USBD_DESC_Private_Defines
  * @brief Private defines.
  * @{
  */

#define USBD_VID     1155
#define USBD_LANGID_STRING     1033
#define USBD_MANUFACTURER_STRING     "STMicroelectronics"
#define USBD_PID_FS     22352
#define USBD_PRODUCT_STRING_FS     "STM32 Custom Human interface"
#define USBD_CONFIGURATION_STRING_FS     "Custom HID Config"
#define USBD_INTERFACE_STRING_FS     "Custom HID Interface"


#define USB_SIZ_BOS_DESC            0x0C

usbd_conf.h中修改发送数据长度和报文长度
在这里插入图片描述

usbd_customhid.h:中修改收发数据长度和时间间隔
在这里插入图片描述
其中,CUSTOM_HID_HS_BINTERVALCUSTOM_HID_FS_BINTERVAL的值也可以在CubeMX中设置。CUSTOM_HID_FS_BINTERVAL的定义在文件usbd_conf.h中,见前一个图。

测试USB HID通信

main.c中,添加如下代码:

/* USER CODE BEGIN Includes */
#include "usbd_custom_hid_if.h"
#include "usbd_customhid.h" //包括发送函数头文件
extern USBD_HandleTypeDef hUsbDeviceFS; //外部声明USB的句柄
/* USER CODE END Includes */
...
/* USER CODE BEGIN PV */
unsigned char USB_Recive_Buffer[64] = {1,2,3,4,5,6,7,8,9,}; //USB接收缓存
unsigned char USB_Received_Count = 0;//USB接收数据计数
/* USER CODE END PV */
...
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
      printf("Enter main while loop!\r\n");
      USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, USB_Recive_Buffer, 64);
      HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_RESET);
      HAL_Delay(500);
      HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_SET);
      HAL_Delay(500);
  }
  /* USER CODE END 3 */

usbd_custom_hid_it.c中添加如下代码:

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
extern unsigned char USB_Recive_Buffer[64];
extern unsigned char USB_Received_Count;
/* USER CODE END PV */

...

/**
  * @brief  Manage the CUSTOM HID class events
  * @param  event_idx: Event index
  * @param  state: Event state
  * @retval USBD_OK if all operations are OK else USBD_FAIL
  */
static int8_t CUSTOM_HID_OutEvent_FS(uint8_t event_idx, uint8_t state)
{
  /* USER CODE BEGIN 6 */
//  UNUSED(event_idx);
//  UNUSED(state);
    
    int i;
    /*查看接收数据长度*/
    USB_Received_Count = USBD_GetRxCount( &hUsbDeviceFS,CUSTOM_HID_EPOUT_ADDR );  //第一参数是USB句柄,第二个参数的是接收的末端地址;要获取发送的数据长度的话就把第二个参数改为发送末端地址即可
    //printf("USB_Received_Count = %d \r\n",USB_Received_Count);
    
    USBD_CUSTOM_HID_HandleTypeDef   *hhid; //定义一个指向USBD_CUSTOM_HID_HandleTypeDef结构体的指针
    hhid = (USBD_CUSTOM_HID_HandleTypeDef*)hUsbDeviceFS.pClassData;//得到USB接收数据的储存地址
    
    for(i=0;i<USB_Received_Count;i++) 
    {
        USB_Recive_Buffer[i]=hhid->Report_buf[i];  //把接收到的数据送到自定义的缓存区保存(Report_buf[i]为USB的接收缓存区)
    } 
    
  /* Start next USB packet transfer once data processing is completed */
  USBD_CUSTOM_HID_ReceivePacket(&hUsbDeviceFS);

  return (USBD_OK);
  /* USER CODE END 6 */
}

编译后下载,测试结果如下图:
在这里插入图片描述
点击端点2/HID发送按钮,结果如下:
在这里插入图片描述
Bus Hound捕获情况如下:
在这里插入图片描述

结论

根据相关资料,使用HID方式的传输为中断传输方式,中断时间间隔由CUSTOM_HID_FS_BINTERVAL设定,最小值为1ms,也就是说最大传输速度为64KByte/Sec。用Bus Hound软件测试出的结果类似,如下图:
在这里插入图片描述
工程文件可以在本人资源里下载。

注:Cmd.Phase.Ofs的含义为三个数据中的第一个表示命令(Cmd),从1开始统计,每当设备收到一条新的命令就加1。
第二个表示Phase在本次(Cmd)中的位置,每次有一个数据或者状态就加1。
第三个表示数据在这一个Phase当中的位置。
最后还有一个括号,里面表示重复的数据被折叠次数,在Settings当中可以设置重复的数据合并显示。

在本实验中,测试的速率差不多是1ms一个包!

  • 10
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值