你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【NUCLEO-WBA65RI评测】 + 基于USBX实现USB鼠标设备

[复制链接]
STMWoodData 发布时间:2025-9-22 23:52

STM32WBA6是首款配备高速USB OTG控制器的STM32WBA系列产品。本次通过STM32CubeMX来配置USB外设功能,并基于USBX协议栈实现USB鼠标设备进行测试。

下面打开STM32CubeMX,通过开发板模式新建工程。

第一步使能外部高速时钟。

image.png

第二步使能USB-OTG-HS外设,设置USB为DEVICE模式。配置相关参数。

image.png

image.png

第三步配置USBX协议栈组件。使能HID类的鼠标设备。

image.png

然后配置相关参数。关键参数如下

image.png

image.png

下面接着设置时钟树,主频100MHz。需要使用外部高速时钟。

image.png

然后就可以设置生成的工程了。这里使用KEIL工程。

image.png

到这里就可以点击生成代码工程了。生成keil工程成功后就需要修改相关代码了。

代码工程这里花了好多时间,参考了USB例子工程才最终成功实现了USB设备正常工作。

代码修改部分如下:

第1步:屏蔽MX_USBX_Device_Init();初始化。添加MX_USBX_Init();初始化。这里估计是STM32CubeMX生成的框架错误了。

image.png

image.png

第2步:新增__HAL_RCC_SYSCFG_CLK_ENABLE();初始化使能SYSCFG外设时钟,USB设备需要SYSCFG外设使能USB OTG 功能。STM32CubeMX生成的框架少了这一个初始化,导致USB外设初始化一直不成功。参考了例子工程才找到这个原因。

image.png

image.png

第3步:增加代码HAL_PCD_Start(&hpcd_USB_OTG_HS);启动USB 外设。

image.png

第4步:添加代码设置USB端点的缓存大小。

image.png

第5步:添加USBX协议栈时间获取接口:

image.png

第6步:添加USB鼠标设备发送数据任务

#define CURSOR_STEP         10
#define BUTTON_DETECT_WAIT  10

UX_SLAVE_CLASS_HID *hid_mouse;
__IO uint8_t User_Button_State = 0;

VOID USBD_HID_Mouse_Activate(VOID *hid_instance)
{
  /* USER CODE BEGIN USBD_HID_Mouse_Activate */
  UX_PARAMETER_NOT_USED(hid_instance);
  hid_mouse = (UX_SLAVE_CLASS_HID *) hid_instance;
  /* USER CODE END USBD_HID_Mouse_Activate */

  return;
}
VOID USBD_HID_Mouse_Deactivate(VOID *hid_instance)
{
  /* USER CODE BEGIN USBD_HID_Mouse_Deactivate */
  UX_PARAMETER_NOT_USED(hid_instance);
  hid_mouse = UX_NULL;
  /* USER CODE END USBD_HID_Mouse_Deactivate */

  return;
}



VOID USBX_DEVICE_HID_MOUSE_Task(VOID)
{
  ULONG tick;
  UX_SLAVE_DEVICE *device;
  UX_SLAVE_CLASS_HID_EVENT hid_event;

  device = &_ux_system_slave->ux_system_slave_device;
  ux_utility_memory_set(&hid_event, 0, sizeof(UX_SLAVE_CLASS_HID_EVENT));

  tick = HAL_GetTick();

  /* Check if the device state already configured */
  if ((device->ux_slave_device_state == UX_DEVICE_CONFIGURED) && (hid_mouse != UX_NULL))
  {

    /* Sleep for 10ms */
    if (ux_utility_time_elapsed(tick, HAL_GetTick()) > BUTTON_DETECT_WAIT)
    {
      return;
    }

    tick = HAL_GetTick();

    /* Check if user button is pressed */
    if (User_Button_State)
    {
      /* Get the new position */
      GetPointerData(&hid_event);

      /* Send an event to the hid */
      ux_device_class_hid_event_set(hid_mouse, &hid_event);

      /* Reset User Button state */
      User_Button_State = 0U;
    }
  }
}
/**
  * @brief  GetPointerData
  *         Gets Pointer Data.
  * @param  hid_event: Pointer to structure of the hid event.
  * @retval None
  */
static VOID GetPointerData(UX_SLAVE_CLASS_HID_EVENT *hid_event)
{
  static int8_t counter = 0;
  static int8_t x = 0, y = 0;

  /* Reset counter */
  if (counter == 16)
  {
    counter = 0;
  }
  /* Update pointer position x and y */
  if ((counter >= 0) && (counter < 4))
  {
    y = 0;
    x = CURSOR_STEP;
  }
  else if ((counter >= 4) && (counter < 8))
  {
    x = 0;
    y = CURSOR_STEP;
  }
  else if ((counter >= 8) && (counter < 12))
  {
    y = 0;
    x = -CURSOR_STEP;
  }
  else
  {
    x = 0;
    y = -CURSOR_STEP;
  }

  /* Increment counter */
  counter++;

  /* Mouse event. Length is fixed to 4 */
  hid_event->ux_device_class_hid_event_length = 4;

  /* Set select position */
  hid_event->ux_device_class_hid_event_buffer[0] = 0;

  /* Set X position */
  hid_event->ux_device_class_hid_event_buffer[1] = x;

  /* Set Y position */
  hid_event->ux_device_class_hid_event_buffer[2] = y;

  /* Set wheel position */
  hid_event->ux_device_class_hid_event_buffer[3] = 0;
}

第7步:在main循环中添加任务代码

image.png

到这里代码修改完成,可以编译下载了。这样就实现了按键B1按下修改鼠标坐标。

image.png

image.png

video3.gifvideo4.gif

收藏 评论0 发布时间:2025-9-22 23:52

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版