陀螺仪LSM6DSOW开发(3)-

2024-08-05

概述

本文档旨在详细介绍如何配置和读取LSM6DSOW传感器的FIFO数据。LSM6DSOW是一款高性能的6轴IMU(惯性测量单元),集成了三轴加速度计和三轴陀螺仪。FIFO(先进先出)缓冲区是LSM6DSOW的重要功能之一,它能够有效地存储传感器数据,减少主机的读取频率,从而降低功耗和提高数据采集效率。

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

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第1张

视频教学

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

样品申请

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

源码下载

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

硬件准备

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

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第2张

主要内容

  1. 初始化LSM6DSOW传感器并检查其设备ID
  2. 恢复传感器默认配置并设置必要的参数
  3. 配置FIFO模式和水印阈值
  4. 设置加速度计和陀螺仪的数据速率
  5. 连续读取FIFO中的传感器数据并解析输出

LSM6DSOW支持六种不同的FIFO模式,每种模式适用于不同的应用场景:

  1. Bypass Mode(旁路模式):

    ○ 在旁路模式下,FIFO不运行,传感器数据直接输出,不存储在FIFO中。该模式常用于实时数据读取。
  2. FIFO Mode(FIFO模式):

    ○ 在FIFO模式下,数据连续存储到FIFO中,直到FIFO满。当FIFO满时,旧数据将被新数据覆盖。适用于需要连续存储数据供后续处理的情况。
  3. Continuous Mode(连续模式):

    ○ 在连续模式下,FIFO始终保存最新的数据,当FIFO满时,旧数据被丢弃,新数据继续写入FIFO。适用于需要实时监控最新数据的应用。
  4. Continuous to FIFO Mode(连续到FIFO模式):

    ○ 开始时处于连续模式,当检测到某个事件时切换到FIFO模式。适用于在特定事件发生后保存数据。
  5. Bypass to Continuous Mode(旁路到连续模式):

    ○ 开始时处于旁路模式,当检测到某个事件时切换到连续模式。适用于事件发生后开始实时数据监控。
  6. Bypass to FIFO Mode(旁路到FIFO模式):

    ○ 开始时处于旁路模式,当检测到某个事件时切换到FIFO模式,开始存储数据。适用于事件发生后开始数据记录。

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第3张

生成STM32CUBEMX

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

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

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第4张

串口配置

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

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第5张

配置串口,速率为2000000。

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第6张

IIC配置

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第7张

LSM6DSOW最大IIC通讯速率为400k。

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第8张

配置IIC速度为400k

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第9张

CS和SA0设置

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第10张

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第11张

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

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第12张

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第13张

INT设置

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第14张

配置为输入检测模式。

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第15张

ICASHE

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第16张

修改堆栈

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第17张

串口重定向

打开魔术棒,勾选MicroLIB

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第18张

在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/lsm6dso-pid

初始化管脚

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

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第19张

所以使能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);


  stmdev_ctx_t dev_ctx;
  /* 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)获取固定值,判断是否为0x6C

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第20张

lsm6dso_device_id_get为获取函数。

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第21张

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

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

复位操作

可以向CTRL3 (12h)的SW_RESET寄存器写入1进行复位。

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第22张

lsm6dso_reset_set为重置函数。

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第23张

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

/* Restore default configuration */
  lsm6dso_reset_set(&dev_ctx, PROPERTY_ENABLE);

  do {
    lsm6dso_reset_get(&dev_ctx, &rst);
  } while (rst);

关闭I3C

/* Disable I3C interface */
  lsm6dso_i3c_disable_set(&dev_ctx, LSM6DSO_I3C_DISABLE);

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进行开启。



陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第24张
对应的驱动程序,如下所示。

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

设置量程和速率

速率可以通过CTRL1 (10h)设置加速度速率和CTRL2 (11h)进行设置角速度速率。

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第25张

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第26张

设置加速度量程可以通过CTRL1 (10h)进行设置。

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第27张

设置角速度量程可以通过CTRL2 (11h)进行设置。

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第28张

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

/* Set Output Data Rate */
  lsm6dso_xl_data_rate_set(&dev_ctx, LSM6DSO_XL_ODR_12Hz5);
  lsm6dso_gy_data_rate_set(&dev_ctx, LSM6DSO_GY_ODR_12Hz5);
  /* Set full scale */
  lsm6dso_xl_full_scale_set(&dev_ctx, LSM6DSO_2g);
  lsm6dso_gy_full_scale_set(&dev_ctx, LSM6DSO_2000dps);

设置FIFO水印

可编程FIFO阈值可以通过FIFO_CTRL1(07h)和FIFO_CTRL2(08h)寄存器中的WTM8[0]位设置。为了监视FIFO状态,可以读取专用寄存器(FIFO_STATUS1(3Ah),FIFO_STATUS2(3Bh)),以检测FIFO溢出事件、FIFO满状态、FIFO空状态、FIFO水位状态和FIFO中存储的未读样本数。

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第29张

