[STM32L5] 【STM32L562E-DK测评活动】by clever:04-硬件IIC读取手势模块

[复制链接]
1661|0
 楼主| 聪聪哥哥 发表于 2025-2-27 15:09 | 显示全部楼层 |阅读模式
本帖最后由 聪聪哥哥 于 2025-2-27 15:13 编辑

#申请原创# @21小跑堂 @21ic小管家 使用STM32L562的硬件IIC读取手势模块的数据,为后期制作小产品做一个准备;硬件准备:STM32L562开发板、MB1280B拓展板、手势模块及mic-USB线
一:STM32L526 硬件IIC的知识分享:
该设备嵌入四个12C。请参阅表17:12C实现以了解功能实现。
12C总线接口处理微控制器和串行12C总线之间的通信。它控制所有12C总线特定的序列、协议、仲裁和定时。
L2C外围设备支持:
12C总线规范和用户手册第5版兼容性:
奴隶和主人模式,多主人能力
标准模式(Sm),比特率最高可达100 kbit/s
快速模式(Fm),比特率可达400 kbit/s
快速模式加(Fm+),具有高达1Mbit/s的比特率和20 mA输出驱动I/0
7位和10位寻址模式,多个7位从机地址
可编程设置和保持时间
可选时钟拉伸
系统管理总线(SMBus)规范修订版2.0兼容性:
硬件PEC(分组错误检查)生成和验证,带有ACK控制
地址解析协议(ARP)支持
SMBus警报
电力系统管理协议(PMBUS)规范修订版 1.1兼容性独立时钟:可以选择独立的时钟源,使12C通信速度独立于PCLK重编程。参见图7:STM32L562xx时钟树
地址匹配时从停止模式唤醒
可编程模拟和数字噪声滤波器
具有 DMA功能的1字节缓冲区
1.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)
红外LED手势识别原理:传感器工作时通过内部 LED 驱动器,驱动红外 LED 向外发射红外线信号,当传感器阵列在有效的距离中探测到物体时,目标信息提取阵列会对探测目标进行特征原始数据的获取,采集到的数据被保存在寄存器中,同时手势识别阵列会对原始数据进行识别处理,最后将手势结果存到寄存器中。
根据 PAJ7620U2传感器数据手册,用户可通过I²C接口总线采集信号并迅速识别出UP、Down、Right、Left等9种常用手势。另外PAJ7620U2还提供内置的接近检测功能,用于检测物体的接近或离开。
实物图片如下所示:
2.png
三:硬件连接:
3.1 原理图查看:
3.png
1脚  GND   供电负极
2脚 VCC  供电正极 设计的是3V3
3脚 SDA  IIC的数据线   PB6    
4脚 SCL  IIC的时钟线      PB7 

