哭死!到底做错了哪一步,帖子为啥只剩一半!555
一、在开发板上实现USB HID模拟键盘的功能。
以前只玩过ESP模块的蓝牙模拟键盘鼠标的实验。第一次在STM32上实现通过USB HID模拟键盘功能。参考着论坛帖子一步一步地完成了复现(感谢anger老师)。
1 使用STM32CubeMX进行系统配置。这里需要留意软件的版本号,先前使用了旧版的STM32CubeMX,在配置USBX时,总是没有对应的选项。

需要配置USBX,将USB口添加为键盘。修改USB的缓存。



2 使用STM32CubeMX添加ThreadX。添加实时操作系统threadx,这样就可以使用多任务的方式操作多个外设了。

3 编码实现USB键盘。
系统复位后,首先调用main函数,在main函数中初始化ThreadX,调用MX_ThreadX_Init()方法去启动内核。此时会调用UINT MX_USBX_Device_Init(VOID *memory_ptr) 对USB设备初始化,并且创建一个新任务

static VOID app_ux_device_thread_entry(ULONG thread_input)
{
/* USER CODE BEGIN app_ux_device_thread_entry */
/* Initialization of USB device */
USBX_APP_Device_Init();
/* USER CODE END app_ux_device_thread_entry */
}
/* USER CODE BEGIN 1 */
/**
* @brief Function implementing usbx_hidkeyboard_thread_entry.
* @param thread_input: User thread input parameter.
* @retval none
*/
static VOID usbx_hidkeyboard_thread_entry(ULONG thread_input)
{
/* USER CODE BEGIN app_ux_device_thread_entry */
UX_SLAVE_DEVICE *device;
UX_SLAVE_CLASS_HID_EVENT hid_event;
TX_PARAMETER_NOT_USED(thread_input);
device = &_ux_system_slave->ux_system_slave_device;
ux_utility_memory_set(&hid_event, 0, sizeof(UX_SLAVE_CLASS_HID_EVENT));
while (1)
{
/* Check if the device state already configured */
if ((device->ux_slave_device_state == UX_DEVICE_CONFIGURED) && (hid_keyboard != UX_NULL))
{
/* sleep for 10ms */
tx_thread_sleep(MS_TO_TICK(100));
if (gesture_key.valid != 0)
{
printf("gesture_key.valid=%d %d\n", gesture_key.valid, gesture_key.type);
gesture_key.valid = 0;
Gesture_GetKeyData(&hid_event);
//发�?�键盘码
ux_device_class_hid_event_set(hid_keyboard, &hid_event);
}
else
{
ClearKeyData(&hid_event);
ux_device_class_hid_event_set(hid_keyboard, &hid_event);
}
}
else
{
/* sleep for 10ms */
tx_thread_sleep(MS_TO_TICK(10));
}
}
/* USER CODE END app_ux_device_thread_entry */
}通过这个任务,调用手势传感器获取手势信息,将手势信息映射成键盘码(四个箭头对应的键盘码),并发送给上位机。
二、PAJ7620U2手势传感器的读取。
1 PAJ720U2模块介绍:PAJ720U2手势识别传感器是一款强大的3D手势识别交互式传感器;在最远20cm范围内,最多可以识别13种手势。具备良好的手势识别稳定性和节能机制。就像是模块上有个摄像头,通过获得到的图像数据进行分析,得到手势的类型,并且将结果写入寄存器,通过IIC协议读取寄存器内容,即可获得手势信息。这里反复阅读了页面的介绍这里提供了Arduino下读取PAJ7620的代码,可以用来做参考。
2、PAJ7620U2模块编码:在PAJ7620内部有两个BANK 寄存器区域,分别是BANK0,BANK1。控制着不同的功能。这里唤醒PAJ7620模块后,直接将功能码写入到对应的BANK中去。
unsigned char PAJ7620u2_init(void)
{
unsigned char status;
HAL_Delay(10);
status = paj7620u2_wakeup(); //唤醒PAJ7620U2
if (!status)
return 0;
paj7620u2_selectBank(BANK0); // enter BANK0
HAL_Delay(50);
/* Load the registers data */
for (uint8_t i = 0; i < INIT_REG_ARRAY_SIZE; i++)
writeReg(initRegisterArray[i][0], initRegisterArray[i][1]); // init PAJ7620U2
paj7620u2_selectBank(BANK0); // enter BANK0
return 1;
}然后去读取寄存器,即可获得PAJ7620U2模块采集到的动作信息。
unsigned char getResult(void)
{
char buf[16];
char tpcVariable[16];
Gesture_Init();
gesture.detect = PAJ7620_Read_nByte(PAJ_GET_INT_FLAG1, 2, &gesture.data[0]); // 读取手势状态
if (gesture.detect)
{
gesture.type = (unsigned short)gesture.data[1] << 8 | gesture.data[0];
if (gesture.type)
{
gesture_key.type = gesture.type;
switch (gesture.type)
{
case GES_UP:
printf("Up\r\n");
gesture.valid = 1;
gesture_key.valid = 1;
break; //
case GES_DOWN:
printf("Down\r\n");
gesture.valid = 1;
gesture_key.valid = 1;
break; //
case GES_LEFT:
printf("Left\r\n");
gesture.valid = 1;
gesture_key.valid = 1;
break; //
case GES_RIGHT:
printf("Right\r\n");
gesture.valid = 1;
gesture_key.valid = 1;
break; //
case GES_FORWARD:
printf("Forward\r\n");
gesture.valid = 1;
break; //
case GES_BACKWARD:
printf("Backward\r\n");
gesture.valid = 1;
break; //
case GES_CLOCKWISE:
printf("Clockwise\r\n");
gesture.valid = 1;
break; //
case GES_ANTI_CLOCKWISE:
printf("Counterclockwise\r\n");
gesture.valid = 1;
break; //
case GES_WAVE:
printf("Wave\r\n");
gesture.valid = 1;
break; //
default:
gesture.valid = 0;
break;
}
}
}
return 0;
}
三、实现翻页功能。
将获得的手势信息映射为键盘码,这里只映射了4个键盘码:上、下、左、右。上传给电脑,就可以实现在PPT展示时前后的翻页功能了。
static void Gesture_GetKeyData(UX_SLAVE_CLASS_HID_EVENT *hid_event)
{
hid_event->ux_device_class_hid_event_length = 8;
hid_event->ux_device_class_hid_event_buffer[0] = 0;
hid_event->ux_device_class_hid_event_buffer[1] = 0;
if (gesture_key.type)
{
switch (gesture_key.type)
{
case GES_UP:
hid_event->ux_device_class_hid_event_buffer[2] = 0x52;
break; //??
case GES_DOWN:
hid_event->ux_device_class_hid_event_buffer[2] = 0x51;
break; //??
case GES_LEFT:
hid_event->ux_device_class_hid_event_buffer[2] = 0x50;
break; //??
case GES_RIGHT:
hid_event->ux_device_class_hid_event_buffer[2] = 0x4F;
break; //??
case GES_FORWARD:
break;
case GES_BACKWARD:
break;
case GES_CLOCKWISE:
hid_event->ux_device_class_hid_event_buffer[2] = 0x50;
break; //F5
case GES_ANTI_CLOCKWISE:
hid_event->ux_device_class_hid_event_buffer[2] = 0x4F;
break; //ESC
case GES_WAVE:
hid_event->ux_device_class_hid_event_buffer[2] = 0;
break; //
default:
break;
}
}
}
我要赚赏金
