【stm32协议外设篇】- PAJ7620手势识别传感器

一、适用场景

适用场景:非接触式人机交互(菜单翻页、音量/频道切换、灯光控制、机器人/车体手势遥控)、手势唤醒、嵌入式交互原型与课程实验。

二、器材清单

PAJ7620 手势识别模块(常见为 GY-PAJ7620模组) ×1

stm32f1 开发板 ×1

若干杜邦线(母对母)×1组

三、工作原理(要点)

PAJ7620有两种功能,一是检测手势,另一个则是检测物体的大小和距离

检测手势:内置红外光学阵列 + 算法,直接输出 9 种手势识别结果:Up, Down, Left, Right, Forward (靠近), Backward (远离), Clockwise, Counter-clockwise, Wave。可通过 I²C 寄存器直接读取识别结果。

检测范围:Normal / Near / Far 模式下典型检测距离约 5--15 cm(Near)或 15--30 cm(Far),视模块/封装与环境而定;视角对角约 60°(Near)等。

四、接线示意(常见模块 4 脚)

VCC → +5V

GND → GND

标准库

PA5 →SCL

PA7 →SDA

HAL库

PA5 →SCL

PA7 →SDA

五、示例代码

标准库

cpp 复制代码
#include "stm32f10x.h"
#include "stdio.h"
#include "bsp_SysTick.h"
#include "bsp_usart.h"
#include "oled.h"

 
int main(void)
{ 
	 SysTick_Init();	    	 //延时函数初始化	  
	 gpio_init();	  		//初始化与LED连接的硬件接口
	 USART_Config1();

	 Usart_SendString(USART1,"wait\n");
	 delay_us(500000);
	Usart_SendString(USART1,"waitok\n");
 	while(!paj7620u2_init())//PAJ7620U2传感器初始化
	{
	    Usart_SendString(USART1,"paj7620u2 error\n");
	    delay_us(5000000);
	}
	delay_us(500000);
  Usart_SendString(USART1,"paj7620u2 ok\n");
	while(1)
	{
		paj7620u2_sensor_test();//PAJ7620U2传感器测试
	}
}
#include "oled.h"
#include "stdio.h"
#include "stdlib.h"
#include "oledfont.h" 
#include "bsp_SysTick.h"

char show[20];
extern u8 mode;
void gpio_init()
{
	GPIO_InitTypeDef PA;
	
	//使能时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	PA.GPIO_Pin = GPIO_Pin_5 |GPIO_Pin_7;
	PA.GPIO_Mode = GPIO_Mode_Out_PP;
	PA.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&PA);
	
	scl_h;
	sda_h;
}


void DS1302_IO_GPIO(u8 FLAG)
{
  GPIO_InitTypeDef GPIO_InitStructre;
  //RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);            /*open GPIO  clock*/
    /**********配置数据IO端口 输出 **********/
    if(FLAG==0x01)
  {
    GPIO_InitStructre.GPIO_Pin= GPIO_Pin_7;//配置IO_GPIO
  GPIO_InitStructre.GPIO_Speed=GPIO_Speed_50MHz;
  GPIO_InitStructre.GPIO_Mode=GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructre);
  }
    /**********配置数据IO端口 输入**********/
    else if(FLAG==0x00)
  {
     GPIO_InitStructre.GPIO_Pin= GPIO_Pin_7;//配置IO_GPIO
   GPIO_InitStructre.GPIO_Speed=GPIO_Speed_50MHz;
   GPIO_InitStructre.GPIO_Mode=GPIO_Mode_IPU;  //配置上拉输入
   GPIO_Init(GPIOA, &GPIO_InitStructre);
   }
}


//产生IIC起始信号
void IIC_Start(void)
{
	DS1302_IO_GPIO(out);     	//sda线输出
	sda_h;
	scl_h;
	delay_us(4);
 	sda_l;//START:when CLK is high,DATA change form high to low 
	delay_us(4);
	scl_l;	//钳住I2C总线,准备发送或接收数据 
}

//产生IIC停止信号
void IIC_Stop(void)
{
	DS1302_IO_GPIO(out);		//sda线输出
	scl_l;
	sda_l;		//STOP:when CLK is high DATA change form low to high
 	delay_us(4);
	scl_h; 
	sda_h;		//发送I2C总线结束信号
	delay_us(4);							   	
}

