0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

陀螺仪LSM6DSOW开发(1)----轮询获取陀螺仪数据

嵌入式单片机MCU开发 来源:嵌入式单片机MCU开发 作者:嵌入式单片机MCU开 2024-08-05 09:44 次阅读

概述

本文将介绍如何使用 LSM6DSOW 传感器来读取数据。主要步骤包括初始化传感器接口、验证设备ID、配置传感器的数据输出率和滤波器,以及通过轮询方式持续读取加速度、角速率和温度数据。读取到的数据会被转换为适当的单位并通过串行通信输出。这个代码是一个很好的起点,用于了解如何操作 LSM6DSOW 传感器并获取其数据。

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

视频教学

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

样品申请

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

源码下载

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

硬件准备

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

LSM6DSOW & LSM6DSO

LSM6DSOW 和 LSM6DSO 是两款惯性测量单元(IMU),都具备三轴数字加速度计和三轴数字陀螺仪功能。它们之间的主要区别如下:

  1. FIFO 容量和数据压缩:
    ○ LSM6DSOW:支持高达 9 KB 的 FIFO,具备动态数据分批和压缩功能,可以实现高效的省电和数据存储。
    ○ LSM6DSO:同样支持 9 KB 的 FIFO,更注重压缩效率,可以实现 2 到 3 倍的数据压缩。
  2. 输出数据速率 (ODR):
    ○ LSM6DSOW:提供广泛的加速度计和陀螺仪的 ODR 范围,支持高达 6.66 kHz 的值。
    ○ LSM6DSO:也支持高 ODR,但在配置和具体值上略有不同。
  3. 显著运动检测
    ○ LSM6DSOW:包含显著运动检测功能,主要利用加速度计来实现此功能。
    ○ LSM6DSO:类似地实现显著运动检测,并突出其他功能如计步器、步态检测和倾斜感应。
  4. 有限状态机 (FSM):
    ○ LSM6DSOW:具有多达 16 个独立的有限状态机,可编程用于各种运动检测任务。
    ○ LSM6DSO:同样包含多达 16 个 FSM,具备类似功能,但更强调与外部传感器的集成。
  5. 功耗和模式:
    ○ LSM6DSOW:设计用于低功耗,具有多种工作模式,包括高性能和超低功耗模式。
    ○ LSM6DSO:具有类似的低功耗特性,特定模式适用于 Android 兼容和高效运动跟踪。
  6. 中断和事件检测:
    ○ LSM6DSOW:支持多种事件检测中断,如自由落体、唤醒、6D 定位、单击和双击检测等。
    ○ LSM6DSO:实现了类似的事件检测功能,重点是 Android 兼容和显著运动检测。
    总结来说,尽管两款传感器在核心功能上相似,LSM6DSOW 优化了高级运动检测和省电特性,适用于需要高效数据管理和复杂运动跟踪的应用。LSM6DSO 则强调 Android 兼容性和强大的数据压缩,适合需要多功能传感器集成的移动和物联网应用。 有关详细的规格和功能,可以参考 STMicroelectronics 提供的 LSM6DSOW 和 LSM6DSO 的数据手册和技术说明。

通信模式

对于LSM6DSOW,可以使用SPI或者IIC进行通讯。 最小系统图如下所示。

在CS管脚为1的时候,为IIC模式。

本文使用的板子原理图如下所示。

管脚定义

IIC通信模式

在在使用IIC通讯模式的时候,SA0是用来控制IIC的地址位的。

对于IIC的地址,可以通过SDO/SA0引脚修改。SDO/SA0引脚可以用来修改设备地址的最低有效位。如果SDO/SA0引脚连接到电源电压,LSb(最低有效位)为'1'(地址1101011b);否则,如果SDO/SA0引脚连接到地线,LSb的值为'0'(地址1101010b)。

接口如下所示。 主要使用的管脚为CS、SCL、SDA、SA0。

速率

该模块支持的速度为普通模式(100k)和快速模式(400k)。

生成STM32CUBEMX

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

串口配置

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

配置串口,速率为2000000。

IIC配置

LSM6DSOW最大IIC通讯速率为400k,配置IIC速度为400k

CS和SA0设置

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

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

初始化管脚

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


  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

lsm6dso_device_id_get为获取函数。

