这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【Let'sDo第1期任务手势翻页笔】——提高作业:PAJ7620U2数据的实时

共2条 1/1 1 跳转至

【Let'sDo第1期任务手势翻页笔】——提高作业:PAJ7620U2数据的实时读取+USB枚举

菜鸟
2024-07-15 01:21:41     打赏

开环境介绍

此次开发按照个人习惯 Keil5+STM32CubeMX 的开发环境进行此次开发。

二、任务介绍

       提高作业(必做):
       1.实现STM32H503RB开发板的USB HIDKeyboard枚举成功;
       2.实现PAJ7620U2数据的实时读取;

三、实现分析

这个任务算是STM32中的进阶和拔高任务,分别用到了I2C外设和USB外设,属于有点难度的,在课程中,老师讲解了如何在第一节的基础上分别配置两种外设的模式。同时我们需要了解如何使用这些模块,去其他网站找一些相关资料和课程来完成本次设计。同时参考了

azhw大佬的方案 https://forum.eepw.com.cn/thread/383176/1

付明大佬的方案 https://forum.eepw.com.cn/thread/382689/1

感谢!感谢!感谢!

四、所需设备

       STM32H503RB开发板

       USB C to A数据线两根(要注意选择可以进行数据传输的,仅有供电功能的无法下载)

安装有Keil5+STM32CubeMX软件的电脑进行程序开发调试

PAJ7620U2模块

五、硬件原理

实验使用的是seeed studio的Grove-Gesture v1.0,

其官方的文档地址为:  https://wiki.seeedstudio.com/Grove-Gesture_v1.0/

        硬件的基本参数:

            l  内置9个手势类型:上,下,左,右,前,后,顺时针旋转,逆时针旋转,挥动。

            l  支持接近检测功能,检测物体体积大小和亮度。

            l  分辨率:60x60 pixels   ,每个像素的大小是:20x20 um2 , 最大支持的速率:720fps。  

            l  模式:gesture / cursor / image modes

            l  控制速度:在普通模式下:60~600°/s

            l  通讯模式:I2C模式(for gesture/ cursor 模式):最高能达到400kbit/s

image.png

      image.png

        传感器带的四针插头,与CN10的引脚间距不兼容。还好家里还有之前买的杜邦线,转接一下。

IMG_8073.JPG

        六、软件编程——图形化配置工具初始化外设

        打开STM32CubeMX,点击“ACCESS TO MCU SELECTOR”开始创建工程

image.png        在commercial part number栏中选择STM32H503RBT6。

image.png        根据自己的需要配置时钟,这里配置为:High Speed Clock(HSE)设置为Crystal/Ceramic Resonator。点击“Clock Configuration”,设置时钟频率:晶振频率设置为24MHz,选择HSE通道,最高频率设置为250MHz

image.png

image.png

        点击“Trace and Debug“- ”Debug“,设置Debug模式为Serial Wire。

image.png

        点击“Pinout& Configuration”将PA5配置为GPIO_Output。

image.png

        点击“Connectivity”-“USART3”,设置USART3 Mode为Asynchronous;点击“Parameter Settings”,设置Baud Rate为115200 Bits/s;点击“NVIC Settings”,勾选“USART3 global interrupt“为enable。

image.png

        配置硬件I2C外设

        使能I2C1,并重新配置IO口PB6/PB7为I2C1。

image.png

        在Project Manager填写Project Name,设置ToolChain/IDE为MDK-ARM,设置Min Version为V5.37。

        点击“Generate Code“即可完成代码的生成。

        点击“Open Project”便可以直接使用Keil打开该工程。


    七、编写代码

        在生成的代码中,我们就可以编译了。

        此处需要注意:所有的代码都要写在注释区BEGIN和END中间!!!

        此处需要注意:所有的代码都要写在注释区BEGIN和END中间!!!

        此处需要注意:所有的代码都要写在注释区BEGIN和END中间!!!

        I2C基本收发字节的函数

            CubeMX配置好外设,HAL自带I2C通讯的基本读写字节基本功能代码。

            HAL_I2C_Mem_Write()和HAL_I2C_Mem_Read()直接对外设地址,实现PAJ7620驱动。

             根据已有的资料,我们需要定义paj7620相关的.h和.c文件。内容分别是:

//PAJ7620地址寄存器定义  
#define PAJ7620_I2C_ADDRESS        0x73<<1     //paj7620的i2c地址,7bit  
#define PAJ_BANK_SELECT            0xEF        //寄存器页选择寄存器:Bank0=0x00, Bank1=0x01  
#define PAJ_INT_FLAG1              0x43        //检测结果数据低八位数据所在地址  
#define PAJ_INT_FLAG2              0x44        //检测结果数据高八位数据所在地址  

//手势状态定义  
#define PAJ_ZERO                   0x00        //未检测到任何手势 
#define PAJ_UP                     0x01        //上  
#define PAJ_DOWN                   0x02        //下  
#define PAJ_LEFT                   0x04        //左  
#define PAJ_RIGHT                  0x08        //右  
#define PAJ_FORWARD                0x10        //接近  
#define PAJ_BACKWARD               0x20        //远离  
#define PAJ_CLOCKWISE              0x40        //顺时针旋转  
#define PAJ_COUNT_CLOCKWISE        0x80        //逆时针旋转  
#define PAJ_WAVE                   0x100       //挥动

  
uint8_t paj7620_init(void);        //PAJ7620U2初始化函数  
uint16_t getGesture(void);             //PAJ7620U2获取手势识别函数  
void usart_print_gesture(uint16_t status);       //通过串口打印手势信息
uint8_t Init_Register_Array[][2] = {
	{0xEF, 0x00},
  {0x32, 0x29},
  {0x33, 0x01},
  {0x34, 0x00},
  {0x35, 0x01},
  {0x36, 0x00},
  {0x37, 0x07},
  {0x38, 0x17},
  {0x39, 0x06},
  {0x3A, 0x12},
  {0x3F, 0x00},
  {0x40, 0x02},
  {0x41, 0xFF},
  {0x42, 0x01},
  {0x46, 0x2D},
  {0x47, 0x0F},
  {0x48, 0x3C},
  {0x49, 0x00},
  {0x4A, 0x1E},
  {0x4B, 0x00},
  {0x4C, 0x20},
  {0x4D, 0x00},
  {0x4E, 0x1A},
  {0x4F, 0x14},
  {0x50, 0x00},
  {0x51, 0x10},
  {0x52, 0x00},
  {0x5C, 0x02},
  {0x5D, 0x00},
  {0x5E, 0x10},
  {0x5F, 0x3F},
  {0x60, 0x27},
  {0x61, 0x28},
  {0x62, 0x00},
  {0x63, 0x03},
  {0x64, 0xF7},
  {0x65, 0x03},
  {0x66, 0xD9},
  {0x67, 0x03},
  {0x68, 0x01},
  {0x69, 0xC8},
  {0x6A, 0x40},
  {0x6D, 0x04},
  {0x6E, 0x00},
  {0x6F, 0x00},
  {0x70, 0x80},
  {0x71, 0x00},
  {0x72, 0x00},
  {0x73, 0x00},
  {0x74, 0xF0},
  {0x75, 0x00},
  {0x80, 0x42},
  {0x81, 0x44},
  {0x82, 0x04},
  {0x83, 0x20},
  {0x84, 0x20},
  {0x85, 0x00},
  {0x86, 0x10},
  {0x87, 0x00},
  {0x88, 0x05},
  {0x89, 0x18},
  {0x8A, 0x10},
  {0x8B, 0x01},
  {0x8C, 0x37},
  {0x8D, 0x00},
  {0x8E, 0xF0},
  {0x8F, 0x81},
  {0x90, 0x06},
  {0x91, 0x06},
  {0x92, 0x1E},
  {0x93, 0x0D},
  {0x94, 0x0A},
  {0x95, 0x0A},
  {0x96, 0x0C},
  {0x97, 0x05},
  {0x98, 0x0A},
  {0x99, 0x41},
  {0x9A, 0x14},
  {0x9B, 0x0A},
  {0x9C, 0x3F},
  {0x9D, 0x33},
  {0x9E, 0xAE},
  {0x9F, 0xF9},
  {0xA0, 0x48},
  {0xA1, 0x13},
  {0xA2, 0x10},
  {0xA3, 0x08},
  {0xA4, 0x30},
  {0xA5, 0x19},
  {0xA6, 0x10},
  {0xA7, 0x08},
  {0xA8, 0x24},
  {0xA9, 0x04},
  {0xAA, 0x1E},
  {0xAB, 0x1E},
  {0xCC, 0x19},
  {0xCD, 0x0B},
  {0xCE, 0x13},
  {0xCF, 0x64},
  {0xD0, 0x21},
  {0xD1, 0x0F},
  {0xD2, 0x88},
  {0xE0, 0x01},
  {0xE1, 0x04},
  {0xE2, 0x41},
  {0xE3, 0xD6},
  {0xE4, 0x00},
  {0xE5, 0x0C},
  {0xE6, 0x0A},
  {0xE7, 0x00},
  {0xE8, 0x00},
  {0xE9, 0x00},
  {0xEE, 0x07},
  {0xEF, 0x01},
  {0x00, 0x1E},
  {0x01, 0x1E},
  {0x02, 0x0F},
  {0x03, 0x10},
  {0x04, 0x02},
  {0x05, 0x00},
  {0x06, 0xB0},
  {0x07, 0x04},
  {0x08, 0x0D},
  {0x09, 0x0E},
  {0x0A, 0x9C},
  {0x0B, 0x04},
  {0x0C, 0x05},
  {0x0D, 0x0F},
  {0x0E, 0x02},
  {0x0F, 0x12},
  {0x10, 0x02},
  {0x11, 0x02},
  {0x12, 0x00},
  {0x13, 0x01},
  {0x14, 0x05},
  {0x15, 0x07},
  {0x16, 0x05},
  {0x17, 0x07},
  {0x18, 0x01},
  {0x19, 0x04},
  {0x1A, 0x05},
  {0x1B, 0x0C},
  {0x1C, 0x2A},
  {0x1D, 0x01},
  {0x1E, 0x00},
  {0x21, 0x00},
  {0x22, 0x00},
  {0x23, 0x00},
  {0x25, 0x01},
  {0x26, 0x00},
  {0x27, 0x39},
  {0x28, 0x7F},
  {0x29, 0x08},
  {0x30, 0x03},
  {0x31, 0x00},
  {0x32, 0x1A},
  {0x33, 0x1A},
  {0x34, 0x07},
  {0x35, 0x07},
  {0x36, 0x01},
  {0x37, 0xFF},
  {0x38, 0x36},
  {0x39, 0x07},
  {0x3A, 0x00},
  {0x3E, 0xFF},
  {0x3F, 0x00},
  {0x40, 0x77},
  {0x41, 0x40},
  {0x42, 0x00},
  {0x43, 0x30},
  {0x44, 0xA0},
  {0x45, 0x5C},
  {0x46, 0x00},
  {0x47, 0x00},
  {0x48, 0x58},
  {0x4A, 0x1E},
  {0x4B, 0x1E},
  {0x4C, 0x00},
  {0x4D, 0x00},
  {0x4E, 0xA0},
  {0x4F, 0x80},
  {0x50, 0x00},
  {0x51, 0x00},
  {0x52, 0x00},
  {0x53, 0x00},
  {0x54, 0x00},
  {0x57, 0x80},
  {0x59, 0x10},
  {0x5A, 0x08},
  {0x5B, 0x94},
  {0x5C, 0xE8},
  {0x5D, 0x08},
  {0x5E, 0x3D},
  {0x5F, 0x99},
  {0x60, 0x45},
  {0x61, 0x40},
  {0x63, 0x2D},
  {0x64, 0x02},
  {0x65, 0x96},
  {0x66, 0x00},
  {0x67, 0x97},
  {0x68, 0x01},
  {0x69, 0xCD},
  {0x6A, 0x01},
  {0x6B, 0xB0},
  {0x6C, 0x04},
  {0x6D, 0x2C},
  {0x6E, 0x01},
  {0x6F, 0x32},
  {0x71, 0x00},
  {0x72, 0x01},
  {0x73, 0x35},
  {0x74, 0x00},
  {0x75, 0x33},
  {0x76, 0x31},
  {0x77, 0x01},
  {0x7C, 0x84},
  {0x7D, 0x03},
  {0x7E, 0x01},
};
//初始化,返回0则初始化失败
uint8_t PAJ7620U2_init(void)
{
	uint8_t i,State,n;
	State = 0;
	while(HAL_OK != HAL_I2C_Mem_Write(&hi2c1,PAJ7620U2_I2C_ADDRESS,0xef,I2C_MEMADD_SIZE_8BIT,&State,1,500)){HAL_Delay(5);printf("1");}
 
	for (i=0;i< 219 ;i++)
	{
		while(HAL_OK != HAL_I2C_Mem_Write(&hi2c1,PAJ7620U2_I2C_ADDRESS,Init_Register_Array[i][0],I2C_MEMADD_SIZE_8BIT,&Init_Register_Array[i][1],1,500)){HAL_Delay(5);printf("2");}
		HAL_Delay(5);
	}
	
	while(HAL_OK != HAL_I2C_Mem_Write(&hi2c1,PAJ7620U2_I2C_ADDRESS,0xef,I2C_MEMADD_SIZE_8BIT,&State,1,500)){HAL_Delay(5);printf("3");}
	HAL_Delay(5);
	
	while (HAL_OK != HAL_I2C_Mem_Read(&hi2c1,PAJ7620U2_I2C_ADDRESS,0x32,I2C_MEMADD_SIZE_8BIT,&n,1,500)){HAL_Delay(5);printf("4");}
	if(n != 0x29)
	{
	return 0;
	}
	
	return 1;
}
 