//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
u8 IIC_Wait_Ack(void)
{
	u8 ucErrTime=0,ack;
	DS1302_IO_GPIO(in);      //SDA设置为输入  
	sda_h;
	delay_us(3);	   
	scl_h;
	delay_us(3);
	if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7) == RESET)
	{
		ack=0;
	}else
		ack=1;
	scl_l//时钟输出0 	   
	return ack;  
} 

//产生ACK应答
void IIC_Ack(void)
{
	scl_l;
	DS1302_IO_GPIO(out);
	sda_l;
	delay_us(3);
	scl_h;
	delay_us(3);
	scl_l;
}

//不产生ACK应答		    
void IIC_NAck(void)
{
	scl_l;
	DS1302_IO_GPIO(out);
	sda_h;
	delay_us(2);
	scl_h;
	delay_us(2);
	scl_l;
}

//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答			  
void IIC_Send_Byte(u8 txd)
{                        
    u8 t;   
	DS1302_IO_GPIO(out); 	    
    scl_l;//拉低时钟开始数据传输
    for(t=0;t<8;t++)
    {              
        if(txd&0x80)
		{
			sda_h;
		}else
			sda_l;
		txd<<=1; 	  
		delay_us(5);   //对TEA5767这三个延时都是必须的
		scl_h;
		delay_us(5); 
		scl_l;	
		delay_us(5);
    }	 
}

//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
u8 IIC_Read_Byte(unsigned char ack)
{
	unsigned char i,receive=0;
	DS1302_IO_GPIO(in);//SDA设置为输入
    for(i=0;i<8;i++ )
	{
        scl_l; 
        delay_us(4);
				scl_h;
        receive<<=1;
        if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7))receive++;   
				delay_us(4); 
    }					 
    if (!ack)
        IIC_NAck();//发送nACK
    else
        IIC_Ack(); //发送ACK   
	
    return receive;
}








//PAJ7620U2写一个字节数据
u8 GS_Write_Byte(u8 REG_Address,u8 REG_data)
{
	IIC_Start();
	IIC_Send_Byte(PAJ7620_ID);
	if(IIC_Wait_Ack())
	{
		IIC_Stop();//释放总线
		return 1;//没应答则退出

	}
	IIC_Send_Byte(REG_Address);
	IIC_Wait_Ack();	
	IIC_Send_Byte(REG_data);
	IIC_Wait_Ack();	
	IIC_Stop();

	return 0;
}

//PAJ7620U2读一个字节数据
u8 GS_Read_Byte(u8 REG_Address)
{
	u8 REG_data;
	
	IIC_Start();
	IIC_Send_Byte(PAJ7620_ID);//发写命令
	if(IIC_Wait_Ack())
	{
		 IIC_Stop();//释放总线
		 return 0;//没应答则退出
	}		
	IIC_Send_Byte(REG_Address);
	IIC_Wait_Ack();
	IIC_Start(); 
	IIC_Send_Byte(PAJ7620_ID|0x01);//发读命令
	IIC_Wait_Ack();
	REG_data = IIC_Read_Byte(0);
	IIC_Stop();

	return REG_data;
}
//PAJ7620U2读n个字节数据
u8 GS_Read_nByte(u8 REG_Address,u16 len,u8 *buf)
{
	IIC_Start();
	IIC_Send_Byte(PAJ7620_ID);//发写命令
	if(IIC_Wait_Ack()) 
	{
		IIC_Stop();//释放总线
		return 1;//没应答则退出
	}
	IIC_Send_Byte(REG_Address);
	IIC_Wait_Ack();

	IIC_Start();
	IIC_Send_Byte(PAJ7620_ID|0x01);//发读命令
	IIC_Wait_Ack();
	while(len)
	{
		if(len==1)
		{
			*buf = IIC_Read_Byte(0);
		}
		else
		{
			*buf = IIC_Read_Byte(1);
		}
		buf++;
		len--;
	}
	IIC_Stop();//释放总线

	return 0;
	
}
//PAJ7620唤醒
void GS_WakeUp(void)
{
	IIC_Start();
	IIC_Send_Byte(PAJ7620_ID);//发写命令
	IIC_Stop();//释放总线
}


//选择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寄存器区域
	}
			
}

//PAJ7620U2唤醒
u8 paj7620u2_wakeup(void)
{ 
	u8 data=0x0a;
	GS_WakeUp();//唤醒PAJ7620U2
	delay_us(5000);//唤醒时间>400us
	GS_WakeUp();//再次唤醒,以确认PAJ7620U2正常工作
	delay_us(5000);//唤醒时间>400us
	paj7620u2_selectBank(BANK0);//进入BANK0寄存器区域
	data = GS_Read_Byte(0x00);//读取状态
	if(data!=0x20) return 0; //唤醒失败
	
	return 1;
}

