STM32F1_PAJ7260U2

手势识别传感器—PAJ7260U2

1、 PAJ7260U2的特点

		①IIC 接口,支持高达 400Khz 通信速率。
		②内置9个手势类型(上、下、左、右、前、后、顺时针旋转、逆时针旋转、挥动),支持输出中断。
		③支持接近检测功能,检测物体体积大小和亮度。
		④待机功耗电流 15uA。
	    ⑤抗灯光干扰

2、工作过程

STM32F1_PAJ7260U2_第1张图片
PAJ7620U2 内部自带 LED 驱动器,传感器感应阵列、目标信息提取阵列和手势识别阵列。
PAJ7620U2 工作时通过内部 LED 驱动器,驱动红外 LED向外发射红外线信号。
当传感器阵列在有效的距离中探测到物体时,目标信息提取阵列会对探测目标进行特征原始数据的获取,获取的数据会存在寄存器中。
同时手势识别阵列会对原始数据进行识别处理,最后将手势结果存到寄存器中,用户可根据 I2C 接口对原始数据和手势识别的结果进行读取。

3、代码解析

1)IIC底层驱动(STM32的部分函数解释)

**** 通过宏定义来设置相应IO口引脚的输入输出,一个GPIOx组有16个引脚,前八个引脚由寄存器CRH控制,后八个引脚由寄存器CRL控制,(CRH和CRL都为32位的寄存器),每四位控制一个IO口引脚,两位控制输入输出,两位控制速度和模式。****
#define GS_SDA_IN() {GPIOA->CRH&=0XFFFF0FFF;GPIOA->CRH|=8<<12;}
#define GS_SDA_OUT() {GPIOA->CRH&=0XFFFF0FFF;GPIOA->CRH|=3<<12;}

	/*IIC发送一个字节返回从机有无应答,返回:1,有应答;0,无应答*/		  
	static void GS_IIC_Send_Byte(u8 txd)
	{                        
	    u8 t;   			//循环控制变量
		GS_SDA_OUT(); 	    //主机发送数据或者命令给从机,引脚设为输出模式
	    GS_IIC_SCL=0;       //要使SDA可以为任意电平,SCL时钟需要拉低,开始数据传输
	    for(t=0;t<8;t++)    //每次发送或者接收的数据或命令都为8位
	    {     
	    	/*从高位开始传送,再从低位,如果取出的位为1,则SDA输出的数据为1,反之为0 */        
			if((txd&0x80)>>7)     //假设要发送的数据为1001 0000(只写出传送前两位)
				GS_IIC_SDA=1;     //t=0时:1001 0000 & 1000 0000=1000 0000						
			else				  //>>7:0000 0001,此时GS_IIC_SDA=1;
				GS_IIC_SDA=0;	  //txd<<=1: 0001 0000
			txd<<=1; 	  		  //t=1时:0001 0000 & 1000 000=0000 0000
			delay_us(5);  		  //>>7: 0000 0000,此时GS_IIC_SDA=1;   
			GS_IIC_SCL=1;	      
			delay_us(5);          
			GS_IIC_SCL=0;	      //在SCL由低电平-高电平-低电平期间,SDA 的数据不能被改变
			delay_us(5);
	    }	 
	} 
	-------------------------------------------------------------------------------------------------------------------------------------
    /*读1个字节,ack=1时,发送ACK,ack=0,发送nACK*/
	static u8 GS_IIC_Read_Byte(u8 ack)
	{
	    u8 i,receive=0;      //receive用来接收一个字节,即八位的数据
		GS_SDA_IN();         //SDA设置为输入(主机向从机读取一个字节)
		for(i=0;i<8;i++ )
		{
			GS_IIC_SCL=0;    //允许数据的接收和发送			//假设读取的数据是 1101 0000
			delay_us(4);															//由于先读取高位再读取低位,故经过一轮循环后
		    GS_IIC_SCL=1;	 //保持数据的稳定性					//receive=0000 0001,第二轮循环中
			receive<<=1;	 //用来一位一位地接收数据				//receive<<=1,receive=0000 0010
			if(GS_READ_SDA)receive++;  //接收到读取的字节并且返回 	//receive=0000 0011
		  delay_us(4); 										    //后面的一次类推
		}	
		/*当发送完八位数据后,我们可以通过ack来终止或者继续通信*/				 
		if (!ack)
			GS_IIC_NAck();//发送nACK
		else
			GS_IIC_Ack(); //发送ACK   
		return receive;
	}
   --------------------------------------------------------------------------------------------------------------------------------------

