陀螺仪LSM6DSV320X开发(6)----单双击检测

描述

概述

本实验主要演示如何使用 LSM6DSV320X 的 Tap Detection 功能,实现对单击和双击动作的识别。通过配置传感器的 Tap 检测轴、敲击阈值、时间窗口以及中断输出,将 Single Tap 和 Double Tap 事件映射到 INT1 引脚。当检测到敲击动作后,MCU 通过外部中断唤醒主循环,并读取 LSM6DSV320X 的事件源寄存器,判断当前触发的是单击还是双击事件,最后通过串口打印检测结果。

需要样片的可以加群申请:925643491/615061293 。

陀螺仪

视频教学

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

样品申请

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

源码下载

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

硬件准备

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

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

陀螺仪

参考程序

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

https://gitee.com/CoreMaker/LSM6DSV320X

生成STM32CUBEMX

用STM32CUBEMX生成例程,这里使用MCU为STM32H503CB。 配置时钟树,配置时钟为250M。

陀螺仪

串口配置

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

陀螺仪

配置串口,速率为2000000。

陀螺仪

IIC配置

陀螺仪

陀螺仪

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

陀螺仪

CS和SA0设置

陀螺仪

陀螺仪

陀螺仪

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

陀螺仪

陀螺仪

陀螺仪

INT配置

INT1管脚为PB0。

陀螺仪

陀螺仪

配置如下所示。

陀螺仪

开启中断。

陀螺仪

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/lsm6dsv320x-pid

变量定义

/* USER CODE BEGIN 0 */
#define SENSOR_BUS hi2c1


/* Private macro -------------------------------------------------------------*/
#define    BOOT_TIME            10 //ms
#define    CNT_FOR_OUTPUT       100

/* Private variables ---------------------------------------------------------*/
static int16_t data_raw_motion[3];
static int16_t data_raw_temperature;
static float_t acceleration_mg[3];
static float_t angular_rate_mdps[3];
static float_t temperature_degC;
static uint8_t whoamI;
static uint8_t tx_buffer[1000];

static lsm6dsv320x_filt_settling_mask_t filt_settling_mask;

/* Extern variables ----------------------------------------------------------*/

/* Private functions ---------------------------------------------------------*/

/*
 *   WARNING:
 *   Functions declare in this section are defined at the end of this file
 *   and are strictly related to the hardware platform used.
 *
 */
static int32_t platform_write(void *handle, uint8_t reg, const uint8_t *bufp,
                              uint16_t len);
static int32_t platform_read(void *handle, uint8_t reg, uint8_t *bufp,
                             uint16_t len);
static void tx_com( uint8_t *tx_buffer, uint16_t len );
static void platform_delay(uint32_t ms);
static void platform_init(void);

static   stmdev_ctx_t dev_ctx;
static volatile uint8_t stap_event_catched = 0;
static volatile uint8_t dtap_event_catched = 0;

static   uint8_t thread_wake = 0;
static lsm6dsv320x_interrupt_mode_t irq;
static lsm6dsv320x_tap_detection_t tap;
static lsm6dsv320x_tap_thresholds_t tap_ths;
static lsm6dsv320x_tap_time_windows_t tap_win;


/* USER CODE END 0 */

初始换管脚

由于需要向LSM6DSV320X_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);

  lsm6dsv320x_pin_int_route_t pin_int = { 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。

陀螺仪

lsm6dsv320x_device_id_get为获取函数。

陀螺仪

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

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

软件上电复位

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

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

陀螺仪

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

/* Perform device power-on-reset */
  lsm6dsv320x_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 */
  lsm6dsv320x_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);

Tap 中断配置说明

LSM6DSV320X 内部可以识别 Single Tap 和 Double Tap 事件,但如果希望 MCU 通过外部中断方式响应这些事件,需要将对应的事件映射到传感器的中断引脚上。
将 Single Tap 和 Double Tap 事件都映射到 INT1 引脚。
Single Tap 和 Double Tap 事件映射到 INT1 引脚,对应 MD1_CFG 寄存器 5Eh。
陀螺仪

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

pin_int.double_tap = PROPERTY_ENABLE;
  pin_int.single_tap = PROPERTY_ENABLE;
  lsm6dsv320x_pin_int1_route_set(&dev_ctx, &pin_int);

使能中断输出

完成中断路由配置后,还需要使能 LSM6DSV320X 的中断输出功能。
中断信号触发后不会一直保持,需要及时读取事件源寄存器。 如果希望中断保持到软件读取状态寄存器后再清除,可以考虑将 lir 配置为 1。

陀螺仪

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

irq.enable = 1;
  irq.lir = 0;
  lsm6dsv320x_interrupt_enable_set(&dev_ctx, irq);

使能 Z 轴 Tap 检测