//PAJ7620U2初始化
//返回值:0:失败 1:成功
u8 paj7620u2_init(void)
{
	u8 i;
	u8 status;
	
	gpio_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;
}


//手势识别测试
void Gesture_test(void)
{
	u8 i;
  u8 status;
	u8 data[2]={0x00};
	u16 gesture_data;
	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;
	while(1)
	{
		if(mode=='c')
		{
			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:              
					                         Usart_SendString(USART1,"UP\r\n");break; //向上
					case GES_DOWM:                  
               						         Usart_SendString(USART1,"Down\r\n");break; //向下
					case GES_LEFT:                       
  						                     Usart_SendString(USART1,"Left\r\n");break; //向左
					case GES_RIGHT:                 
                						       Usart_SendString(USART1,"Right\r\n");break; //向右
					case GES_FORWARD:            
						                       Usart_SendString(USART1,"Forward\r\n");break; //向前
					case GES_BACKWARD:          
            						           Usart_SendString(USART1,"Backward\r\n");break; //向后
					case GES_CLOCKWISE:          
                						       Usart_SendString(USART1,"Clockwise\r\n");break; //顺时针
					case GES_COUNT_CLOCKWISE:  
                   						     Usart_SendString(USART1,"AntiClockwise\r\n");break; //逆时针
					case GES_WAVE:                
						                       Usart_SendString(USART1,"Wave\r\n");break; //挥动
					default:  break;
					
				}	

			}
			
		}
		delay_us(500000);
	}
}

//接近检测测试
void Ps_test(void)
{
    u8 i;
	u8 data[2]={0x00};
	u8 obj_brightness=0;
	u16 obj_size=0;
	
	paj7620u2_selectBank(BANK0);//进入BANK0寄存器区域
	for(i=0;i<PROXIM_SIZE;i++)
	{
		GS_Write_Byte(proximity_arry[i][0],proximity_arry[i][1]);//接近检测模式初始化
	}
	paj7620u2_selectBank(BANK0);//返回BANK0寄存器区域
	i=0;
	
	while(1)
	{	
		if(mode=='c') break;
		
		obj_brightness = GS_Read_Byte(PAJ_GET_OBJECT_BRIGHTNESS);//读取物体亮度
		data[0] = GS_Read_Byte(PAJ_GET_OBJECT_SIZE_1);//读取物体大小
		data[1] = GS_Read_Byte(PAJ_GET_OBJECT_SIZE_2);
		obj_size = ((u16)data[1] & 0x0f)<<8 | data[0];
		sprintf(show,"light:%d,size:%d\r\n",obj_brightness,obj_size);
		Usart_SendString(USART1,show);
		
		delay_us(500000);

	}
	
}
//PAJ7620U2传感器测试
void paj7620u2_sensor_test(void)
{   
	 while(1)
	 {
		 switch(mode)
		 {
		  case 'h':  Gesture_test();   break;//手势检测模式
			case 'n':  Ps_test();        break;//接近检测模式  
		 }
		delay_us(50000);	 
	 }
}

HAL库

cpp 复制代码
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  MX_TIM2_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
	HAL_UART_Receive_IT(&huart2, &RxOneByte, 1);
	HAL_UART_Transmit(&huart2,"wait\r\n",strlen("wait\r\n"),HAL_MAX_DELAY);
	HAL_Delay(500);
	HAL_UART_Transmit(&huart2,"waitok\r\n",strlen("waitok\r\n"),HAL_MAX_DELAY);
 	while(!paj7620u2_init())//PAJ7620U2传感器初始化
	{
		HAL_UART_Transmit(&huart2,"paj7620u2 error\r\n",strlen("paj7620u2 error\r\n"),HAL_MAX_DELAY);
	  HAL_Delay(5000);
	}
	HAL_Delay(500);
	HAL_UART_Transmit(&huart2,"paj7620u2ok\r\n",strlen("paj7620u2ok\r\n"),HAL_MAX_DELAY);
	uint8_t id = GS_Read_Byte(0x00);
	char buf[32];
	sprintf(buf, "PAJ ID = 0x%02X\r\n", id);
	HAL_UART_Transmit(&huart2, buf, strlen(buf), HAL_MAX_DELAY);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		paj7620u2_sensor_test();
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
#include "stdio.h"
#include "stdlib.h"
#include "paj7620.h"
#include <string.h>
#include "paj7620font.h" 
char show[20];
uint8_t RxOneByte;
u8 mode='h';
extern TIM_HandleTypeDef htim2;
extern UART_HandleTypeDef huart2;
/**
 * @brief   基于 TIM2 的微秒级阻塞延时
 * @param   us: 延时微秒数
 */
