STM32WBA6是首款配备高速USB OTG控制器的STM32WBA系列产品。本次通过STM32CubeMX来配置USB外设功能,并基于USBX协议栈实现USB鼠标设备进行测试。
下面打开STM32CubeMX,通过开发板模式新建工程。
第一步使能外部高速时钟。

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


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

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


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

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

到这里就可以点击生成代码工程了。生成keil工程成功后就需要修改相关代码了。
代码工程这里花了好多时间,参考了USB例子工程才最终成功实现了USB设备正常工作。
代码修改部分如下:
第1步:屏蔽MX_USBX_Device_Init();初始化。添加MX_USBX_Init();初始化。这里估计是STM32CubeMX生成的框架错误了。


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


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

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

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

第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循环中添加任务代码

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


 
|