//检测手势并输出
void gesture(void)
{	
	uint8_t Data[2]={0,0};
	uint16_t Gesture_Data;
	HAL_I2C_Mem_Read(&hi2c1,PAJ7620U2_I2C_ADDRESS,PAJ_INT_FLAG1,I2C_MEMADD_SIZE_8BIT,&Data[0],1,500);
	HAL_Delay(5);
 
	HAL_I2C_Mem_Read(&hi2c1,PAJ7620U2_I2C_ADDRESS,PAJ_INT_FLAG2,I2C_MEMADD_SIZE_8BIT,&Data[1],1,500);
	HAL_Delay(5);
 
	Gesture_Data= Data[1]<<8 | Data[0];
	printf("\n %x \r\n",Gesture_Data);
	if(Gesture_Data !=0)
	{	
	switch (Gesture_Data)
			{
				case PAJ_UP:			  			  printf("Up\r\n");				break;
				case PAJ_DOWN:							printf("Down\r\n");				break;
				case PAJ_LEFT:							printf("Left\r\n");				break;
				case PAJ_RIGHT:							printf("Right\r\n"); 			break;
				case PAJ_FORWARD:						printf("Forward\r\n");			break;
				case PAJ_BACKWARD:					printf("Backward\r\n"); 		break;
				case PAJ_CLOCKWISE:					printf("Clockwise\r\n"); 		break;
				case PAJ_COUNT_CLOCKWISE:		printf("AntiClockwise\r\n"); 	break;
				case PAJ_WAVE:							printf("Wave\r\n"); 			break;
				default: break;
			}
			Gesture_Data=0;
		}		
}

        主函数main.C中调用

	  gesture_statu = getGesture();        //检测手势
      usart_print_gesture(gesture_statu);  //打印手势状态


        效果演示

image.png

image.png

        八、增加USBHIDKeyboard功能

image.png

        启用ThreadX操作系统

image.png

        配置ThreadX的usb库USBX

image.png

修改ux_device_keyboard.c代码

修改app_usbx_device.c代码

然后重新生成代码。

保持ST-LINK的下载线不变,同时接入另一根线到电脑Host。

然后下载代码到板子中,测试功能,可新建一个PPT复制几页,写入内容以便于区别。

image.png

image.png






关键词: 手势翻页笔     I2C     PAJ7620     USB枚举    

菜鸟
2024-07-15 04:09:47     打赏
2楼

视频:https://www.bilibili.com/video/BV1Lub2esEro/


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]