LSM6DSOW传感器通过一系列控制寄存器来配置和管理FIFO。通过配置WTM,用户可以灵活地管理传感器数据的批处理。当数据量达到设定的阈值时,主处理器可以一次性读取大量数据,提高数据读取效率,减少频繁的I/O操作。 1 LSB = 1传感器(6字节) + TAG(1字节)写入FIFO

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第30张

/* Set FIFO watermark (number of unread sensor data TAG + 6 bytes
   * stored in FIFO) to 10 samples
   */
  lsm6dso_fifo_watermark_set(&dev_ctx, 10);

FIFO_CTRL3寄存器用于选择陀螺仪和加速度计数据在FIFO中的批处理数据速率(BDR)。每个传感器都有独立的控制位,可以设置不同的批处理数据速率,从而控制数据写入FIFO的频率。

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第31张

/* Set FIFO batch XL/Gyro ODR to 12.5Hz */
  lsm6dso_fifo_xl_batch_set(&dev_ctx, LSM6DSO_XL_BATCHED_AT_12Hz5);
  lsm6dso_fifo_gy_batch_set(&dev_ctx, LSM6DSO_GY_BATCHED_AT_12Hz5);

FIFO_CTRL4寄存器用于配置LSM6DSOW传感器的FIFO模式、时间戳批处理和温度数据批处理速率。该寄存器包含多个字段,每个字段的功能如下所述。

FIFO_MODE[2:0]: FIFO模式选择

● 用于选择FIFO的工作模式。

● 000: Bypass mode(旁路模式),FIFO禁用

● 001: FIFO mode(FIFO模式),FIFO满时停止收集数据

● 010: 保留

● 011: Continuous-to-FIFO mode(连续到FIFO模式),连续模式直到触发器释放,然后进入FIFO模式

● 100: Bypass-to-continuous mode(旁路到连续模式),旁路模式直到触发器释放,然后进入连续模式

● 101: 保留

● 110: Continuous mode(连续模式),FIFO满时新数据覆盖旧数据

● 111: Bypass-to-FIFO mode(旁路到FIFO模式),旁路模式直到触发器释放,然后进入FIFO模式

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第32张

/* Set FIFO mode to Stream mode (aka Continuous Mode) */
  lsm6dso_fifo_mode_set(&dev_ctx, LSM6DSO_STREAM_MODE);

设置中断

COUNTER_BDR_REG1寄存器用于配置批处理数据速率计数器的相关参数。该寄存器允许用户选择数据准备模式、重置内部计数器以及选择批处理事件的触发器。以下是COUNTER_BDR_REG1寄存器的详细描述。

COUNTER_BDR_REG1寄存器位字段

● dataready_pulsed: 启用脉冲数据准备模式

○ 0: 数据准备锁存模式(默认),仅在接口读取后返回0;

○ 1: 数据准备脉冲模式(数据准备脉冲持续时间为75微秒)。

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第33张

INT1_CTRL寄存器用于配置INT1引脚的控制信号。该寄存器的每个位可以启用一个信号,当MIPI I3CSM动态地址未分配时,信号可以通过INT1引脚传输。一些位还可以在使用MIPI I3CSM接口时触发IBI(带内中断)。引脚的输出是此处选择的信号与MD1_CFG(5Eh)中的信号的或组合。

INT1_CTRL寄存器字段描述

● DEN_DRDY_flag: 发送DEN_DRDY(DEN标记在传感器数据标志上)到INT1引脚。

● INT1_CNT_BDR: 启用COUNTER_BDR_IA中断在INT1引脚上。

● INT1_FIFO_FULL: 启用FIFO满中断在INT1引脚上。当使用MIPI I3CSM接口时,它还可以用于触发IBI。

● INT1_FIFO_OVR: 启用FIFO溢出中断在INT1引脚上。当使用MIPI I3CSM接口时,它还可以用于触发IBI。

● INT1_FIFO_TH: 启用FIFO阈值中断在INT1引脚上。当使用MIPI I3CSM接口时,它还可以用于触发IBI。

● INT1_BOOT: 启用引导状态在INT1引脚上。

● INT1_DRDY_G: 启用陀螺仪数据准备中断在INT1引脚上。当使用MIPI I3CSM接口时,它还可以用于触发IBI。

● INT1_DRDY_XL: 启用加速度计数据准备中断在INT1引脚上。当使用MIPI I3CSM接口时,它还可以用于触发IBI。

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第34张

lsm6dso_pin_int1_route_get(&dev_ctx, ∫1_route);
  int1_route.fifo_th = PROPERTY_ENABLE;
  lsm6dso_pin_int1_route_set(&dev_ctx, int1_route);

获取FIFO数据

FIFO_STATUS寄存器用于监控LSM6DSOW传感器FIFO的状态。它们包括FIFO_STATUS1(3Ah)和FIFO_STATUS2(3Bh),分别用于报告未读数据和FIFO状态信息。

