【前言】
我的工程目的是使用手势传感器来实现无接触的控制,所以驱动PAJ7620U2为首要任务。在前面我已经 驱动好的oled屏的前提下,添加手势传感的驱动。
【I2C读写函数的封装】
因为有多个i2c的读写,所以在github上面找到了一个库,修改以后可以实现i2c的单、多数据的写入,多数据的读取。
其代码如下:
#include "i2c_app.h" #define I2CT_FLAG_TIMEOUT ((uint32_t)0x1000) #define I2CT_LONG_TIMEOUT ((uint32_t)(10 * I2CT_FLAG_TIMEOUT)) static __IO uint32_t I2CTimeout = I2CT_LONG_TIMEOUT; uint8_t i2c_app_write (I2C_Regs *i2c, uint8_t addr, uint8_t reg, uint8_t *dat, uint8_t len) { DL_I2C_fillControllerTXFIFO(i2c, ®, 1); DL_I2C_fillControllerTXFIFO(i2c, dat, len); I2CTimeout = I2CT_FLAG_TIMEOUT; while (!(DL_I2C_getControllerStatus(i2c) & DL_I2C_CONTROLLER_STATUS_IDLE)) if ((I2CTimeout--) == 0) return 1; DL_I2C_startControllerTransfer(i2c, addr, DL_I2C_CONTROLLER_DIRECTION_TX, len + 1); I2CTimeout = I2CT_FLAG_TIMEOUT; while (DL_I2C_getControllerStatus(i2c) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS) if ((I2CTimeout--) == 0) return 2; if (DL_I2C_getControllerStatus(i2c) & DL_I2C_CONTROLLER_STATUS_ERROR) return 1; I2CTimeout = I2CT_FLAG_TIMEOUT; while (!(DL_I2C_getControllerStatus(i2c) & DL_I2C_CONTROLLER_STATUS_IDLE)) if ((I2CTimeout--) == 0) return 3; return 0; } uint8_t i2c_app_read (I2C_Regs *i2c, uint8_t addr, uint8_t reg, uint8_t *dat, uint8_t len) { DL_I2C_fillControllerTXFIFO(i2c, ®, 1); I2CTimeout = I2CT_FLAG_TIMEOUT; while (!(DL_I2C_getControllerStatus(i2c) & DL_I2C_CONTROLLER_STATUS_IDLE)) if ((I2CTimeout--) == 0) return 1; DL_I2C_startControllerTransfer(i2c, addr, DL_I2C_CONTROLLER_DIRECTION_TX, 1); // DL_I2C_startControllerTransferAdvanced(i2c, addr, DL_I2C_CONTROLLER_DIRECTION_TX, 1, // I2C_MCTR_START_ENABLE, I2C_MCTR_STOP_DISABLE, I2C_MCTR_ACK_ENABLE); I2CTimeout = I2CT_FLAG_TIMEOUT; while (DL_I2C_getControllerStatus(i2c) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS) if ((I2CTimeout--) == 0) return 2; if (DL_I2C_getControllerStatus(i2c) & DL_I2C_CONTROLLER_STATUS_ERROR) { /* LED will remain high if there is an error */ __BKPT(0); } /* Wait for I2C to be Idle */ while (!( DL_I2C_getControllerStatus(i2c) & DL_I2C_CONTROLLER_STATUS_IDLE)) ; /* Add delay between transfers */ delay_cycles(1000); DL_I2C_startControllerTransfer(i2c, addr, DL_I2C_CONTROLLER_DIRECTION_RX, len); for (uint8_t i = 0; i < len; i++) { I2CTimeout = I2CT_FLAG_TIMEOUT; while (DL_I2C_isControllerRXFIFOEmpty(i2c)) if ((I2CTimeout--) == 0) return 3; dat[i] = DL_I2C_receiveControllerData(i2c); } return 0; }
i2capp.h如下:
#ifndef I2C_APP_H #define I2C_APP_H #include "ti_msp_dl_config.h" uint8_t i2c_app_read (I2C_Regs *i2c, uint8_t addr, uint8_t reg, uint8_t *dat, uint8_t len); uint8_t i2c_app_write (I2C_Regs *i2c, uint8_t addr, uint8_t reg, uint8_t *dat, uint8_t len); #endif
封装好后,只需要传感i2c序号,写入从机的地址(为7bit地址),buf的地址,以及buf的长度。
将其加入到工程之中:
【PAJ7620驱动】
根据i2c的驱动封装,我这里只需要修改PAJ7620如下几个函数的代码,即可以完成:
/****************************************************************************** function: I2C Write and Read ******************************************************************************/ static void DEV_I2C_WriteByte(I2C_Regs * PAJ7620U2_I2C,uint8_t add_, uint8_t data_) { uint8_t Buf[1] = {0}; Buf[0] = data_; i2c_app_write(I2C1, 0x73, add_,Buf, 2); } static void DEV_I2C_WriteWord(I2C_Regs * PAJ7620U2_I2C,uint8_t add_, uint16_t data_) { uint8_t Buf[2] = {0}; Buf[0] = data_ >> 8; Buf[1] = data_; i2c_app_write(I2C1, 0x73, add_,Buf, 2); } static uint8_t DEV_I2C_ReadByte(I2C_Regs * PAJ7620U2_I2C,uint8_t add_) { uint8_t state; uint8_t Buf[1]; Buf[0] = add_; state = i2c_app_read(I2C1, 0x73, add_,Buf, 1); if(state == 0) { return Buf[0]; } else return state; } static uint16_t DEV_I2C_ReadWord(I2C_Regs * PAJ7620U2_I2C,uint8_t add_) { uint8_t Buf[2]={0, 0}; i2c_app_read(I2C1, 0x73, add_,Buf, 2); return ((Buf[1] << 8) | (Buf[0] & 0xff)); }
这样就可以成功的驱动他了,接上逻辑分析仪,捕获到数据为读写正常的:
在主程序中添加测试代码:
#include "ti_msp_dl_config.h" #include "\drivers\PAJ7620U2.h" #include "\oled\oled.h" int main(void) { SYSCFG_DL_init(); /* Set LED to indicate start of transfer */ OLED_Init(); OLED_Clear(); OLED_ShowString(0,0,"hello world",16,1); OLED_Refresh_Gram(); uint8_t OBJ_BRIGHTNESS = 0; // Object Brightness (Max. 255) uint16_t OBJ_SIZE = 0; // Object Size (Max. 900) uint16_t ID = PAJ7620U2_init(I2C1); /* If write and read were successful, toggle LED */ while (1) { delay_cycles(1000); OLED_Clear(); OBJ_BRIGHTNESS = PAJ7620U2_PS_ReadObjBrightness(I2C1); // Object Brightness (Max. 255) OBJ_SIZE = PAJ7620U2_PS_ReadObjSize(I2C1); // Object Size (Max. 900) OLED_Printf(0,0,16,1,"BRIGHT:%d",OBJ_BRIGHTNESS); OLED_Printf(0,24,16,1,"OBJ_SIZE:%d",OBJ_SIZE); OLED_Refresh_Gram(); } }
下载程序后,未测检到手势时的数值:
手靠近到传感器的数据:
到此说明手势传感器驱动正常。