打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
STM32USB开发(一)HIDSlave通信

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、开发板USB硬件
  • 二、STM32CubeMX 设置
    • 1.设置小灯灯和串口
    • 2.开启USB
    • 3.时钟设置
  • 三、KEIL中的代码
    • 1.设置串口,测试
    • 2.设置USB,测试
      • 报文描述符 usbd_custom_hid_if.c
      • 发送数据长度 报文长度 usbd_conf.h
      • 收发数据长度 时间间隔 usbd_customhid.h
      • main.c
  • 四、测试
  • 总结

前言

学习STM32中的USB通信的时候,面对USB中数据帧结构、设备描述符/配置描述符/接口描述符/端点描述符等等的概念,入门即放弃。因此抛开所有,先让开发板的小灯闪起来,一点一点调试、一点一点熟悉、一点一点深入,一点一点理解。LET’S DO。先来玩HID


一、开发板USB硬件

翻到了一块吃灰的STM32F407ZGT6的板子和SCH原理图。
usb Low-Speed -->1.5Mbps(192kB/s)
usb Full-Speed -->12Mbps(1.5MB/s)
支持Full-Speed

二、STM32CubeMX 设置

1.设置小灯灯和串口

DMA 串口传输

2.开启USB

其余参数保持默认

3.时钟设置

导出工程,用KEIL 打开

三、KEIL中的代码

1.设置串口,测试

在main.c 中添加

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define debug(...) {	int len=0;	len=snprintf(debug_buf , 128, __VA_ARGS__);	if(len>0)	{		HAL_UART_Transmit_DMA(&huart1, (uint8_t *)debug_buf, len );	}}
/* USER CODE END PD */

/* USER CODE BEGIN PV */
char debug_buf[128];
/* USER CODE END PV */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
      debug("Enter main while loop!\r\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 */

记得选中,不然可能发现串口无信息输出。

2.设置USB,测试

报文描述符 usbd_custom_hid_if.c

从别人那里照抄

/** 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_conf.h

/** @defgroup USBD_CONF_Exported_Defines USBD_CONF_Exported_Defines
  * @brief Defines for configuration of the Usb device.
  * @{
  */

/*---------- -----------*/
#define USBD_MAX_NUM_INTERFACES     1U
/*---------- -----------*/
#define USBD_MAX_NUM_CONFIGURATION     1U
/*---------- -----------*/
#define USBD_MAX_STR_DESC_SIZ     512U
/*---------- -----------*/
#define USBD_DEBUG_LEVEL     0U
/*---------- -----------*/
#define USBD_LPM_ENABLED     0U
/*---------- -----------*/
#define USBD_SELF_POWERED     1U
/*---------- -----------*/
#define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE     64U
/*---------- -----------*/
#define USBD_CUSTOM_HID_REPORT_DESC_SIZE     33U
/*---------- -----------*/
#define CUSTOM_HID_FS_BINTERVAL     0x1U

/****************************************/

收发数据长度 时间间隔 usbd_customhid.h

/** @defgroup USBD_CUSTOM_HID_Exported_Defines
  * @{
  */
#ifndef CUSTOM_HID_EPIN_ADDR
#define CUSTOM_HID_EPIN_ADDR                         0x81U
#endif /* CUSTOM_HID_EPIN_ADDR */

#ifndef CUSTOM_HID_EPIN_SIZE
#define CUSTOM_HID_EPIN_SIZE                         0x40U
#endif /* CUSTOM_HID_EPIN_SIZE */

#ifndef CUSTOM_HID_EPOUT_ADDR
#define CUSTOM_HID_EPOUT_ADDR                        0x01U
#endif /* CUSTOM_HID_EPOUT_ADDR */

#ifndef CUSTOM_HID_EPOUT_SIZE
#define CUSTOM_HID_EPOUT_SIZE                        0x40U
#endif /* CUSTOM_HID_EPOUT_SIZE*/

#define USB_CUSTOM_HID_CONFIG_DESC_SIZ               41U
#define USB_CUSTOM_HID_DESC_SIZ                      9U

#ifndef CUSTOM_HID_HS_BINTERVAL
#define CUSTOM_HID_HS_BINTERVAL                      0x05U
#endif /* CUSTOM_HID_HS_BINTERVAL */

#ifndef CUSTOM_HID_FS_BINTERVAL
#define CUSTOM_HID_FS_BINTERVAL                      0x05U
#endif /* CUSTOM_HID_FS_BINTERVAL */

#ifndef USBD_CUSTOMHID_OUTREPORT_BUF_SIZE
#define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE            0x02U
#endif /* USBD_CUSTOMHID_OUTREPORT_BUF_SIZE */

#ifndef USBD_CUSTOM_HID_REPORT_DESC_SIZE
#define USBD_CUSTOM_HID_REPORT_DESC_SIZE             163U
#endif /* USBD_CUSTOM_HID_REPORT_DESC_SIZE */

#define CUSTOM_HID_DESCRIPTOR_TYPE                   0x21U
#define CUSTOM_HID_REPORT_DESC                       0x22U

#define CUSTOM_HID_REQ_SET_PROTOCOL                  0x0BU
#define CUSTOM_HID_REQ_GET_PROTOCOL                  0x03U

#define CUSTOM_HID_REQ_SET_IDLE                      0x0AU
#define CUSTOM_HID_REQ_GET_IDLE                      0x02U

#define CUSTOM_HID_REQ_SET_REPORT                    0x09U
#define CUSTOM_HID_REQ_GET_REPORT                    0x01U

通信关键函数:

usb hid 数据发送函数:usbd_customhid.c 中
	uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len)
usb hid 数据接收回调函数:usbd_custom_hid_it.c中
	static int8_t CUSTOM_HID_OutEvent_FS(uint8_t event_idx, uint8_t state)

拷贝代码

/* 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句柄,第二个参数的是接收的末端地址;要获取发送的数据长度的话就把第二个参数改为发送末端地址即可
    
    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 */
  if (USBD_CUSTOM_HID_ReceivePacket(&hUsbDeviceFS) != (uint8_t)USBD_OK)
  {
    return -1;
  }
  return (USBD_OK);
  /* USER CODE END 6 */
}

main.c

添加如下代码

extern USBD_HandleTypeDef hUsbDeviceFS; //外部声明USB的句柄
/* USER CODE END Includes */
...
/* USER CODE BEGIN PV */
unsigned char USB_Recive_Buffer[64] = {0}; //USB接收缓存
unsigned char USB_Received_Count = 0;//USB接收数据计数
/* USER CODE END PV */
...
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    HAL_Delay(1000);
	debug("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);
	HAL_UART_Transmit_DMA(&huart1, (uint8_t *)USB_Recive_Buffer, 64);
	debug("\r\n");
	HAL_Delay(1000);
	debug("USB_Received_Count=== %d\r\n",USB_Received_Count);
	}
  /* USER CODE END 3 */

四、测试

如果和图中的一样,恭喜你,和我的水平一样了。✊ ✊ ✊ ✊ ✊ ✊ ✊ ✊

总结

慢慢来,尖刺就是生梨。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
单片机外围模块漫谈之五,USB开发,这个错误你犯了吗?
INA3221的使用教程(IIC)
mtk android mcp camera更改
STM32F4xx移植USB-HID库-详细步骤五
物联网之LoRa开发与应用二(驱动移植)
基于STM32的redboot移植,(去掉FSMC,仅用片内64KRAM)[原创]
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服