3.2:STM32 cubeMX 软件配置如下所示:
4.png
这里i为了方便,我们使用默认的参数就可以,然后在生成的代码中,添加对手势模块的驱动程序就可以。
3.3 添加串口1的配置信息
本款开发板,已将串口1连接到调试器的串口上面,我们只需要使用引脚的PA9,PA10配置好,使用printf重映射就可以。直接把调试信息输出到串口就可以。
具体的配置过程,大家可以参考我之前写的帖子就可以,这里就不再重复介绍
https://bbs.21ic.com/icview-3434762-1-1.html
四:手势模块的主要代码如下所示:
  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.         if (HAL_I2C_Master_Transmit(&hi2c1, PAJ7620_I2C_ADDR, &data, 1, 100) != HAL_OK)
  11.         {
  12.                 return 0;
  13.         }
  14.         return 1;        
  15. }
  16. /**************************************************************************************************
  17.   * 函数功能: static unsigned char PAJ7620_send_byteS(unsigned char *data, unsigned char length)
  18.   * 输入参数: data  length
  19.   * 返 回 值: 1:正常 0:异常
  20.   * 说    明: 通过IIC向模块发送 长度为length 的数据
  21.   *
  22. ***************************************************************************************************/
  23. static unsigned char PAJ7620_send_byteS(unsigned char *data, unsigned char length)
  24. {
  25.         if (HAL_I2C_Master_Transmit(&hi2c1, PAJ7620_I2C_ADDR, data, length, 100) != HAL_OK)
  26.         {
  27.                 return 0;
  28.         }
  29.         return 1;
  30. }
  31. /**************************************************************************************************
  32.   * 函数功能: static unsigned char PAJ7620_read_byteS(unsigned char *data, unsigned char length)
  33.   * 输入参数: data  length
  34.   * 返 回 值: 1:正常 0:异常
  35.         * 说    明: 通过IIC向模块读取 长度为length 的数据
  36.   *
  37. ***************************************************************************************************/
  38. static unsigned char PAJ7620_read_byteS(unsigned char *data, unsigned char length)
  39. {
  40.         /* Do the read */
  41.         if (HAL_I2C_Master_Receive(&hi2c1, PAJ7620_I2C_ADDR, data, length, 100) != HAL_OK)
  42.         {
  43.                 return 0;
  44.         }
  45.         return 1;
  46. }
  47. /**************************************************************************************************
  48.   * 函数功能: static void writeReg(uint8_t addr, uint8_t value)
  49.   * 输入参数: addr  value
  50.   * 返 回 值: 无
  51.         * 说    明: 通过 IIC 向模块的指定寄存器写入数据
  52.   *
  53. ***************************************************************************************************/
  54. static void writeReg(uint8_t addr, uint8_t value)
  55. {
  56.         unsigned char dta[2] = {0};
  57.         dta[0] = addr;
  58.         dta[1] = value;
  59.         PAJ7620_send_byteS(dta, 2);
  60. }
  61. /**************************************************************************************************
  62.   * 函数功能: static unsigned char readRegs(uint8_t addr, uint8_t *values, int size)
  63.   * 输入参数: addr  values  size
  64.   * 返 回 值: 无
  65.         * 说    明: 通过 IIC 向模块的读取 指定寄存器及其该寄存器的之后的数据长度
  66.   *
  67. ***************************************************************************************************/
  68. static unsigned char readRegs(uint8_t addr, uint8_t *values, int size)
  69. {
  70.         if (PAJ7620_send_byte(addr) != 1)
  71.                 return 0;
  72.         if (PAJ7620_read_byteS(values, size) != 1)
  73.                 return 0;
  74.         return 1;
  75. }
  76. /**************************************************************************************************
  77.   * 函数功能: static unsigned char readReg(uint8_t addr)
  78.   * 输入参数: addr  
  79.   * 返 回 值: 无
  80.         * 说    明: 通过 IIC 向模块的读取 指定寄存器的数据
  81.   *
  82. ***************************************************************************************************/
  83. static unsigned char readReg(uint8_t addr)
  84. {
  85.         uint8_t values;
  86.         readRegs(addr, &values, 1);
  87.         return values;
  88. }
  89. /**************************************************************************************************
  90.   * 函数功能: void paj7620u2_selectBank(bank_e bank)
  91.   * 输入参数: bank  
  92.   * 返 回 值: 无
  93.         * 说    明: 通过 IIC 向模块的读取 指定寄存器的数据
  94.   *
  95. ***************************************************************************************************/
  96. void paj7620u2_selectBank(bank_e bank)
  97. {
  98.         switch (bank)
  99.         {
  100.         case BANK0:
  101.                 writeReg(PAJ_REGITER_BANK_SEL, PAJ_BANK0);
  102.                 break; // BANK0
  103.         case BANK1:
  104.                 writeReg(PAJ_REGITER_BANK_SEL, PAJ_BANK1);
  105.                 break; // BANK1
  106.         }
  107. }
  108. void GS_WakeUp()
  109. {
  110.         PAJ7620_send_byte(0);
  111. }
  112. /**************************************************************************************************
  113.   * 函数功能: unsigned char paj7620u2_wakeup()
  114.   * 输入参数: bank  
  115.   * 返 回 值: 无
  116.         * 说    明: 唤醒手势模块
  117.   *
  118. ***************************************************************************************************/
  119. unsigned char paj7620u2_wakeup()
  120. {
  121.         unsigned char data1 = 0x0a;
  122.         unsigned char data2 = 0x0a;
  123.         GS_WakeUp();                                 // wake PAJ7620U2
  124.         HAL_Delay(5);                                 // wake time >400us
  125.         GS_WakeUp();                                 // wake PAJ7620U2
  126.         HAL_Delay(5);                                 // wake time>400us
  127.         paj7620u2_selectBank(BANK0); //进入BANK0
  128.         /* check ID */
  129.         data1 = readReg(0x00); //读取id
  130.         data2 = readReg(0x01); //读取id
  131.         if ((data2 != 0x76) || (data1 != 0x20))
  132.                 return 0;
  133.         return 1;
  134. }
  135. /**************************************************************************************************
  136.   * 函数功能: unsigned char PAJ7620u2_init(void)
  137.   * 输入参数:   
  138.   * 返 回 值: 无
  139.         * 说    明: 模块初始化
  140.   *
  141. ***************************************************************************************************/
  142. unsigned char PAJ7620u2_init(void)
  143. {
  144.         unsigned char status;
  145.         HAL_Delay(10);
  146.         status = paj7620u2_wakeup(); //唤醒PAJ7620U2
  147.         if (!status)
  148.                 return 0;
  149.         paj7620u2_selectBank(BANK0); // enter BANK0
  150.         HAL_Delay(50);
  151.         /* Load the registers data */
  152.         for (uint8_t i = 0; i < INIT_REG_ARRAY_SIZE; i++)
  153.                 writeReg(initRegisterArray[i][0], initRegisterArray[i][1]); // init PAJ7620U2
  154.         paj7620u2_selectBank(BANK0);                                                                        // enter BANK0
  155.         return 1;
  156. }
  157. /**************************************************************************************************
  158.   * 函数功能: void Gesture_Init(void)
  159.   * 输入参数:   
  160.   * 返 回 值: 无
  161.         * 说    明: 模块初始化
  162.   *
  163. ***************************************************************************************************/
  164. void Gesture_Init(void)
  165. {
  166.         unsigned char i;
  167.         paj7620u2_selectBank(BANK0); //
  168.         for (i = 0; i < GESTURE_SIZE; i++)
  169.         {
  170.                 writeReg(gesture_arry[i][0], gesture_arry[i][1]);
  171.         }
  172.         paj7620u2_selectBank(BANK0); //
  173.         memset(&gesture, 0, sizeof(GestureData));
  174. }
  175. /**************************************************************************************************
  176.   * 函数功能: void Gesture_Init(void)
  177.   * 输入参数:   
  178.   * 返 回 值: 无
  179.         * 说    明: 模块初始化
  180.   *
  181. ***************************************************************************************************/
  182. void PAJ7620_Init(void)
  183. {
  184.         while (!PAJ7620u2_init()) // PAJ7620U2初始化
  185.         {
  186.                 printf("PAJ7620U2_B Error!!!\r\n");
  187.                 HAL_Delay(500);
  188.         }
  189.         HAL_Delay(1000);
  190.         printf("PAJ7620U2 OK\r\n"); //
  191. }
  192. unsigned char PAJ7620_Read_nByte(unsigned char addr, unsigned short len, unsigned char *buf)
  193. {

  194.         return readRegs(addr, &buf[0], len);
  195. }
  196. /**************************************************************************************************
  197.   * 函数功能: unsigned char GetCurrentGesture(void)
  198.   * 输入参数:   
  199.   * 返 回 值: 无
  200.         * 说    明: 读取模块的手势地址
  201.   *
  202. ***************************************************************************************************/
  203. unsigned char GetCurrentGesture(void)
  204. {        
  205.         uint8_t Data[2]={0,0};
  206.         uint16_t Gesture_Data;        
  207.         uint8_t state ;
  208.         uint8_t i ;        
  209. //        Gesture_Init();
  210. //        此处判断读取来当前手势不为0时,进行处理
  211.         state = PAJ7620_Read_nByte(PAJ_GET_INT_FLAG1, 2, &gesture.data[0]); //               

  212.         if(state != 0)
  213.         {
  214.                         Gesture_Data = (gesture.data[1]<<8) | gesture.data[0];
  215.                 switch(Gesture_Data)
  216.                 {
  217.                         
  218.                         case PAJ_UP:                                      printf("Up\r\n");            break;
  219.                         case PAJ_DOWN:                                printf("Down\r\n");        break;
  220.                         case PAJ_LEFT:                                   printf("Left\r\n");          break;
  221.                         case PAJ_RIGHT:                                 printf("Right\r\n");        break;
  222.                         case PAJ_FORWARD:                           printf("Forward\r\n");     break;
  223.                         case PAJ_BACKWARD:                         printf("Backward\r\n");    break;
  224.                         case PAJ_CLOCKWISE:                        printf("Clockwise\r\n");    break;
  225.                         case PAJ_COUNT_CLOCKWISE:            printf("AntiClockwise\r\n");break;
  226.                         case PAJ_WAVE:                                  printf("Wave\r\n");          break;                                               
  227.                         default: break;
  228.                 }
  229.                 Gesture_Data = 0;
  230.         }
  231.                 return 0;
  232. }
在主程序中,首先初始化模块信息,在主程序中,不停的调用模块当前状态就可以,如下所示:
  1.   /* USER CODE BEGIN 2 */
  2.         printf("autor  by congconggege\r\n");
  3.         HAL_Delay(1000);
  4.         printf("PAJ7620U2 Gesture Sensor Test Program ...\r\n");
  5.         PAJ7620_Init();
  6.         printf("PAJ7620U2 Gesture Sensor OK \r\n");
  7. //        CorMark_main();
  8.   /* USER CODE END 2 */
  9.   /* Infinite loop */
  10.   /* USER CODE BEGIN WHILE */
  11.   while (1)
  12.   {
  13.     /* USER CODE END WHILE */
  14.     /* USER CODE BEGIN 3 */
  15.     HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_12);
  16.     HAL_Delay(500);
  17.     GetCurrentGesture();//
  18.   }
五:实物测试图片和PC截图如下所示:
5.png
微信图片_20250227150739.png
如图所示:在模块前做不同指令,串口接收窗口,显示当前的模块信息了。
至此,硬件IIC读取手势模块,调试完毕。


您需要登录后才可以回帖 登录 | 注册

本版积分规则

108

主题

309

帖子

1

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