STM32F1_PAJ7260U2_第2张图片

    /*PAJ7620U2写一个字节数据*/
	u8 GS_Write_Byte(u8 REG_Address,u8 REG_data)
	{
		GS_IIC_Start();                 //启动信号
		GS_IIC_Send_Byte(PAJ7620_ID);   //发送器件地址
		if(GS_IIC_Wait_Ack())           //等待应答
		{
			GS_IIC_Stop();//释放总线
			return 1;//没应答则退出
		}
		GS_IIC_Send_Byte(REG_Address);    //发送寄存器地址
		GS_IIC_Wait_Ack();	              //等待应答
		GS_IIC_Send_Byte(REG_data);       //发送数据
		GS_IIC_Wait_Ack();	              //等待应答
		GS_IIC_Stop();                    //停止信号
		return 0;
     }
-------------------------------------------------------------------------------------------------------------------------------------

STM32F1_PAJ7260U2_第3张图片

	/*PAJ7620U2读一个字节数据*/
	u8 GS_Read_Byte(u8 REG_Address)
	{
		u8 REG_data;
		GS_IIC_Start();                 //启动信号
		GS_IIC_Send_Byte(PAJ7620_ID);   //发送器件地址+写命令
		if(GS_IIC_Wait_Ack())           //等待应答
		{
			 GS_IIC_Stop();//释放总线
			 return 0;//没应答则退出
		}		
		GS_IIC_Send_Byte(REG_Address);    //发送寄存器地址
		GS_IIC_Wait_Ack();                //等待应答
		GS_IIC_Start();                   //启动信号
		GS_IIC_Send_Byte(PAJ7620_ID|0x01);//发送器件地址+读命令
		GS_IIC_Wait_Ack();                //等待应答
		REG_data = GS_IIC_Read_Byte(0);   //已经读取了一个字节的数据,不需要再次读取,传入0输出非应答信号,不再接收
		GS_IIC_Stop();                    //停止信号
		return REG_data;
	}
	-------------------------------------------------------------------------------------------------------------------------------------
	/*PAJ7620U2读n个字节数据*/
	u8 GS_Read_nByte(u8 REG_Address,u16 len,u8 *buf)
	{
	    GS_IIC_Start();
		GS_IIC_Send_Byte(PAJ7620_ID);    //发写命令
		if(GS_IIC_Wait_Ack()) 
		{
			GS_IIC_Stop();//释放总线
			return 1;//没应答则退出
		}
		GS_IIC_Send_Byte(REG_Address);
		GS_IIC_Wait_Ack();
	
		GS_IIC_Start();
		GS_IIC_Send_Byte(PAJ7620_ID|0x01);//发读命令
		GS_IIC_Wait_Ack();
		while(len)                        //用来判断读取的字节数
		{
			if(len==1)					  //若len==1,则GS_IIC_Read_Byte(0)中的参数为0,停止继续读取,否则继续读取字节数
			{
				*buf = GS_IIC_Read_Byte(0);
			}
			else
			{
				*buf = GS_IIC_Read_Byte(1);
			}
			buf++;
			len--;
		}
		GS_IIC_Stop();//释放总线	
		return 0;	
	}

2)PAJ7260U2驱动(STM32的部分函数解释)

** PAJ7260U2在首次上电时处于挂起状态,上电后还不能正常工作,需要唤醒,等待的时间为>700us,然后进入bank0寄存器区域,写入0x00,判断接收的值是否为0x20,若是,则已经唤醒成功,退出bank0区域,执行其他操作。**

    /*PAJ7620U2唤醒,  返回0:失败;返回1:成功*/
	u8 paj7620u2_wakeup(void)
	{ 
	    u8 data=0x0a;
		GS_WakeUp();//唤醒PAJ7620U2
		delay_ms(5);//唤醒时间>700us
		GS_WakeUp();//唤醒PAJ7620U2
		delay_ms(5);//唤醒时间>700us			
		/*通过查询bank0中0x00寄存器,是否等于0x20,来判断是否唤醒成功*/
		paj7620u2_selectBank(BANK0);//进入BANK0寄存器区域
		data = GS_Read_Byte(0x00);//读取状态
		if(data!=0x20) return 0; //唤醒失败		
		return 1;
	}

** PAJ7260U2在唤醒后需要写入上电初始化数组**

    /*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寄存器区域	
		/*init_Array:上电初始化数组,INIT_SIZE=init_Array/2*/
		for(i=0;i

** 手势识别测试**

	/*PAJ7260U2有三个数组,上电初始化、接近检测、手势识别,三个初始化都为二维数组,第一个字节表示寄存器地址,第二个字节表示要设置的值*/
	void Gesture_test(void)
	{
		u8 i;
	    u8 status; //变量
		u8 data[2]={0x00}; //data[0]=data[1]=0x00   相当于是两个八位的寄存器,用来存储九种手势的状态
		u16 gesture_data; //手势的数据
		paj7620u2_selectBank(BANK0);//进入BANK0寄存器区域
		for(i=0;i

你可能感兴趣的:(STM32F1,传感器,模块)