[单片机芯片] 【CH32F207VCT6】开发例程+12使用官方的硬件IIC读取手势模块状态

[复制链接]
543|0
聪聪哥哥 发表于 2025-9-30 13:54 | 显示全部楼层 |阅读模式
开发, , ,
本帖最后由 聪聪哥哥 于 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 总线拉低,如图 下所示。
12-1.png
12-2.png
三:手势模块知识分享:
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 主要在官方的代码中进行移植:移植底层的 驱动函数:
  1. /**************************************************************************************************
  2.   * 函数功能: static unsigned char PAJ7620_send_byte(unsigned char dta)
  3.   * 输入参数: data
  4.   * 返 回 值: 1:正常 0:异常
  5.   * 说    明: 通过IIC向模块发送一个字节
  6.   *
  7. ***************************************************************************************************/
  8. static unsigned char PAJ7620_send_byte(unsigned char data)
  9. {
  10.         AT24CXX_WriteOneByte(PAJ7620_I2C_ADDR,data);
  11.         return 1;
  12.         ;
  13. }
  14. /**************************************************************************************************
  15.   * 函数功能: static unsigned char PAJ7620_send_byteS(unsigned char *data, unsigned char length)
  16.   * 输入参数: data  length
  17.   * 返 回 值: 1:正常 0:异常
  18.         * 说    明: 通过IIC向模块发送 长度为length 的数据
  19.   *
  20. ***************************************************************************************************/
  21. static unsigned char PAJ7620_send_byteS(unsigned char *data, unsigned char length)
  22. {
  23.   AT24CXX_Write( PAJ7620_I2C_ADDR, data, length) ;
  24.         return 1;
  25. }
  26. /**************************************************************************************************
  27.   * 函数功能: static unsigned char PAJ7620_read_byteS(unsigned char *data, unsigned char length)
  28.   * 输入参数: data  length
  29.   * 返 回 值: 1:正常 0:异常
  30.         * 说    明: 通过IIC向模块读取 长度为length 的数据
  31.   *
  32. ***************************************************************************************************/
  33. static unsigned char PAJ7620_read_byteS(unsigned char *data, unsigned char length)
  34. {

  35.         /* Do the read */
  36.         AT24CXX_Read(PAJ7620_I2C_ADDR ,data ,length);
  37.         return 1;
  38. }

  39. /**************************************************************************************************
  40.   * 函数功能: static void writeReg(uint8_t addr, uint8_t value)
  41.   * 输入参数: addr  value
  42.   * 返 回 值: 无
  43.         * 说    明: 通过 IIC 向模块的指定寄存器写入数据
  44.   *
  45. ***************************************************************************************************/
  46. static void writeReg(uint8_t addr, uint8_t value)
  47. {
  48.         unsigned char dta[2] = {0};
  49.         dta[0] = addr;
  50.         dta[1] = value;
  51.         PAJ7620_send_byteS(dta, 2);
  52. }

  53. /**************************************************************************************************
  54.   * 函数功能: static unsigned char readRegs(uint8_t addr, uint8_t *values, int size)
  55.   * 输入参数: addr  values  size
  56.   * 返 回 值: 无
  57.         * 说    明: 通过 IIC 向模块的读取 指定寄存器及其该寄存器的之后的数据长度
  58.   *
  59. ***************************************************************************************************/
  60. static unsigned char readRegs(uint8_t addr, uint8_t *values, int size)
  61. {
  62.         if (PAJ7620_send_byte(addr) != 1)
  63.                 return 0;
  64.         if (PAJ7620_read_byteS(values, size) != 1)
  65.                 return 0;
  66.         return 1;
  67. }
  68. /**************************************************************************************************
  69.   * 函数功能: static unsigned char readReg(uint8_t addr)
  70.   * 输入参数: addr  
  71.   * 返 回 值: 无
  72.         * 说    明: 通过 IIC 向模块的读取 指定寄存器的数据
  73.   *
  74. ***************************************************************************************************/
  75. static unsigned char readReg(uint8_t addr)
  76. {
  77.         uint8_t values;
  78.         readRegs(addr, &values, 1);
  79.         return values;
  80. }
4.2 添加读取模块的状态信息函数如下所示:
  1. /**************************************************************************************************
  2.   * 函数功能: unsigned char GetCurrentGesture(void)
  3.   * 输入参数:   
  4.   * 返 回 值: 无
  5.         * 说    明: 读取模块的手势地址
  6.   *
  7. ***************************************************************************************************/
  8. unsigned char GetCurrentGesture(void)
  9. {        
  10.         uint8_t Data[2]={0,0};
  11.         uint16_t Gesture_Data;
  12.         uint8_t state ;
  13.         state = PAJ7620_Read_nByte(PAJ_GET_INT_FLAG1, 2, &gesture.data[0]); //               
  14.         if(state != 0)
  15.         {
  16.                         Gesture_Data = (gesture.data[1]<<8) | gesture.data[0];
  17.                 switch(Gesture_Data)
  18.                 {                        
  19.                         case PAJ_UP:                                                                printf("Up\r\n");                                          break;
  20.                         case PAJ_DOWN:                                                        printf("Down\r\n");                                        break;
  21.                         case PAJ_LEFT:                                                        printf("Left\r\n");                                        break;
  22.                         case PAJ_RIGHT:                                                        printf("Right\r\n");        break;
  23.                         case PAJ_FORWARD:                                                printf("Forward\r\n");                        break;
  24.                         case PAJ_BACKWARD:                                        printf("Backward\r\n");                        break;
  25.                         case PAJ_CLOCKWISE:                                        printf("Clockwise\r\n");                break;
  26.                         case PAJ_COUNT_CLOCKWISE:                printf("AntiClockwise\r\n");break;
  27.                         case PAJ_WAVE:                                                        printf("Wave\r\n");                                  break;                                                
  28.                         default: break;
  29.                 }
  30.                 Gesture_Data = 0;
  31.         }
  32.                 return 0;
  33. }
五:实物图片如下所示:
12-3.png
12-4.png
在500ms的任务中,不间断的读取模块的状态信息就可以了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

108

主题

307

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部