一.简介:
1.内置光源和环境光抑制滤波器集成的 LED,镜头和手势感测器在一个小的立方体模组,能在黑暗或低光环境下工作
2.PAJ7620U2 的特点包括:
①IIC 接口,支持高达 400Khz 通信速率。
②内置 9 个手势类型(上、下、左、右、前、后、顺时针旋转、逆时针旋转、挥动),
支持输出中断。
③支持接近检测功能,检测物体体积大小和亮度
3.PAJ7620U2 内部自带 LED 驱动器,传感器感应阵列、目标信息提取阵列和手势识别阵列
二.工作原理:
PAJ7620U2 工作时通过内部 LED 驱动器,驱动红外 LED向外发射红外线信号,当传感器阵列在有效的距离中探测到物体时,目标信息提取阵列会对探测目标进行特征原始数据的获取,获取数据会存在寄存器中,同时手势识别阵列会对原始数据进行识别处理,最后将手势结果存到寄存器中,用户可根据 I2C 接口对原始数据和手势识别的结果进行读取
三.模块常用寄存器简介
1.在 PAJ7620U2 的内部有两个 BANK 寄存器区域,分别是 BANK0和 BANK12.想访问其中的 BANK 区域下的寄存器,需在访问前发送控制指令进入该寄存器区域,具体控制指令如表 1.3.1 所示:
进入 BANK0 区域往传感器 0xEF 地址写 0x00 数值,而 BANK1 区域往传感器 0xEF 地址写 0x01 数值① PAJ7620U2 使能工作寄存器在BANK1
地址0x72
只关心 bit0 位,设置为 1,则使能PAJ7620 工作,设置为 0,则失能 PAJ7620U2 工作②BANK0 下的挂起管理寄存器
地址0x03
使能和挂起操作
要进入挂起状态,首先通过写寄存器Bank 1, ADDR Ox72 with Oxoo禁用PAJ7620U2,然后通过写寄存器Bank O, ADDR Ox03 with Ox01处理IC suspend命令。
要退出挂起状态,首先通过写入从ID(参考主题“12C总线时序特征和协议”)处理I2C唤醒命令,然后通过使用Ox01写入寄存器Bank 1, ADDR 0x72启用PAJ7620U2
退出挂起到唤醒工作,则需执行 3 个步骤:
③检测手势寄存器
BANK0 下的手势检测输出中断使能寄存器 1
地址0x41
bit0 位为“上”、bit1 位为“下”、bit2 位为“左”、bit3 位为“右”、bit4 位为
“前”、bit5 位为“后”、bit6 位为“顺时针旋转”、而 bit7 位为“逆时针旋转”
对应位设置为 1,则使能,当检测到对应的手势识别时,会输出对应手势识别结果中断BANK0 下的手势检测输出中断使能寄存器 2
地址0x42
该寄存器保留7:1位
bit0 为用于使能手势识别“挥动”的输出中断
④标志寄存器:当 PAJ7620U2 检测到内置的手势,则对应的寄存器手势标志会置 1,读取标志可清除对应的中断标志位。用户根据读取对应的状态,可知道当前手势识别
的结果
BANK0 的手势识别中断标志寄存器 2
地址0x43
BANK0 的手势识别中断标志寄存器 2
地址0x44
5.BANK0 的检测物体亮度寄存器
地址0xb0
当物体在 PAJ7620U2 的有效检测距离内,读取该寄存器能获得物体的亮度,亮度值为 0~2556.BANK0 的检测物体体积大小寄存器
地址0XB2,0XB1
0XB2 寄存器的低四位值和 0XB1寄存器八位值
体积值为 0~900
四.开发板实验
- 流程图
模块初始化:上电初始化
手势识别测试:需要先手势初始化
接近检测测试:需要先接近检测初始化
所谓初始化就是把商家提供的配置组写入BANK0
在 PAJ7620U2 的初始化中,需配置多个寄存器,而有些寄存器手册没提及到,不过幸好的是手册上有提供配置数组给用户,我们直接调用就可以了。
同样手势识别和接近检测,手册也有提供初始化配置数组,我们也是调用就可以了
2. 硬件连接
模块通过 IIC 接口与外部进行通信,上电时,默认的 IIC 从机地址为:0X73(使用时需
左移一位)
3.软件实现
新建 paj7620u2.c、paj7620u2.h、paj7620u2_iic.c、
paj7620u2_iic.h、paj7620u2_cfg.h 共 5 个文件
paj7620u2.c 文件为手势识别和接近检测的驱动
paj7620u2_iic 文件为底层的 IIC 驱动
paj7620u2_cfg.h 文件为存放上电初始化、手势
识别初始化、以及接近检测初始化的配置数组
a.在 paj7620u2_cfg.h 中
在
在这三个数组里包含上电,接近检测,手势识别数组,是二维数组,每个数组的第一个字节为寄存器号(也就是寄存器地址),第二个字节为要设置的值
b.在 paj7620u2_iic.c 文件
该文件包括 PAJ7620U2 的 IIC 底层驱动读写函数,引脚 IO 初始化以及唤醒命令的函数
唤醒命令的函数
//PAJ7620U2 唤醒命令
void GS_WakeUp(void)
{
GS_IIC_Start();//开始
GS_IIC_Send_Byte(PAJ7620_ID);//发写命令
GS_IIC_Stop();//释放总线
}
在该函数中直接写命令,不用等待PAJ回应
c.在paj7620u2.c 文件
该文件包括手势识别和接近检测等代码
- paj7620u2_selectBank()函数,该函数实现选择 BANK 区域,通过 bank 的入口参数选择要进入 BANK 的区域
1. //选择 PAJ7620U2 BANK 区域
void paj7620u2_selectBank(bank_e bank)
{
switch(bank)
{
case BANK0: GS_Write_Byte(PAJ_REGITER_BANK_SEL,PAJ_BANK0);break;
//BANK0 寄存器区域
case BANK1: GS_Write_Byte(PAJ_REGITER_BANK_SEL,PAJ_BANK1);break;
//BANK1 寄存器区域
} }2. paj7620u2_wakeup()函数,该函数实现对 PAJ7620U2 唤醒
//PAJ7620U2 唤醒
u8 paj7620u2_wakeup(void)
{
u8 data=0x0a;
GS_WakeUp();//唤醒 PAJ7620U2
delay_ms(5);//唤醒时间>700us
GS_WakeUp();//唤醒 PAJ7620U2
delay_ms(5);//唤醒时间>700us
paj7620u2_selectBank(BANK0);//进入 BANK0 寄存器区域
data = GS_Read_Byte(0x00);//读取状态
if(data!=0x20) return 0; //唤醒失败
return 1;
}
在发送唤醒命令后需等待大于 700us 的时间,然后切换到 BANK0 区域,读取 0x00 寄存器,判断读取的值是否为 0x20,若是则唤醒成功,否则唤醒失败3.paj7620u2_init()函数,该函数实现对 PAJ7620U2 初始化
//PAJ7620U2 初始化
//返回值:0:失败 1:成功
u8 paj7620u2_init(void)
{
u8 i;
u8 status;
GS_i2c_init();//IIC 初始化
status = paj7620u2_wakeup();//唤醒 PAJ7620U2
if(!status) return 0;
paj7620u2_selectBank(BANK0);//进入 BANK0 寄存器区域
for(i=0;i<INIT_SIZE;i++)
{
GS_Write_Byte(init_Array[i][0],init_Array[i][1]);//初始化 PAJ7620U2
}
paj7620u2_selectBank(BANK0);//切换回 BANK0 寄存器区域
return 1;
}
先对 IIC 通信的 IO 引脚初始化,然后调用paj7620u2_wakeup()函数对 PAJ7620U2 进行唤醒,唤醒成功后,由于后面要调用 init_Array初始化数组,初始化时是从 BANK0 区域开始的,所以这里先选择进入 BANK0 区域,初始化数组配置完毕后,又切换回 BANK0 区域,这时 PAJ7620U2 初始化完成4.Gesrure_test()函数,该函数实现手势识别功能
一开始先对 PAJ7620U2 手势识别检测进行初始化,配置其gesture_arry 数组的参数值,该数组有使能 9 个手势识别的中断标志输出的配置,初始化完毕后,在 while 循环中一直读取手势中断标志寄存器,当识别到相应的手势,手势标志会置 1,读取寄存器标志会自动清 0
//手势识别测试-手势初始化
void Gesture_test(void)
{
u8 i;
u8 status;
u8 key;
u8 data[2]={0x00};
u16 gesture_data;
u8 ledflash=0;
//该部分为初始化手势检测
paj7620u2_selectBank(BANK0);//进入BANK0寄存器区域
for(i=0;i<GESTURE_SIZE;i++)
{
GS_Write_Byte(gesture_arry[i][0],gesture_arry[i][1]);//手势识别模式初始化
}
paj7620u2_selectBank(BANK0);//切换回BANK0寄存器区域
/******************************/
i=0;
POINT_COLOR=BLUE;//设置字体为蓝色
LCD_Fill(30,170,300,300,WHITE);
LCD_ShowString(30,180,200,16,16,“KEY_UP: Exit the test”);
LCD_ShowString(30,210,200,16,16,“Gesture test”);
POINT_COLOR=RED;//设置字体为蓝色
while(1)
{
//按键关闭检测
key = KEY_Scan(0);
if(key==WKUP_PRES)
{
GS_Write_Byte(PAJ_SET_INT_FLAG1,0X00);//关闭手势识别中断输出
GS_Write_Byte(PAJ_SET_INT_FLAG2,0X00);
break;
}
//读取手势标志位
status = GS_Read_nByte(PAJ_GET_INT_FLAG1,2,&data[0]);//读取手势状态
if(!status)
{
gesture_data =(u16)data[1]<<8 | data[0];
if(gesture_data)
{
switch(gesture_data)
{
case GES_UP: LCD_ShowString(110,250,200,16,24,"UP ");
printf(“Up\r\n”); ledflash=1; break; //向上
case GES_DOWM: LCD_ShowString(100,250,200,16,24,"Dowm ");
printf(“Dowm\r\n”); ledflash=1; break; //向下
case GES_LEFT: LCD_ShowString(100,250,200,16,24,"Left ");
printf(“Left\r\n”); ledflash=1; break; //向左
case GES_RIGHT: LCD_ShowString(100,250,200,16,24,"Right ");
printf(“Right\r\n”); ledflash=1; break; //向右
case GES_FORWARD: LCD_ShowString(80,250,200,16,24,"Forward ");
printf(“Forward\r\n”); ledflash=1; break; //向前
case GES_BACKWARD: LCD_ShowString(80,250,200,16,24,"Backward ");
printf(“Backward\r\n”); ledflash=1; break; //向后
case GES_CLOCKWISE: LCD_ShowString(70,250,200,16,24,"Clockwise ");
printf(“Clockwise\r\n”); ledflash=1; break; //顺时针
case GES_COUNT_CLOCKWISE: LCD_ShowString(50,250,200,16,24,“AntiClockwise”);
printf(“AntiClockwise\r\n”); ledflash=1; break; //逆时针
case GES_WAVE: LCD_ShowString(100,250,200,16,24,"Wave ");
printf(“Wave\r\n”); ledflash=1; break; //挥动
default: ledflash=0; break;
}
if(ledflash)//DS1闪烁
{
LED1=0;delay_ms(80);LED1=1;delay_ms(80);
LED1=0;delay_ms(80);LED1=1;delay_ms(80);
LCD_ShowString(40,250,200,16,24," ");
ledflash=0;
}
}
}
delay_ms(50);
i++;
if(i==5)
{
LED0=!LED0;//提示系统正在运行
i=0;
}
}
}
在该函数里不断读取手势中断标志位从而识别是何种手势
附:IIC协议
PAJ7620U2地址是0X73,7位寻址即左移一位
以下协议包含时序:
单写时序
单读时序
唤醒PAJ7620U2协议
全部寄存器
IIC中应答问题:应答目的是提醒发送端数据我这边已经接收完成
主机发数据给从机需要从机应答
主机读从机数据需要主机应答
IIC是按字节来传输的,当每传输完一个字节的数据,后面必须紧跟一个校验位,这个校验位是接收端通过控制SDA(数据线)来实现的,以提醒发送端数据我这边已经接收完成。
(SDA=0为ACK 接收完成 SDA=1为NACK 繁忙中)
主机应答: 传输完一个字节数据以后(数据传输方向:从机—>主机),主机控制(此时是接收端)SDA来提醒从机(发送端)我这边接受完成
从机应答: 传输完一个字节数据以后(数据传输方向:主机—>从机),从机控制(此时是接收端)SDA来提醒主机(发送端)我这边接受完成