void Tims_delay_us(uint32_t us)
{
    const uint32_t max_chunk = 0xFFFF;  // 16 位定时器最大

    // 分段延时,每段不超过 65535us
    while (us >= max_chunk)
    {
        __HAL_TIM_SET_COUNTER(&htim2, 0);         // 计数器清零
        HAL_TIM_Base_Start(&htim2);               // 启动定时器
        while (__HAL_TIM_GET_COUNTER(&htim2) < max_chunk)
        {
            /* 等待计数到达 max_chunk */
        }
        HAL_TIM_Base_Stop(&htim2);                // 停止定时器
        us -= max_chunk;
    }

    // 处理剩余小于 65535 的部分
    if (us > 0)
    {
        __HAL_TIM_SET_COUNTER(&htim2, 0);
        HAL_TIM_Base_Start(&htim2);
        while (__HAL_TIM_GET_COUNTER(&htim2) < us)
        {
            /* 等待剩余时间 */
        }
        HAL_TIM_Base_Stop(&htim2);
    }
}


void DS1302_IO_GPIO(u8 FLAG)
{
	__HAL_RCC_GPIOA_CLK_ENABLE();
	GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(FLAG==0x01)
  {
      /*  ??  */
		  GPIO_InitStruct.Pin = GPIO_PIN_7;                //  9???
      GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;      //  Push Pull ??????
      GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;    //  ??
			GPIO_InitStruct.Pull = GPIO_NOPULL;
  }
  else 
  {
      GPIO_InitStruct.Pin = GPIO_PIN_7;                   //  9???
      GPIO_InitStruct.Mode = GPIO_MODE_INPUT;             //  ???? 
			GPIO_InitStruct.Pull = GPIO_PULLUP;		
  }
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}


//产生IIC起始信号
void IIC_Start(void)
{
	DS1302_IO_GPIO(out);     	//sda线输出
	sda_h;
	scl_h;
	Tims_delay_us(4);
 	sda_l;//START:when CLK is high,DATA change form high to low 
	Tims_delay_us(4);
	scl_l;	//钳住I2C总线,准备发送或接收数据 
}

//产生IIC停止信号
void IIC_Stop(void)
{
	DS1302_IO_GPIO(out);		//sda线输出
	scl_l;
	sda_l;		//STOP:when CLK is high DATA change form low to high
 	Tims_delay_us(4);
	scl_h; 
	sda_h;		//发送I2C总线结束信号
	Tims_delay_us(4);							   	
}

//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
u8 IIC_Wait_Ack(void)
{
	u8 ucErrTime=0,ack;
	DS1302_IO_GPIO(in);      //SDA设置为输入  
	sda_h;
	Tims_delay_us(3);	   
	scl_h;
	Tims_delay_us(3);
	if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7) == RESET)
	{
		ack=0;
	}else
		ack=1;
	scl_l//时钟输出0 	   
	return ack;  
} 

//产生ACK应答
void IIC_Ack(void)
{
	scl_l;
	DS1302_IO_GPIO(out);
	sda_l;
	Tims_delay_us(3);
	scl_h;
	Tims_delay_us(3);
	scl_l;
}

//不产生ACK应答		    
void IIC_NAck(void)
{
	scl_l;
	DS1302_IO_GPIO(out);
	sda_h;
	Tims_delay_us(2);
	scl_h;
	Tims_delay_us(2);
	scl_l;
}

//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答			  
void IIC_Send_Byte(u8 txd)
{                        
    u8 t;   
	DS1302_IO_GPIO(out); 	    
    scl_l;//拉低时钟开始数据传输
    for(t=0;t<8;t++)
    {              
        if(txd&0x80)
		{
			sda_h;
		}else
			sda_l;
		txd<<=1; 	  
		Tims_delay_us(5);   //对TEA5767这三个延时都是必须的
		scl_h;
		Tims_delay_us(5); 
		scl_l;	
		Tims_delay_us(5);
    }	 
}