当FIFO中的数据量达到或超过预设的水位线时,FIFO_WTM_IA位将被置为1。这意味着主处理器可以通过读取该位的状态来确定何时需要处理FIFO中的数据。例如,当数据量达到水位线时,触发一次中断,主处理器读取并处理FIFO中的数据,然后继续下一轮数据采集。

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第35张

DIFF_FIFO 位于 FIFO_STATUS1 (3Ah) 和 FIFO_STATUS2 (3Bh) 寄存器中,用于指示FIFO中未读传感器数据的数量。它包括两个部分:

● DIFF_FIFO7:07:07:0: 位于 FIFO_STATUS1 寄存器中,表示未读数据的低8位。

● DIFF_FIFO9:89:89:8: 位于 FIFO_STATUS2 寄存器中,表示未读数据的高2位。

DIFF_FIFO字段用于跟踪FIFO中未读的数据量。通过读取DIFF_FIFO,可以确定FIFO中当前存储了多少数据,这对于决定何时读取FIFO中的数据非常重要。该字段的值在数据从FIFO中读取时会自动更新。

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第36张

FIFO_DATA_OUT_TAG (78h)寄存器用于标识FIFO中的传感器数据来源。该寄存器包含标识符(TAG),用于指示数据是由哪个传感器生成的,并帮助用户正确地解析FIFO中的数据。

TAG_SENSOR: 标识FIFO中的传感器数据源。根据传感器类型和数据源,该字段值表示具体的传感器数据。详细见下表。

FIFO_DATA_OUT_TAG 寄存器提供了数据标签,用于识别FIFO中存储的数据来源。这对于解析和处理从FIFO中读取的数据非常重要。通过TAG字段,用户可以区分不同传感器的数据,并采取适当的处理措施。

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第37张

FIFO_DATA_OUT_X, FIFO_DATA_OUT_Y 和 FIFO_DATA_OUT_Z 寄存器,这些寄存器用于读取LSM6DSOW传感器的FIFO中的X、Y和Z轴数据。每个轴的数据由两个寄存器组成:一个低字节寄存器(_L)和一个高字节寄存器(_H)。

为了从FIFO中读取加速度计或陀螺仪的X、Y、Z轴数据,需要依次读取对应的低字节和高字节寄存器,并将它们组合成一个完整的16位数据。

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第38张

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第39张

/* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    uint16_t num = 0;
    uint8_t wmflag = 0;
    lsm6dso_fifo_tag_t reg_tag;
    axis3bit16_t dummy;

        if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0))
        {
    /* Read watermark flag */
    lsm6dso_fifo_wtm_flag_get(&dev_ctx, &wmflag);

    if (wmflag > 0) {
      /* Read number of samples in FIFO */
      lsm6dso_fifo_data_level_get(&dev_ctx, #);

      while (num--) {
        /* Read FIFO tag */
        lsm6dso_fifo_sensor_tag_get(&dev_ctx, ®_tag);

        switch (reg_tag) {
          case LSM6DSO_XL_NC_TAG:
            memset(data_raw_acceleration.u8bit, 0x00 
3 * sizeof(int16_t)); lsm6dso_fifo_out_raw_get(&dev_ctx, data_raw_acceleration.u8bit); acceleration_mg[0] = lsm6dso_from_fs2_to_mg(data_raw_acceleration.i16bit[0]); acceleration_mg[1] = lsm6dso_from_fs2_to_mg(data_raw_acceleration.i16bit[1]); acceleration_mg[2] = lsm6dso_from_fs2_to_mg(data_raw_acceleration.i16bit[2]); printf("Acceleration [mg]:%4.2ft%4.2ft%4.2frn"
acceleration_mg[0], acceleration_mg[1], acceleration_mg[2]); break; case LSM6DSO_GYRO_NC_TAG: memset(data_raw_angular_rate.u8bit, 0x00
3 * sizeof(int16_t)); lsm6dso_fifo_out_raw_get(&dev_ctx, data_raw_angular_rate.u8bit); angular_rate_mdps[0] = lsm6dso_from_fs2000_to_mdps(data_raw_angular_rate.i16bit[0]); angular_rate_mdps[1] = lsm6dso_from_fs2000_to_mdps(data_raw_angular_rate.i16bit[1]); angular_rate_mdps[2] = lsm6dso_from_fs2000_to_mdps(data_raw_angular_rate.i16bit[2]); printf("Angular rate [mdps]:%4.2ft%4.2ft%4.2frn"
angular_rate_mdps[0], angular_rate_mdps[1], angular_rate_mdps[2]); break; default: /* Flush unused samples */ memset(dummy.u8bit, 0x00
3 * sizeof(int16_t)); lsm6dso_fifo_out_raw_get(&dev_ctx, dummy.u8bit); break; } } } } /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */

演示

陀螺仪LSM6DSOW开发(3)- (https://ic.work/) 技术资料 第40张

文章推荐

相关推荐