手势已经完成蛮久的时间了,今天完成成果篇。
一、总纲:
1、功能分析及模块介绍
2、STM32CubeMX生成工程
3、代码
4、硬件连接
5、视频
二、下面开始对手势的进程进行解析:
1、功能分析及模块介绍
NUCLEO-H503 开发板:
特性微控制器:型号:STM32H503系列,具体型号可能包括STM32H503RB等。内核:基于ARM® Cortex®-M33内核,该内核带DSP和浮点单元(FPU),工作频率高达250 MHz。性能:在250MHz频率下,从Flash存储器执行时,STM32H503能够提供375DMIPS/1023 CoreMark性能,并利用意法半导体的ART加速器™实现FLASH零等待状态。存储:通常配备128 KB Flash和32 KB RAM,但请注意,不同型号或配置可能有所不同。通信外设:多达13个通信外设,包括I3C、FD-CAN、USB 2.0全速主机和从机等。手势模块PAJ7620U2
手势识别能力:PAJ7620U2可识别多种手势,可识别9种基本手势(上、下、左、右、前、后、顺时针旋转、逆时针旋转、挥动),而在低速模式下可识别多达13种手势,包括慢速上下、慢速左右、慢速前后及乱序等。支持自定义手势识别,用户可根据需求定义特定的手势动作。通信接口:采用IIC(I2C)接口,支持高达400Khz的通信速率,便于与微控制器(MCU)等设备进行连接和数据传输。
这里只介绍一下主要的两个模块,继电器与蜂鸣器就不多讲,非常的简单。
2、STM32CubeMX生成工程
新建工程
查找H503开发板步骤:
STM32H503RBTxLQFP64界面:
时钟配置:
设置输出文件:
点击GENERATE CODE生成工程:
下面就可以开始点灯了。
三、核心代码
VOID USBD_HID_Keyboard_Activate(VOID *hid_instance) { /* USER CODE BEGIN USBD_HID_Keyboard_Activate */ //UX_PARAMETER_NOT_USED(hid_instance); hid_keyboard = (UX_SLAVE_CLASS_HID*)hid_instance; /* USER CODE END USBD_HID_Keyboard_Activate */ return; }函数定义:
VOID USBD_HID_Keyboard_Activate(VOID *hid_instance): 这是一个没有返回值的函数,接受一个VOID指针作为参数,这个指针指向HID设备实例。
用户代码区域:/* USER CODE BEGIN USBD_HID_Keyboard_Activate */ 和 /* USER CODE END USBD_HID_Keyboard_Activate */ 之间的代码是用户自定义代码区域。这意味着你可以在这个区域内添加或修改代码,而不影响其他部分的代码
注释掉的代码://UX_PARAMETER_NOT_USED(hid_instance);: 这行代码被注释掉了。如果取消注释,它将用于指示hid_instance参数在函数体内未被使用,这可以帮助避免编译器警告未使用的参数。
激活代码:hid_keyboard = (UX_SLAVE_CLASS_HID*)hid_instance;: 这行代码将传入的hid_instance参数转换为UX_SLAVE_CLASS_HID类型的指针,并将其赋值给hid_keyboard变量。这实际上是在激活或初始化键盘设备实例,以便后续操作。
函数返回:return;: 函数执行完毕后返回。// 向I2C设备写入一个字节 void DEV_I2C_WriteByte(UBYTE add_, UBYTE data_) { UBYTE Buf[1] = {0}; // 创建一个长度为1的缓冲区,用于存储要写入的数据 Buf[0] = data_; // 将要写入的数据存储到缓冲区中 // 调用HAL库函数,向I2C设备写入数据 // 参数依次为:I2C句柄,设备地址,寄存器地址,寄存器地址大小,数据缓冲区,数据长度,超时时间 HAL_I2C_Mem_Write(&hi2c1, IIC_Addr_t, add_, I2C_MEMADD_SIZE_8BIT, Buf, 1, 0x10); } // 向I2C设备写入一个字(两个字节) void DEV_I2C_WriteWord(UBYTE add_, UWORD data_) { UBYTE Buf[2] = {0}; // 创建一个长度为2的缓冲区,用于存储要写入的字 Buf[0] = data_ >> 8; // 将字的高8位存储到缓冲区的第一个位置 Buf[1] = data_; // 将字的低8位存储到缓冲区的第二个位置 // 调用HAL库函数,向I2C设备写入字 HAL_I2C_Mem_Write(&hi2c1, IIC_Addr_t, add_, I2C_MEMADD_SIZE_8BIT, Buf, 2, 0x10); } // 从I2C设备读取一个字节 UBYTE DEV_I2C_ReadByte(UBYTE add_) { UBYTE Buf[1]={add_}; // 创建一个长度为1的缓冲区,用于存储读取到的数据(注意这里可能是一个错误,通常应该是{0}或其他合适的初始值) // 调用HAL库函数,从I2C设备读取数据 HAL_I2C_Mem_Read(&hi2c1, IIC_Addr_t, add_, I2C_MEMADD_SIZE_8BIT, Buf, 1, 0x10); return Buf[0]; // 返回读取到的数据 } // 从I2C设备读取一个字(两个字节) UWORD DEV_I2C_ReadWord(UBYTE add_) { UBYTE Buf[2]={0, 0}; // 创建一个长度为2的缓冲区,用于存储读取到的字 // 调用HAL库函数,从I2C设备读取字 HAL_I2C_Mem_Read(&hi2c1, IIC_Addr_t, add_, I2C_MEMADD_SIZE_8BIT, Buf, 2, 0x10); // 将读取到的两个字节组合成一个字并返回 return ((Buf[1] << 8) | (Buf[0] & 0xff)); }
static void Gesture_GetKeyData(UX_SLAVE_CLASS_HID_EVENT *hid_event) { // 初始化HID事件长度和缓冲区 hid_event->ux_device_class_hid_event_length = 8; memset(hid_event->ux_device_class_hid_event_buffer, 0, sizeof(hid_event->ux_device_class_hid_event_buffer)); // 检查是否有手势按键事件 if (gesture_key.type != 0) { // 根据手势类型设置对应的HID事件缓冲区内容 switch (gesture_key.type) { case PAJ_UP: // 上 hid_event->ux_device_class_hid_event_buffer[2] = 0x52; // 设置为特定值 break; case PAJ_DOWN: // 下 hid_event->ux_device_class_hid_event_buffer[2] = 0x51; // 设置为特定值 break; case PAJ_LEFT: // 左 hid_event->ux_device_class_hid_event_buffer[2] = 0x50; // 设置为特定值 break; case PAJ_RIGHT: // 右 hid_event->ux_device_class_hid_event_buffer[2] = 0x4F; // 设置为特定值 break; case PAJ_CLOCKWISE:// 顺时针 hid_event->ux_device_class_hid_event_buffer[2] = 0x3E; // F5键 break; case PAJ_COUNT_CLOCKWISE:// 逆时针 hid_event->ux_device_class_hid_event_buffer[2] = 0x29; // ESC键 break; case PAJ_WAVE: // 挥动 // 设置为0或特定值,此处未指定具体行为 break; default: // 未定义的手势类型,不执行任何操作 break; } } }
四、硬件连接
工作状态
五、视频
https://www.bilibili.com/video/BV1G1b7eMEfV/?vd_source=f74b5cde30d6973f0ab1f1f47abd41b9