本帖最后由 聪聪哥哥 于 2025-9-30 13:56 编辑
一:CH32 IIC知识分享:
内部集成电路总线(12C)广泛用在微控制器和传感器及其他片外模块的通讯上,它本身支持多主多从模式,仅仅使用两根线(SDA 和 SCL)就能以 100kHz(标准)和 400kHz(快速)两种速度通讯。12C 总线还兼容 SMBus 协议,不仅支持 12C 的时序,还支持仲裁、定时和 DMA,拥有 CRC 校验功能。
二:主要特征:
支持主模式和从模式
支持 7 位或 10 位地址
从设备支持双7位地址
支持两种速度模式:100kHz 和 400kHz多种状态模式,多种错误标志
支持加长的时钟功能
2 个中断向量
支持 DMA
支持 PEC
兼容 SMBus
12C 是半双工的总线,它同时只能运行在下列四种模式中之一:主设备发送模式、主设备接收模式、从设备发送模式和从设备接收模式。120 模块默认工作在从模式,在产生起始条件后,会自动地切换到主模式,当仲裁丢失或产生停止信号后,会切换到从模式。120模块支持多主机功能。工作在主模式时,120 模块会主动发出数据和地址。数据和地址都以8位为单位进行传输,高位在前,低位在后,在起始事件后的是一个字节(7 位地址模式下)或两个字节(10 位地址模式下)地址,主机每发送8位数据或地址,从机需要回复一个应答 ACK,即把 SDA 总线拉低,如图 下所示。
三:手势模块知识分享:
PAJ7620U2 Gesture Sensor是一款基于PAJ7620U2的手势识别模块,可直接识别9种基本手势,支持I2C接口,兼容3.3V/5V电平。这里为了方式调试,我使用的是STM32硬件的IIC驱动代码,也加深了自己对IIC通讯的理解;
模块资料:
电源电压 : 3.3V/5V
工作原理:光学数组式环境亮度传感检测
通讯接口:I²C 接口,400Khz(Max)
识别速度:240Hz
工作环境光:<100K Lux(抗灯光干扰)
有效探测距离:5~15cm
检测角度范围:60°~180°
手势识别种类:内置 9 个手势类型:(上、下、左、右、前、后、顺时针旋转、逆时针旋转、挥动)
功耗:3~10mA(待机功耗电流 15u)
PAJ7620U2传感器的工作原理
我们可以看到PAJ7620U2传感器内部自带 LED 驱动器(可发射红外线信号),内置有传感器感应阵列、目标信息提取阵列和手势识别阵列。另外,PAJ7620U2作为一种光学数组式传感器,其内置LED驱动器集成了环境光和光源抑制滤波器,模块基本不受环境光干扰。
红外LED手势识别原理:传感器工作时通过内部 LED 驱动器,驱动红外 LED 向外发射红外线信号,当传感器阵列在有效的距离中探测到物体时,目标信息提取阵列会对探测目标进行特征原始数据的获取,采集到的数据被保存在寄存器中,同时手势识别阵列会对原始数据进行识别处理,最后将手势结果存到寄存器中。
根据 PAJ7620U2传感器数据手册,用户可通过I²C接口总线采集信号并迅速识别出UP、Down、Right、Left等9种常用手势。另外PAJ7620U2还提供内置的接近检测功能,用于检测物体的接近或离开。
四:软件代码:
4.1 主要在官方的代码中进行移植:移植底层的 驱动函数:
- /**************************************************************************************************
- * 函数功能: static unsigned char PAJ7620_send_byte(unsigned char dta)
- * 输入参数: data
- * 返 回 值: 1:正常 0:异常
- * 说 明: 通过IIC向模块发送一个字节
- *
- ***************************************************************************************************/
- static unsigned char PAJ7620_send_byte(unsigned char data)
- {
- AT24CXX_WriteOneByte(PAJ7620_I2C_ADDR,data);
- return 1;
- ;
- }
- /**************************************************************************************************
- * 函数功能: static unsigned char PAJ7620_send_byteS(unsigned char *data, unsigned char length)
- * 输入参数: data length
- * 返 回 值: 1:正常 0:异常
- * 说 明: 通过IIC向模块发送 长度为length 的数据
- *
- ***************************************************************************************************/
- static unsigned char PAJ7620_send_byteS(unsigned char *data, unsigned char length)
- {
- AT24CXX_Write( PAJ7620_I2C_ADDR, data, length) ;
- return 1;
- }
- /**************************************************************************************************
- * 函数功能: static unsigned char PAJ7620_read_byteS(unsigned char *data, unsigned char length)
- * 输入参数: data length
- * 返 回 值: 1:正常 0:异常
- * 说 明: 通过IIC向模块读取 长度为length 的数据
- *
- ***************************************************************************************************/
- static unsigned char PAJ7620_read_byteS(unsigned char *data, unsigned char length)
- {
- /* Do the read */
- AT24CXX_Read(PAJ7620_I2C_ADDR ,data ,length);
- return 1;
- }
- /**************************************************************************************************
- * 函数功能: static void writeReg(uint8_t addr, uint8_t value)
- * 输入参数: addr value
- * 返 回 值: 无
- * 说 明: 通过 IIC 向模块的指定寄存器写入数据
- *
- ***************************************************************************************************/
- static void writeReg(uint8_t addr, uint8_t value)
- {
- unsigned char dta[2] = {0};
- dta[0] = addr;
- dta[1] = value;
- PAJ7620_send_byteS(dta, 2);
- }
- /**************************************************************************************************
- * 函数功能: static unsigned char readRegs(uint8_t addr, uint8_t *values, int size)
- * 输入参数: addr values size
- * 返 回 值: 无
- * 说 明: 通过 IIC 向模块的读取 指定寄存器及其该寄存器的之后的数据长度
- *
- ***************************************************************************************************/
- static unsigned char readRegs(uint8_t addr, uint8_t *values, int size)
- {
- if (PAJ7620_send_byte(addr) != 1)
- return 0;
- if (PAJ7620_read_byteS(values, size) != 1)
- return 0;
- return 1;
- }
- /**************************************************************************************************
- * 函数功能: static unsigned char readReg(uint8_t addr)
- * 输入参数: addr
- * 返 回 值: 无
- * 说 明: 通过 IIC 向模块的读取 指定寄存器的数据
- *
- ***************************************************************************************************/
- static unsigned char readReg(uint8_t addr)
- {
- uint8_t values;
- readRegs(addr, &values, 1);
- return values;
- }
4.2 添加读取模块的状态信息函数如下所示:
- /**************************************************************************************************
- * 函数功能: unsigned char GetCurrentGesture(void)
- * 输入参数:
- * 返 回 值: 无
- * 说 明: 读取模块的手势地址
- *
- ***************************************************************************************************/
- unsigned char GetCurrentGesture(void)
- {
- uint8_t Data[2]={0,0};
- uint16_t Gesture_Data;
- uint8_t state ;
- state = PAJ7620_Read_nByte(PAJ_GET_INT_FLAG1, 2, &gesture.data[0]); //
- if(state != 0)
- {
- Gesture_Data = (gesture.data[1]<<8) | gesture.data[0];
- switch(Gesture_Data)
- {
- case PAJ_UP: printf("Up\r\n"); break;
- case PAJ_DOWN: printf("Down\r\n"); break;
- case PAJ_LEFT: printf("Left\r\n"); break;
- case PAJ_RIGHT: printf("Right\r\n"); break;
- case PAJ_FORWARD: printf("Forward\r\n"); break;
- case PAJ_BACKWARD: printf("Backward\r\n"); break;
- case PAJ_CLOCKWISE: printf("Clockwise\r\n"); break;
- case PAJ_COUNT_CLOCKWISE: printf("AntiClockwise\r\n");break;
- case PAJ_WAVE: printf("Wave\r\n"); break;
- default: break;
- }
- Gesture_Data = 0;
- }
- return 0;
- }
五:实物图片如下所示:
在500ms的任务中,不间断的读取模块的状态信息就可以了。
|