/* -----------------------------------------宏定義-----------------------------------------*/
/* -----------------------------------------頭文件-----------------------------------------*/
#include "main.h"
#include "PAJ7620U2_cfg.h"
/* -----------------------------------------結構體定義-------------------------------------*/
code IIC_TYPE PAJ7620U2 = {2, 0x73 << 1};
/* -----------------------------------------全局變量定義-----------------------------------*/
/* -----------------------------------------應用程序---------------------------------------*/
/*********************************************
函數名:PAJ7620U2_Write_DATA
功 能:寫 地址 數據
形 參:addr 地址 dat 數據
返回值:
備 注:
作 者:薛建強
時 間:2020/03/19
**********************************************/
void PAJ7620U2_Write_DATA(const uint8_t addr, const uint8_t DATA)
{
IIC_Start(); // 啓動
IIC_WriteByte(PAJ7620U2.ADDR); // 設備地址
IIC_Wait_ACK(); // 等待數據響應
IIC_WriteByte(addr); // 發送寄存器地址
IIC_Wait_ACK(); // 等待數據響應
IIC_WriteByte(DATA); // 發送數據
IIC_Wait_ACK(); // 等待數據響應
IIC_Stop(); // 停止
}
/*********************************************
函數名:PAJ7620U2_Read_DATA
功 能:讀地址數據
形 參:addr--寄存器地址
返回值:
備 注:
作 者:薛建強
時 間:2020/03/19
**********************************************/
uint8_t PAJ7620U2_Read_DATA(const uint8_t addr)
{
uint8_t GET_DATA = 0;
IIC_Start(); // 啓動
IIC_WriteByte(PAJ7620U2.ADDR); // 發送地址
IIC_Wait_ACK(); // 等待數據響應
IIC_WriteByte(addr); // 發送地址
IIC_Wait_ACK(); // 等待數據響應
IIC_Start(); // 啓動
IIC_WriteByte(PAJ7620U2.ADDR | 1); // 發送地址
IIC_Wait_ACK(); // 等待數據響應
GET_DATA = IIC_ReadByte(); // 獲取數據
IIC_Wait_ACK(); // 等待數據響應
IIC_Stop(); // 停止
return GET_DATA;
}
/*********************************************
函數名:PAJ7620U2_get_data
功 能:讀取一次寄存器值
形 參:
返回值:
備 注:
作 者:薛建強
時 間:2019/06/11
**********************************************/
uint16_t PAJ7620U2_get_data(const uint8_t addr)
{
uint8_t i = 0;
xdata uint8_t GET_DATA[2] = {0};
IIC_Start(); // 啓動
IIC_WriteByte(PAJ7620U2.ADDR); // 發送地址
IIC_Wait_ACK(); // 等待數據響應
IIC_WriteByte(addr); // 發送地址
IIC_Wait_ACK(); // 等待數據響應
IIC_Start(); // 啓動
IIC_WriteByte(PAJ7620U2.ADDR | 1); // 發送地址
IIC_Wait_ACK(); // 等待數據響應
for (i = 0; i < 2; i++)
{
if (i == 1)
{
GET_DATA[i] = IIC_ReceiveData(0);
}
else
{
GET_DATA[i] = IIC_ReceiveData(1);
}
}
IIC_Stop(); // 停止
return (uint16_t)((GET_DATA[1] << 8) | (GET_DATA[0])); //
}
/*********************************************
函數名:PAJ7620U2_CMD_WakeUp
功 能:PAJ7620喚醒
形 參:
返回值:
備 注:①喚醒命令格式就是I2C通訊的命令格式,在發送寫命令後不用等待PAJ7629U2的應答,直接發送停止就可以了。
②發送完喚醒命令後,需等待大於700us的時間,然後讀取PAJ7620U2的0X00寄存器,判斷是否爲0X20數值,若不是則繼續執行步驟1繼續喚醒。
直到讀取0X00寄存器值爲0X20,則喚醒成功。
作 者:薛建強
時 間:2020/03/19
使 用:
**********************************************/
void PAJ7620U2_CMD_WakeUp(void)
{
IIC_Start(); // 啓動
IIC_WriteByte(PAJ7620U2.ADDR); // 發送地址
IIC_Stop(); // 停止
}
/*********************************************
函數名:PAJ7620U2_SelectBank
功 能:選擇PAJ7620U2 BANK區域
形 參:bank-->[0,1]
返回值:
備 注:
作 者:薛建強
時 間:2020/03/19
使 用:
**********************************************/
void PAJ7620U2_SelectBank(bank_e bank)
{
switch (bank)
{
case BANK0:
PAJ7620U2_Write_DATA(PAJ_REGITER_BANK_SEL, PAJ_BANK0);
break;//BANK0寄存器區域
case BANK1:
PAJ7620U2_Write_DATA(PAJ_REGITER_BANK_SEL, PAJ_BANK1);
break;//BANK1寄存器區域
}
}
/*********************************************
函數名:PAJ7620U2_wakeup
功 能:PAJ7620U2喚醒
形 參:
返回值:
備 注:連續喚醒兩次,防止一次不成功
作 者:薛建強
時 間:2020/03/19
使 用:
**********************************************/
uint8_t PAJ7620U2_wakeup(void)
{
uint8_t Data = 0x0a;
PAJ7620U2_CMD_WakeUp();//喚醒PAJ7620U2
os_wait(K_IVL, 5, 0);//5ms
PAJ7620U2_CMD_WakeUp();//喚醒PAJ7620U2
os_wait(K_IVL, 5, 0);//5ms
//return 0; //喚醒失敗
PAJ7620U2_SelectBank(BANK0);//進入BANK0寄存器區域
Data = PAJ7620U2_Read_DATA(0x00);//讀取狀態
if (Data != 0x20) return 0; //喚醒失敗
return 1;
}
/*********************************************
函數名:PAJ7620U2_Init
功 能:手勢傳感器初始化
形 參:
返回值:0--初始化失敗 1--初始化成功
備 注:
作 者:薛建強
時 間:2020/03/19
使 用:
**********************************************/
uint8_t PAJ7620U2_Init(void)
{
uint8_t i;
uint8_t status;
IIC_Init(); // I2C初始化
status = PAJ7620U2_wakeup();//喚醒PAJ7620U2
if (!status) return 0;
PAJ7620U2_SelectBank(BANK0);//進入BANK0寄存器區域
for (i = 0; i < INIT_SIZE; i++)
{
PAJ7620U2_Write_DATA(init_Array[i][0], init_Array[i][1]); //初始化PAJ7620U2
}
PAJ7620U2_SelectBank(BANK0);//切換回BANK0寄存器區域
return 1;
}
/*********************************************
函數名:PAJ7620U2_Set_Gesture_Mode
功 能:設置爲手勢模式
形 參:
返回值:
備 注:
作 者:薛建強
時 間:2020/03/19
使 用:
**********************************************/
void PAJ7620U2_Set_Gesture_Mode(void)
{
uint8_t i;
PAJ7620U2_SelectBank(BANK0);//進入BANK0寄存器區域
for (i = 0; i < GESTURE_SIZE; i++)
{
PAJ7620U2_Write_DATA(gesture_arry[i][0], gesture_arry[i][1]); //手勢識別模式初始化
}
PAJ7620U2_SelectBank(BANK0);//切換回BANK0寄存器區域
}
uint8_t PAJ7620U2_Read_Gesture_State(void)
{
switch (PAJ7620U2_get_data(PAJ_GET_INT_FLAG1))
{
case GES_UP://向上
return 1;
case GES_DOWM://向下
return 2;
case GES_LEFT://向左
return 3;
case GES_RIGHT://向右
return 4;
case GES_FORWARD://向前
return 5;
case GES_BACKWARD: //向後
return 6;
case GES_CLOCKWISE://順時針
return 7;
case GES_COUNT_CLOCKWISE://逆時針
return 8;
case GES_WAVE://揮動
return 9;
default:
return 0;
}
}
#ifndef _PAJ7620U2_H
#define _PAJ7620U2_H
/* -----------------------------------------宏定義-----------------------------------------*/
#define PAJ_REGITER_BANK_SEL 0XEF //BANK選擇寄存器
#define PAJ_BANK0 0X00 //BANK0
#define PAJ_BANK1 0X01 //BANK1
//BANK0 寄存器組
#define PAJ_SUSPEND_CMD 0X03 //設置設備掛起
#define PAJ_SET_INT_FLAG1 0X41 //設置手勢檢測中斷寄存器1
#define PAJ_SET_INT_FLAG2 0X42 //設置手勢檢測中斷寄存器2
#define PAJ_GET_INT_FLAG1 0X43 //獲取手勢檢測中斷標誌寄存器1(獲取手勢結果)
#define PAJ_GET_INT_FLAG2 0X44 //獲取手勢檢測中斷標誌寄存器2(獲取手勢結果)
#define PAJ_GET_STATE 0X45 //獲取手勢檢測工作狀態
#define PAJ_SET_HIGH_THRESHOLD 0x69 //設置滯後高閥值(僅在接近檢測模式下)
#define PAJ_SET_LOW_THRESEHOLD 0X6A //設置滯後低閥值
#define PAJ_GET_APPROACH_STATE 0X6B //獲取接近狀態 (1:PS data>= PS threshold ,0:PS data<= Low threshold)
#define PAJ_GET_GESTURE_DATA 0X6C //獲取接近數據
#define PAJ_GET_OBJECT_BRIGHTNESS 0XB0 //獲取被照物體亮度(最大255)
#define PAJ_GET_OBJECT_SIZE_1 0XB1 //獲取被照物體大小低八位(bit7:0)(最大900)
#define PAJ_GET_OBJECT_SIZE_2 0XB2 //獲取被照物體大小高四位(bit3:0)
//BANK1 寄存器組
#define PAJ_SET_PS_GAIN 0X44 //設置檢測增益大小 (0:1x gain 1:2x gain)
#define PAJ_SET_IDLE_S1_STEP_0 0x67 //設置S1的響應因子
#define PAJ_SET_IDLE_S1_STEP_1 0x68
#define PAJ_SET_IDLE_S2_STEP_0 0X69 //設置S2的響應因子
#define PAJ_SET_IDLE_S2_STEP_1 0X6A
#define PAJ_SET_OP_TO_S1_STEP_0 0X6B //設置OP到S1的過度時間
#define PAJ_SET_OP_TO_S1_STEP_1 0X6C
#define PAJ_SET_S1_TO_S2_STEP_0 0X6D //設置S1到S2的過度時間
#define PAJ_SET_S1_TO_S2_STEP_1 0X6E
#define PAJ_OPERATION_ENABLE 0X72 //設置PAJ7620U2使能寄存器
//手勢識別效果
#define BIT(x) 1<<(x)
#define GES_UP BIT(0) //向上
#define GES_DOWM BIT(1) //向下
#define GES_LEFT BIT(2) //向左
#define GES_RIGHT BIT(3) //向右
#define GES_FORWARD BIT(4) //向前
#define GES_BACKWARD BIT(5) //向後
#define GES_CLOCKWISE BIT(6) //順時針
#define GES_COUNT_CLOCKWISE BIT(7) //逆時針
#define GES_WAVE BIT(8) //揮動
/* -----------------------------------------頭文件-----------------------------------------*/
#include "main.h"
/* -----------------------------------------結構體定義-------------------------------------*/
/* -----------------------------------------全局變量定義-----------------------------------*/
//BANK寄存器枚舉
typedef enum{
BANK0 = 0, //BANK0寄存器
BANK1, //BANK1寄存器
}bank_e;
/* -----------------------------------------應用程序---------------------------------------*/
uint8_t PAJ7620U2_Init(void);
uint8_t PAJ7620U2_Read_Gesture_State(void);
void PAJ7620U2_Set_Gesture_Mode(void);
#endif
使用方法:
if (SystemReg.RunningState == 0 && SystemInit.PAJ7620U2 == 0)
{
SystemInit.PAJ7620U2 = PAJ7620U2_Init();
if (SystemInit.PAJ7620U2 == 1)
{
PAJ7620U2_Set_Gesture_Mode();
}
}
if (SystemReg.RunningState == 0 && SystemInit.PAJ7620U2 == 1)
{
State = PAJ7620U2_Read_Gesture_State(); //獲取手勢狀態
if (State != 0)
{
printf("State:%d\r\n", (uint16_t)State);
State = 0;
}
}