陀螺仪LSM6DSV80X开发(5)----高G唤醒中断

描述

概述

本文演示如何在 LSM6DSV80X 的 High-G 加速度计上配置 冲击/唤醒(HG Wakeup)事件检测:设置 High-G 采样率与量程、配置滤波链路、设置唤醒阈值与持续时间,并把事件映射到 INT1 引脚输出中断。最后在主循环中读取事件标志位,判断触发轴向并通过串口打印。

最近在弄ST的课程,需要样片的可以加群申请:615061293 。

陀螺仪

视频教学

[https://www.bilibili.com/video/BV1SzwTzdE6L/]

样品申请

[https://www.wjx.top/vm/OhcKxJk.aspx#]

源码下载

[https://download.csdn.net/download/qq_24312945/92915752]

硬件准备

首先需要准备一个开发板,这里我准备的是自己绘制的开发板,需要的可以进行申请。

主控为STM32H503CB,陀螺仪为LSM6DSV80X,磁力计为LIS2MDL。

陀螺仪

参考程序

https://github.com/CoreMaker-lab/LSM6DSV80X

https://gitee.com/CoreMaker/LSM6DSV80X

FIFO存储

FIFO 可以存:
● Gyroscope(陀螺)
● Low-g accelerometer(低量程加速度)
● High-g accelerometer(高量程加速度)
● External sensors(最多 4 路外部传感器,走 sensor hub)
● Step counter(计步)
● Timestamp(时间戳)
● Temperature(温度)
● FSM events(FSM 事件)
● High-g peak value(高 G 峰值)
● MLC features/filters/results(MLC 特征/滤波/结果)

陀螺仪

生成STM32CUBEMX

用STM32CUBEMX生成例程,这里使用MCU为STM32H503CB。

配置时钟树,配置时钟为250M。

陀螺仪

串口配置

查看原理图,PA9和PA10设置为开发板的串口。

陀螺仪

配置串口,速率为2000000。

陀螺仪

IIC配置

陀螺仪

陀螺仪

LSM6DSV80X最大IIC通讯速率为1M,配置IIC速度为400k

陀螺仪

CS和SA0设置

陀螺仪

陀螺仪

陀螺仪

由于还有一个磁力计,需要把该CS也使能。

陀螺仪

陀螺仪

陀螺仪

INT配置

INT1管脚为PB1。

陀螺仪

陀螺仪

配置如下所示。

陀螺仪

开启中断。

陀螺仪

ICASHE

陀螺仪

修改堆栈

陀螺仪

串口重定向

打开魔术棒,勾选MicroLIB

陀螺仪

在main.c中,添加头文件,若不添加会出现 identifier "FILE" is undefined报错。

/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */

函数声明和串口重定向:

/* USER CODE BEGIN PFP */
int fputc(int ch, FILE *f){
    HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
    return ch;
}
/* USER CODE END PFP */

参考程序

https://github.com/STMicroelectronics/lsm6dsv80x-pid

初始换管脚

由于需要向LSM6DSV80X_I2C_ADD_L写入以及为IIC模式。

陀螺仪

所以使能CS为高电平,配置为IIC模式。 配置SA0为低电平。

printf("HELLO!n");
  HAL_GPIO_WritePin(CS1_GPIO_Port, CS1_Pin, GPIO_PIN_SET);
  HAL_GPIO_WritePin(SA0_GPIO_Port, SA0_Pin, GPIO_PIN_RESET);
  HAL_GPIO_WritePin(CS2_GPIO_Port, CS2_Pin, GPIO_PIN_SET);
    HAL_Delay(100);

  lsm6dsv80x_pin_int_route_hg_t pin_int = { 0 };
  lsm6dsv80x_hg_wake_up_cfg_t wu_cfg = { 0 };
  lsm6dsv80x_hg_wu_interrupt_cfg_t int_cfg = { 0 };

  /* Initialize mems driver interface */
  dev_ctx.write_reg = platform_write;
  dev_ctx.read_reg = platform_read;
  dev_ctx.mdelay = platform_delay;
  dev_ctx.handle = &SENSOR_BUS;

  /* Init test platform */
//  platform_init();

  /* Wait sensor boot time */
  platform_delay(BOOT_TIME);

获取ID

可以向WHO_AM_I (0Fh)获取固定值,判断是否为0x73。

陀螺仪

lsm6dsv80x_device_id_get为获取函数。

陀螺仪

对应的获取ID驱动程序,如下所示。

/* Check device ID */
  lsm6dsv80x_device_id_get(&dev_ctx, &whoamI);
    printf("LSM6DSV80X_ID=0x%x,whoamI=0x%x",LSM6DSV80X_ID,whoamI);
  if (whoamI != LSM6DSV80X_ID)
    while (1);

软件上电复位

写 0x01(FUNC_CFG_ACCESS)这个寄存器,把 SW_POR 置 1,然后等待芯片完成复位。
陀螺仪

lsm6dsv80x_sw_por为 软件上电复位 / 全局复位 函数。

陀螺仪

对应的驱动程序,如下所示。

/* Perform device power-on-reset */
  lsm6dsv80x_sw_por(&dev_ctx);

BDU设置

在很多传感器中,数据通常被存储在输出寄存器中,这些寄存器分为两部分:MSB和LSB。这两部分共同表示一个完整的数据值。例如,在一个加速度计中,MSB和LSB可能共同表示一个加速度的测量值。 连续更新模式(BDU = '0'):在默认模式下,输出寄存器的值会持续不断地被更新。这意味着在你读取MSB和LSB的时候,寄存器中的数据可能会因为新的测量数据而更新。这可能导致一个问题:当你读取MSB时,如果寄存器更新了,接下来读取的LSB可能就是新的测量值的一部分,而不是与MSB相对应的值。这样,你得到的就是一个“拼凑”的数据,它可能无法准确代表任何实际的测量时刻。 块数据更新(BDU)模式(BDU = '1'):当激活BDU功能时,输出寄存器中的内容不会在读取MSB和LSB之间更新。这就意味着一旦开始读取数据(无论是先读MSB还是LSB),寄存器中的那一组数据就被“锁定”,直到两部分都被读取完毕。这样可以确保你读取的MSB和LSB是同一测量时刻的数据,避免了读取到代表不同采样时刻的数据。 简而言之,BDU位的作用是确保在读取数据时,输出寄存器的内容保持稳定,从而避免读取到拼凑或错误的数据。这对于需要高精度和稳定性的应用尤为重要。 可以向CTRL3 (12h)的BDU寄存器写入1进行开启。

陀螺仪

对应的驱动程序,如下所示。

/* Enable Block Data Update */
  lsm6dsv80x_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);

设置高量程加速度速率

高量程加速度速率可以通过CTRL1_XL_HG (4Eh)设置高量程加速度速率。

陀螺仪

设置高量程加速度速率可以使用如下函数。

/* Set Output Data Rate.
   * Selected data rate have to be equal or greater with respect
   * with MLC data rate.
   */
  lsm6dsv80x_hg_xl_data_rate_set(&dev_ctx, LSM6DSV80X_HG_XL_ODR_AT_960Hz, 1);

设置高量程加速度量程

高量程加速度量程可以通过CTRL1_XL_HG (4Eh)设置。

陀螺仪

设置高量程加速度量程可以使用如下函数。

/* Set full scale */
  lsm6dsv80x_hg_xl_full_scale_set(&dev_ctx, LSM6DSV80X_80g);

需要注意的是高量程加速度的精度问题。

陀螺仪

数字滤波链

/* Configure filtering chain */
  filt_settling_mask.drdy = PROPERTY_ENABLE;
  filt_settling_mask.irq_xl = PROPERTY_ENABLE;
  filt_settling_mask.irq_g = PROPERTY_ENABLE;
  lsm6dsv80x_filt_settling_mask_set(&dev_ctx, filt_settling_mask);
  lsm6dsv80x_filt_xl_lp2_set(&dev_ctx, PROPERTY_ENABLE);
  lsm6dsv80x_filt_xl_lp2_bandwidth_set(&dev_ctx, LSM6DSV80X_XL_STRONG);

High-g 唤醒/冲击检测器

HG_FUNCTIONS_ENABLE (0x52) 的 HG_SHOCK_DUR[3:0](冲击状态退出持续时间)。
HG_SHOCK_DUR[s] = (HG_SHOCK_DUR + 1) * 512 / ODR_XL_HG
前面把 ODR 设为 960 Hz,所以:
● hg_shock_dur=1 → (1+1)*512/960 ≈ 1.07 s

检测到一次 high-g 事件后,芯片会用这个“持续时间/去抖窗口”来定义 shock 状态的保持/退出节奏,避免事件抖动导致中断疯狂触发

陀螺仪

HG_WAKE_UP_THS (0x53) 的 HG_WK_THS[7:0](high-g wake-up 阈值)。
● 分辨率规则: 1 g/LSB。
● FS 选了 ±80 g,所以:
● hg_wakeup_ths=4 ≈ 4 g 阈值
● 直观含义:任一轴的 high-g 加速度超过约 4 g,就会被判定为 wake-up(后续再通过你读到的 hg_wakeup_x/y/z 来看是哪一轴触发)。

wu_cfg.hg_shock_dur = 1;
  wu_cfg.hg_wakeup_ths = 4;
  lsm6dsv80x_hg_wake_up_cfg_set(&dev_ctx, wu_cfg);

中断配置

把“HG wakeup 事件(DRDY_XL)路由到芯片的 INT1 引脚上,从而让 INT1 产生脉冲/中断 去唤醒 MCU。

/* enable interrupt on HG wakeup */
  pin_int.hg_wakeup = PROPERTY_ENABLE;
  lsm6dsv80x_pin_int1_route_hg_set(&dev_ctx, &pin_int);
  //lsm6dsv80x_pin_int2_route_hg_set(&dev_ctx, &pin_int);

LSM6DSV80X_HG_FUNCTIONS_ENABLE 寄存器中的 hg_interrupts_enable 字段为 1。
把 HG 相关事件(包括 hg_wakeup)允许输出到中断系统。

陀螺仪

int_cfg.hg_interrupts_enable = 1;
  lsm6dsv80x_hg_wu_interrupt_cfg_set(&dev_ctx, int_cfg);

High-G 事件状态

lsm6dsv80x_hg_event_get() 读 0x4C → 如果 HG_WU_IA 等位为 1 → 再判断 HG_X_WU/HG_Y_WU/HG_Z_WU → 打印是哪几个轴超过阈值。

陀螺仪

陀螺仪

/* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    if (thread_wake) {
      lsm6dsv80x_hg_event_t status;

      thread_wake = 0;

      lsm6dsv80x_hg_event_get(&dev_ctx, &status);

      if (status.hg_event) {
        if (status.hg_wakeup) {
          uint8_t axis = 0;

          if (status.hg_wakeup_x) {
            axis |= AXIS_X;
          }

          if (status.hg_wakeup_y) {
            axis |= AXIS_Y;
          }

          if (status.hg_wakeup_z) {
            axis |= AXIS_Z;
          }

          printf("WAKEUP event on X: %d, Y = %d, Z= %drn",
                  (axis & AXIS_X) ? 1 : 0,
                  (axis & AXIS_Y) ? 1 : 0,
                  (axis & AXIS_Z) ? 1 : 0);
        }
      }
    }        
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

演示

陀螺仪

审核编辑 黄宇

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分