对应的获取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进行复位。

lsm6dso_reset_set为重置函数。

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

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

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

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

设置量程和速率

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

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

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

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

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

配置滤波器

/* Configure filtering chain(No aux interface)
   * Accelerometer - LPF1 + LPF2 path
   */
  lsm6dso_xl_hp_path_on_out_set(&dev_ctx, LSM6DSO_LP_ODR_DIV_100);
  lsm6dso_xl_filter_lp2_set(&dev_ctx, PROPERTY_ENABLE);

轮询读取数据

进入一个无限循环,不断检查是否有新的数据(加速度、角速率、温度)可用。
对于每种类型的数据(加速度、角速率、温度),如果有新数据,就读取原始数据,转换为对应的单位(毫克、毫度每秒、摄氏度),并通过串行输出打印。

对于数据是否准备好,可以访问STATUS_REG (1Eh)进行判断。

/* Read output only if new xl value is available */
    lsm6dso_xl_flag_data_ready_get(&dev_ctx, ®);

对于加速度数据,可以通过28-2D进行获取。

加速度数据首先以原始格式(通常是整数)读取,然后需要转换为更有意义的单位,如毫重力(mg)。这里的转换函数 lsm6dso_from_fs2_to_mg() 根据加速度计的量程(这里假设为±2g)将原始数据转换为毫重力单位。

acceleration_mg[0] = lsm6dso_from_fs2_to_mg(data_raw_acceleration[0]);等三行代码分别转换 X、Y、Z 轴的加速度数据。

/* Read output only if new xl value is available */
    lsm6dso_xl_flag_data_ready_get(&dev_ctx, ®);

    if (reg) {
      /* Read acceleration field data */
      memset(data_raw_acceleration, 0x00, 3 * sizeof(int16_t));
      lsm6dso_acceleration_raw_get(&dev_ctx, data_raw_acceleration);
      acceleration_mg[0] =
        lsm6dso_from_fs2_to_mg(data_raw_acceleration[0]);
      acceleration_mg[1] =
        lsm6dso_from_fs2_to_mg(data_raw_acceleration[1]);
      acceleration_mg[2] =
        lsm6dso_from_fs2_to_mg(data_raw_acceleration[2]);
      printf( "Acceleration [mg]:%4.2ft%4.2ft%4.2frn",
              acceleration_mg[0], acceleration_mg[1], acceleration_mg[2]);

    }

对于角速度数据,可以通过22-27进行获取。

lsm6dso_gy_flag_data_ready_get(&dev_ctx, ®);

    if (reg) {
      /* Read angular rate field data */
      memset(data_raw_angular_rate, 0x00, 3 * sizeof(int16_t));
      lsm6dso_angular_rate_raw_get(&dev_ctx, data_raw_angular_rate);
      angular_rate_mdps[0] =
        lsm6dso_from_fs2000_to_mdps(data_raw_angular_rate[0]);
      angular_rate_mdps[1] =
        lsm6dso_from_fs2000_to_mdps(data_raw_angular_rate[1]);
      angular_rate_mdps[2] =
        lsm6dso_from_fs2000_to_mdps(data_raw_angular_rate[2]);
      printf("Angular rate [mdps]:%4.2ft%4.2ft%4.2frn",
              angular_rate_mdps[0], angular_rate_mdps[1], angular_rate_mdps[2]);

    }

对于温度数据,可以通过20-21进行获取。

lsm6dso_temp_flag_data_ready_get(&dev_ctx, ®);

    if (reg) {
      /* Read temperature data */
      memset(&data_raw_temperature, 0x00, sizeof(int16_t));
      lsm6dso_temperature_raw_get(&dev_ctx, &data_raw_temperature);
      temperature_degC =
        lsm6dso_from_lsb_to_celsius(data_raw_temperature);
      printf("Temperature [degC]:%6.2frn", temperature_degC);

    }

主程序

/* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {

    uint8_t reg;
    /* Read output only if new xl value is available */
    lsm6dso_xl_flag_data_ready_get(&dev_ctx, ®);

    if (reg) {
      /* Read acceleration field data */
      memset(data_raw_acceleration, 0x00, 3 * sizeof(int16_t));
      lsm6dso_acceleration_raw_get(&dev_ctx, data_raw_acceleration);
      acceleration_mg[0] =
        lsm6dso_from_fs2_to_mg(data_raw_acceleration[0]);
      acceleration_mg[1] =
        lsm6dso_from_fs2_to_mg(data_raw_acceleration[1]);
      acceleration_mg[2] =
        lsm6dso_from_fs2_to_mg(data_raw_acceleration[2]);
      printf( "Acceleration [mg]:%4.2ft%4.2ft%4.2frn",
              acceleration_mg[0], acceleration_mg[1], acceleration_mg[2]);

    }

    lsm6dso_gy_flag_data_ready_get(&dev_ctx, ®);

    if (reg) {
      /* Read angular rate field data */
      memset(data_raw_angular_rate, 0x00, 3 * sizeof(int16_t));
      lsm6dso_angular_rate_raw_get(&dev_ctx, data_raw_angular_rate);
      angular_rate_mdps[0] =
        lsm6dso_from_fs2000_to_mdps(data_raw_angular_rate[0]);
      angular_rate_mdps[1] =
        lsm6dso_from_fs2000_to_mdps(data_raw_angular_rate[1]);
      angular_rate_mdps[2] =
        lsm6dso_from_fs2000_to_mdps(data_raw_angular_rate[2]);
      printf("Angular rate [mdps]:%4.2ft%4.2ft%4.2frn",
              angular_rate_mdps[0], angular_rate_mdps[1], angular_rate_mdps[2]);

    }

    lsm6dso_temp_flag_data_ready_get(&dev_ctx, ®);

    if (reg) {
      /* Read temperature data */
      memset(&data_raw_temperature, 0x00, sizeof(int16_t));
      lsm6dso_temperature_raw_get(&dev_ctx, &data_raw_temperature);
      temperature_degC =
        lsm6dso_from_lsb_to_celsius(data_raw_temperature);
      printf("Temperature [degC]:%6.2frn", temperature_degC);

    }        


    /* USER CODE END WHILE */

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

演示

审核编辑 黄宇

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

    关注

    44

    文章

    758

    浏览量

    98042
  • stm32cubemx
    +关注

    关注

    5

    文章

    278

    浏览量

    14569