//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
u8 IIC_Read_Byte(unsigned char ack)
{
	unsigned char i,receive=0;
	DS1302_IO_GPIO(in);//SDA设置为输入
  for(i=0;i<8;i++)
	{
    scl_l; 
    Tims_delay_us(4);
		scl_h;
    receive<<=1;
    if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7))receive++;   
		Tims_delay_us(4); 
  }					 
  if (!ack)
      IIC_NAck();//发送nACK
  else
      IIC_Ack(); //发送ACK   
	
  return receive;
}








//PAJ7620U2写一个字节数据
u8 GS_Write_Byte(u8 REG_Address,u8 REG_data)
{
	IIC_Start();
	IIC_Send_Byte(PAJ7620_ID);
	if(IIC_Wait_Ack())
	{
		IIC_Stop();//释放总线
		return 1;//没应答则退出

	}
	IIC_Send_Byte(REG_Address);
	IIC_Wait_Ack();	
	IIC_Send_Byte(REG_data);
	IIC_Wait_Ack();	
	IIC_Stop();

	return 0;
}

//PAJ7620U2读一个字节数据
u8 GS_Read_Byte(u8 REG_Address)
{
	u8 REG_data;
	
	IIC_Start();
	IIC_Send_Byte(PAJ7620_ID);//发写命令
	if(IIC_Wait_Ack())
	{
		 IIC_Stop();//释放总线
		 return 0;//没应答则退出
	}		
	IIC_Send_Byte(REG_Address);
	IIC_Wait_Ack();
	IIC_Start(); 
	IIC_Send_Byte(PAJ7620_ID|0x01);//发读命令
	IIC_Wait_Ack();
	REG_data = IIC_Read_Byte(0);
	IIC_Stop();

	return REG_data;
}
//PAJ7620U2读n个字节数据
u8 GS_Read_nByte(u8 REG_Address,u16 len,u8 *buf)
{
	IIC_Start();
	IIC_Send_Byte(PAJ7620_ID);//发写命令
	if(IIC_Wait_Ack()) 
	{
		IIC_Stop();//释放总线
		return 1;//没应答则退出
	}
	IIC_Send_Byte(REG_Address);
	IIC_Wait_Ack();

	IIC_Start();
	IIC_Send_Byte(PAJ7620_ID|0x01);//发读命令
	IIC_Wait_Ack();
	while(len)
	{
		if(len==1)
		{
			*buf = IIC_Read_Byte(0);
		}
		else
		{
			*buf = IIC_Read_Byte(1);
		}
		buf++;
		len--;
	}
	IIC_Stop();//释放总线

	return 0;
	
}
//PAJ7620唤醒
void GS_WakeUp(void)
{
	IIC_Start();
	IIC_Send_Byte(PAJ7620_ID);//发写命令
	IIC_Stop();//释放总线
}


//选择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寄存器区域
	}
			
}

//PAJ7620U2唤醒
u8 paj7620u2_wakeup(void)
{ 
	u8 data=0x0a;
	GS_WakeUp();//唤醒PAJ7620U2
	HAL_Delay(5);//唤醒时间>400us
	GS_WakeUp();//再次唤醒,以确认PAJ7620U2正常工作
	HAL_Delay(5);//唤醒时间>400us
	paj7620u2_selectBank(BANK0);//进入BANK0寄存器区域
	data = GS_Read_Byte(0x00);//读取状态
	if(data!=0x20) return 0; //唤醒失败
	
	return 1;
}

//PAJ7620U2初始化
//返回值:0:失败 1:成功
u8 paj7620u2_init(void)
{
	u8 i;
	u8 status;
	
  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;
}