Tap 检测是基于加速度计数据实现的。LSM6DSV320X 可以配置 X、Y、Z 三个方向的 Tap 检测轴。 本实验中只开启 Z 轴 Tap 检测,也就是主要检测垂直于模块表面的敲击动作。 具体是否需要开启多个方向,需要根据实际产品安装方向和敲击方向来决定。
Tap 检测轴配置对应 TAP_CFG0 寄存器 56h。

陀螺仪

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

tap.tap_z_en = 1;
  lsm6dsv320x_tap_detection_set(&dev_ctx, tap);

配置 Tap 阈值

Z 轴 Tap 阈值对应 TAP_THS_6D 寄存器 59h。
该配置实际对应的是写入 TAP_THS_6D(59h) 寄存器的低 5 位 TAP_THS_Z[4:0]。在当前 ±8g 量程下,1 LSB 对应 0.25g,因此阈值 3 对应约 0.75g。

陀螺仪

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

tap_ths.z = 3;
  lsm6dsv320x_tap_thresholds_set(&dev_ctx, tap_ths);

配置 Tap 时间窗口

LSM6DSV320X 的单击 / 双击识别不仅需要配置 Tap 阈值,还需要配置 Tap 识别的时间窗口。时间窗口主要用于判断一次敲击的持续时间、敲击后的静默时间,以及两次敲击之间的最大间隔。
Tap 时间窗口由 TAP_DUR 寄存器 配置,该寄存器地址为 5Ah.

bit7~bit4:DUR[3:0]

用于配置双击识别时,两次 Tap 之间允许的最大时间间隔。

bit3~bit2:QUIET[1:0]

用于配置第一次 Tap 检测后的静默时间。在 quiet time 内,不能再出现超过阈值的事件,否则可能会影响 Tap 判断。

bit1~bit0:SHOCK[1:0]

用于配置一次 Tap 允许的最大冲击持续时间。如果超过阈值的时间太长,传感器可能不会将其识别为一次有效 Tap。

陀螺仪

在当前 ODR_XL = 480Hz 条件下,双击最大间隔约为 466.7 ms,Tap 后静默时间约为 25 ms,单次 Tap 最大冲击持续时间约为 50 ms。实际产品调试时,如果双击不容易触发,可以适当增大 tap_gap;如果单击容易被误识别为双击,可以适当调整 quiet 和 tap_gap;如果敲击动作持续时间较长但无法识别,可以适当调整 shock 参数。
对应的驱动程序,如下所示。

tap_win.tap_gap = 7;
  tap_win.shock = 3;
  tap_win.quiet = 3;
  lsm6dsv80x_tap_time_windows_set(&dev_ctx, tap_win);

配置 Single Tap / Double Tap 检测模式

LSM6DSV320X 的单击 / 双击模式选择由 WAKE_UP_THS 寄存器 配置,该寄存器地址为 5Bh. LSM6DSV320X 会同时支持 Single Tap 和 Double Tap 检测。 当只检测到一次有效敲击时,可以产生 Single Tap 事件; 当在设定的 TAP_DUR(5Ah) 时间窗口内连续检测到两次有效敲击时,可以产生 Double Tap 事件。

陀螺仪

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

lsm6dsv320x_tap_mode_set(&dev_ctx, LSM6DSV320X_BOTH_SINGLE_DOUBLE);

设置量程和速率

/* Set Output Data Rate.*/
  lsm6dsv320x_xl_setup(&dev_ctx, LSM6DSV320X_ODR_AT_480Hz, LSM6DSV320X_XL_HIGH_PERFORMANCE_MD);
  /* Set full scale */
  lsm6dsv320x_xl_full_scale_set(&dev_ctx, LSM6DSV320X_8g);

外部中断回调函数

当 LSM6DSV320X 检测到 Single Tap 或 Double Tap 后,INT1 引脚会产生中断信号。

void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{
  if (GPIO_Pin == INT1_Pin) {
    thread_wake = 1;
  }
}

主程序

/* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
        if(thread_wake==1)
        {
            thread_wake=0;
            lsm6dsv320x_all_sources_t status;
            /* Read output only if new xl value is available */
            lsm6dsv320x_all_sources_get(&dev_ctx, &status);

            if (status.single_tap) {
                stap_event_catched = 1;
            }
            if (status.double_tap) {
                dtap_event_catched = 1;
            }        

            if (stap_event_catched) {
                stap_event_catched = 0;
        printf("Single TAPrn");
            }
            if (dtap_event_catched) {
        dtap_event_catched = 0;
        printf("Double TAPrn");
            }            

        }

    /* USER CODE END WHILE */

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

演示

陀螺仪

审核编辑 黄宇

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

全部0条评论

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

×
20
完善资料,
赚取积分