收藏 人收藏

    评论

    相关推荐

    详解三轴陀螺仪的技术原理

    陀螺仪的种类很多,按用途来分,它可以分为传感陀螺仪和指示陀螺仪。传感陀螺仪用于飞行体运动的自动控制系统中,作为水平、垂直、俯仰、航向和角速度传感器。指示
    发表于 10-26 20:25 4442次阅读
    详解三轴<b class='flag-5'>陀螺仪</b>的技术原理

    陀螺仪LSM6DSV16X与AI集成(2)----姿态解算

    LSM6DSV16X包含三轴陀螺仪与三轴加速度计。
    的头像 发表于 12-18 10:51 1360次阅读
    <b class='flag-5'>陀螺仪</b><b class='flag-5'>LSM6</b>DSV16X与AI集成(2)----姿态解算

    陀螺仪LSM6DSOW开发(2)----上报匿名上位机实现可视化

    本文档详细介绍了如何使用匿名助手的上位机实现加速度计和陀螺仪数据的可视化显示。内容涵盖了加速度计和陀螺仪的工作原理、上位机通信协议、数据处理流程以及具体的代码实现。通过本文档,读者可以
    的头像 发表于 08-05 09:52 747次阅读
    <b class='flag-5'>陀螺仪</b><b class='flag-5'>LSM6DSOW</b><b class='flag-5'>开发</b>(2)----上报匿名上位机实现可视化

    陀螺仪LSM6DSOW开发(3)----FIFO数据读取与配置

    本文档旨在详细介绍如何配置和读取LSM6DSOW传感器的FIFO数据LSM6DSOW是一款高性能的6轴IMU(惯性测量单元),集成了三轴加速度计和三轴
    的头像 发表于 08-05 10:03 817次阅读
    <b class='flag-5'>陀螺仪</b><b class='flag-5'>LSM6DSOW</b><b class='flag-5'>开发</b>(3)----FIFO<b class='flag-5'>数据</b>读取与配置

    三轴陀螺仪是什么_三轴陀螺仪在手机上的应用

    三轴陀螺仪是什么 陀螺仪英文名Gyroscope,是一种用来传感和维持方向的装置设备。陀螺仪是由一个位于轴心且可旋转的轮子构成。 陀螺仪一旦开始旋转,由于轮子的角动量,
    发表于 08-30 11:52 8219次阅读
    三轴<b class='flag-5'>陀螺仪</b>是什么_三轴<b class='flag-5'>陀螺仪</b>在手机上的应用

    三轴陀螺仪有什么用_三轴陀螺仪的作用

    陀螺仪敏感轴之间的不正交安装误差相关。相比于单轴传感器,三轴传感器的校准参数更多,校准过程更为复杂。目前,陀螺仪的标定通常采用位置标定和速率标定方法。 三轴陀螺仪的作用 三轴陀螺仪
    发表于 10-26 20:02 1.4w次阅读
    三轴<b class='flag-5'>陀螺仪</b>有什么用_三轴<b class='flag-5'>陀螺仪</b>的作用

    陀螺仪有什么用_陀螺仪的特性图解_陀螺仪的应用

    就用现在的智能手机来研究下陀螺仪的用处,之后还会介绍清楚陀螺仪的特性,看完大家就能完全理解陀螺仪了。
    发表于 12-01 15:27 9767次阅读

    MEMS陀螺仪技术原理_三轴陀螺仪技术原理

    三轴陀螺仪也叫“微机械陀螺仪”,而“微机械陀螺仪”也可称作“MEMS陀螺仪”,即同时测定6个方向的位置,移动轨迹,加速。
    发表于 12-01 16:17 1.5w次阅读
    MEMS<b class='flag-5'>陀螺仪</b>技术原理_三轴<b class='flag-5'>陀螺仪</b>技术原理

    浅谈MEMS陀螺仪技术 MEMS是否取代光纤陀螺仪技术

    MEMS陀螺仪也称电子式陀螺仪,就是一块芯片。 Iphone 4上的陀螺仪就是这种,主要作用是在GPS没有信号时,通过陀螺仪的作用仍然能够继续精确导航。
    发表于 07-30 11:21 1.3w次阅读

    光纤陀螺仪与旋转式陀螺仪的工作原理解析

    光纤陀螺仪(FOGs)与常用于玩具中的旋转式陀螺仪类似,因为这两种陀螺仪都能测量物体的旋转。但这两种陀螺仪的工作机制却不同:光纤陀螺仪内部没
    发表于 10-10 15:22 7802次阅读
    光纤<b class='flag-5'>陀螺仪</b>与旋转式<b class='flag-5'>陀螺仪</b>的工作原理解析

    工业和汽车级MEMS陀螺仪的应用

    目前,在陀螺仪应用领域,按精度细分的话,陀螺仪可分为商用陀螺仪、战术陀螺仪、导航陀螺仪、战略陀螺仪
    发表于 07-14 16:00 4017次阅读

    什么是MEMS陀螺仪

    Ericco的MEMS陀螺仪根据轴数分为单轴、双轴和三轴。它分为工业级、战术级(ER-MG-056、ER-MG-067)和导航级(ER-MG2-50/100、ER-MG2-300/400)。战术
    的头像 发表于 07-07 10:16 3045次阅读

    怎么解决陀螺仪角度漂移问题 三轴陀螺仪和六轴陀螺仪的区别

    陀螺仪角度漂移是指在使用陀螺仪时,由于各种误差和不完美的因素导致测量的角度随时间发生偏移。为了解决陀螺仪角度漂移问题,可以考虑以下几种方法。
    发表于 08-21 14:40 6242次阅读

    陀螺仪的基本组成 陀螺仪的工作原理 陀螺仪的作用

    陀螺仪的基本组成 陀螺仪的工作原理 陀螺仪的作用 陀螺仪和重力传感器有什么区别呢? 陀螺仪是一种测量和感知设备,可用于测量或检测物体的角速度
    的头像 发表于 12-07 11:26 1909次阅读

    手机陀螺仪失灵解决方法

    手机陀螺仪是一种用于感知和测量设备旋转、倾斜和方向的传感器。失灵的陀螺仪可能导致手机在运动控制、游戏和导航等应用中出现问题。下面将详细介绍陀螺仪失灵的原因和解决方法。 陀螺仪失灵的原因
    的头像 发表于 01-30 10:06 2w次阅读