//手势识别测试
void Gesture_test(void)
{
	u8 i;
  u8 status;
	u8 data[2]={0x00};
	u16 gesture_data;
	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;
	while(1)
	{
		if(mode=='c')
		{
			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:HAL_UART_Transmit(&huart2,"UP\r\n",strlen("UP\r\n"),HAL_MAX_DELAY);break; //向上
					case GES_DOWM:HAL_UART_Transmit(&huart2,"Down\r\n",strlen("Down\r\n"),HAL_MAX_DELAY);break; //向下
					case GES_LEFT:HAL_UART_Transmit(&huart2,"Left\r\n",strlen("Left\r\n"),HAL_MAX_DELAY);break; //向左
					case GES_RIGHT:HAL_UART_Transmit(&huart2,"Right\r\n",strlen("Right\r\n"),HAL_MAX_DELAY);break;  //向右               
					case GES_FORWARD:HAL_UART_Transmit(&huart2,"Forward\r\n",strlen("Forward\r\n"),HAL_MAX_DELAY);break; //向前
					case GES_BACKWARD:HAL_UART_Transmit(&huart2,"Backward\r\n",strlen("Backward\r\n"),HAL_MAX_DELAY);break;//向后
					case GES_CLOCKWISE:HAL_UART_Transmit(&huart2,"Clockwise\r\n",strlen("Clockwise\r\n"),HAL_MAX_DELAY);break; //顺时针
					case GES_COUNT_CLOCKWISE:HAL_UART_Transmit(&huart2,"AntiClockwise\r\n",strlen("AntiClockwise\r\n"),HAL_MAX_DELAY);break;//逆时针
					case GES_WAVE:HAL_UART_Transmit(&huart2,"Wave\r\n",strlen("Wave\r\n"),HAL_MAX_DELAY);break;//挥动
					default:  break;
				}	
			}	
		}
		HAL_Delay(500);
	}
}

//接近检测测试
void Ps_test(void)
{
  u8 i;
	u8 data[2]={0x00};
	u8 obj_brightness=0;
	u16 obj_size=0;
	
	paj7620u2_selectBank(BANK0);//进入BANK0寄存器区域
	for(i=0;i<PROXIM_SIZE;i++)
	{
		GS_Write_Byte(proximity_arry[i][0],proximity_arry[i][1]);//接近检测模式初始化
	}
	paj7620u2_selectBank(BANK0);//返回BANK0寄存器区域
	i=0;
	
	while(1)
	{	
		if(mode=='c') break;
		
		obj_brightness = GS_Read_Byte(PAJ_GET_OBJECT_BRIGHTNESS);//读取物体亮度
		data[0] = GS_Read_Byte(PAJ_GET_OBJECT_SIZE_1);//读取物体大小
		data[1] = GS_Read_Byte(PAJ_GET_OBJECT_SIZE_2);
		obj_size = ((u16)data[1] & 0x0f)<<8 | data[0];
		sprintf(show,"light:%d,size:%d\r\n",obj_brightness,obj_size);
		HAL_UART_Transmit(&huart2,show,strlen(show),HAL_MAX_DELAY);
		
		HAL_Delay(500);

	}
	
}
//PAJ7620U2传感器测试
void paj7620u2_sensor_test(void)
{   
	 while(1)
	 {
		 switch(mode)
		 {
		  case 'h':  Gesture_test();   break;//手势检测模式
			case 'n':  Ps_test();        break;//接近检测模式  
		 }
		HAL_Delay(50);	 
	 }
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if (huart->Instance == USART2)
    {
        mode = RxOneByte;  // 上一步启动 DMA/IT 时指定的接收变量
				HAL_UART_Transmit(&huart2,&mode,1,HAL_MAX_DELAY);
        // 再次开启下一个字节接收
        HAL_UART_Receive_IT(&huart2, &RxOneByte, 1);
    }
}

六、讲解视频

https://www.bilibili.com/video/BV1Hd1LBcEVj/?spm_id_from=333.1387.upload.video_card.click&vd_source=f7dfe1b14f260b9cc3a146d2dbfd0719

相关推荐
烛衔溟2 小时前
C语言算法:排序算法入门
c语言·算法·排序算法·插入排序·冒泡排序·选择排序·多关键字排序
Laity______2 小时前
指针(2)
c语言·开发语言·数据结构·算法
是苏浙2 小时前
零基础入门C语言之C语言实现数据结构之顺序表经典算法
c语言·开发语言·数据结构·算法
Jerry丶Li3 小时前
二十七、通信接口
c语言·stm32·单片机·嵌入式硬件
沸速存储4 小时前
DDR5引领变革:内存条行业的技术迭代与市场重构
嵌入式硬件·电脑
飞睿科技4 小时前
【IoT开发选型】乐鑫ESP32-C6核心优势解析:为何它在无线连接中表现如此全面?
嵌入式硬件·物联网
heisd_15 小时前
STM32时钟系统对于STM32F1系列(详解)
stm32·单片机·嵌入式硬件
应用市场5 小时前
STM32 ADC底层原理与寄存器配置详解
stm32·单片机·嵌入式硬件
d111111111d5 小时前
STM32外设学习--DMA直接存储器读取--学习笔记。
笔记·stm32·单片机·嵌入式硬件·学习