陀螺仪LSM6DSV80X开发(6)----单双击检测
2026/6/8 3:21:55 网站建设 项目流程

陀螺仪LSM6DSV80X开发.6--单双击检测

  • 概述
  • 视频教学
  • 样品申请
  • 源码下载
  • 硬件准备
  • 参考程序
  • 生成STM32CUBEMX
  • 串口配置
  • IIC配置
  • CS和SA0设置
  • INT配置
  • ICASHE
  • 修改堆栈
  • 串口重定向
  • 参考程序
  • 变量定义
  • 初始换管脚
  • 获取ID
  • 软件上电复位
  • BDU设置
  • Tap 中断配置说明
  • 使能中断输出
  • 使能 Z 轴 Tap 检测
  • 配置 Tap 阈值
  • 配置 Tap 时间窗口
  • 配置 Single Tap / Double Tap 检测模式
  • 设置量程和速率
  • 外部中断回调函数
  • 主程序
  • 演示

概述

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

视频教学

https://www.bilibili.com/video/BV1tYGJ6vEHK/

样品申请

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

源码下载

https://download.csdn.net/download/qq_24312945/92952592

硬件准备

首先需要准备一个开发板,这里我准备的是自己绘制的开发板,需要的可以进行申请。
主控为STM32H503CB,陀螺仪为LSM6DSV80X,磁力计为LIS2MDL。

参考程序

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

https://gitee.com/CoreMaker/LSM6DSV80X

生成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 */intfputc(intch,FILE*f){HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,0xFFFF);returnch;}/* USER CODE END PFP */

参考程序

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

变量定义

/* USER CODE BEGIN 0 */#defineSENSOR_BUShi2c1/* Private macro -------------------------------------------------------------*/#defineBOOT_TIME10//ms#defineCNT_FOR_OUTPUT100/* Private variables ---------------------------------------------------------*/staticint16_tdata_raw_motion[3];staticint16_tdata_raw_temperature;staticfloat_tacceleration_mg[3];staticfloat_tangular_rate_mdps[3];staticfloat_ttemperature_degC;staticuint8_twhoamI;staticuint8_ttx_buffer[1000];staticlsm6dsv80x_filt_settling_mask_tfilt_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. * */staticint32_tplatform_write(void*handle,uint8_treg,constuint8_t*bufp,uint16_tlen);staticint32_tplatform_read(void*handle,uint8_treg,uint8_t*bufp,uint16_tlen);staticvoidtx_com(uint8_t*tx_buffer,uint16_tlen);staticvoidplatform_delay(uint32_tms);staticvoidplatform_init(void);staticstmdev_ctx_tdev_ctx;staticvolatileuint8_tstap_event_catched=0;staticvolatileuint8_tdtap_event_catched=0;staticuint8_tthread_wake=0;staticlsm6dsv80x_interrupt_mode_tirq;staticlsm6dsv80x_tap_detection_ttap;staticlsm6dsv80x_tap_thresholds_ttap_ths;staticlsm6dsv80x_tap_time_windows_ttap_win;/* USER CODE END 0 */

初始换管脚

由于需要向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_tpin_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。

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);

Tap 中断配置说明

LSM6DSV80X 内部可以识别 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;lsm6dsv80x_pin_int1_route_set(&dev_ctx,&pin_int);

使能中断输出

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

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

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

使能 Z 轴 Tap 检测

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


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

tap.tap_z_en=1;lsm6dsv80x_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;lsm6dsv80x_tap_thresholds_set(&dev_ctx,tap_ths);

配置 Tap 时间窗口

LSM6DSV80X 的单击 / 双击识别不仅需要配置 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 检测模式

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

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

lsm6dsv80x_tap_mode_set(&dev_ctx,LSM6DSV80X_BOTH_SINGLE_DOUBLE);

设置量程和速率

/* Set Output Data Rate.*/lsm6dsv80x_xl_setup(&dev_ctx,LSM6DSV80X_ODR_AT_480Hz,LSM6DSV80X_XL_HIGH_PERFORMANCE_MD);/* Set full scale */lsm6dsv80x_xl_full_scale_set(&dev_ctx,LSM6DSV80X_8g);

外部中断回调函数

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

voidHAL_GPIO_EXTI_Rising_Callback(uint16_tGPIO_Pin){if(GPIO_Pin==INT1_Pin){thread_wake=1;}}

主程序

/* Infinite loop *//* USER CODE BEGIN WHILE */while(1){if(thread_wake==1){thread_wake=0;lsm6dsv80x_all_sources_tstatus;/* Read output only if new xl value is available */lsm6dsv80x_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 TAP\r\n");}if(dtap_event_catched){dtap_event_catched=0;printf("Double TAP\r\n");}}/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */

演示

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询