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

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

3天内不再提示

LSM6DSO六轴传感器使用指南

CHANBAEK 来源:嵌入式Linux系统开发 作者:Jasonangel 2023-04-17 18:04 次阅读

博主最近在调试 lsm6dso,一款集合加速度和陀螺仪的模块,主要运用在手持设备中。

1、前言

LSM6DSO 是 ST 公司的六轴传感器,集成三轴加速度和三轴陀螺仪。

2、传感器特性

  1. 具有数字 I2C、SPI 和 MIPI I3C 串口标准输出,组合工作在高性能模式下功耗只要 0.55 mA。
  2. 满量程加速度范围:±2/±4/±8/±16 g,且角速率范围为 ±125/±250/±500/±1000/±2000 dps。
  3. 经过配置,LSM6DSO 可利用硬件识别出的自由落体事件、6D 方向、单击和双击感应、活动或不活动、唤醒事件,来生成中断信号
  4. SMD 封装的超小尺寸和重量使其成为手持便携式应用的理想选择,如智能手机物联网IoT)连接设备,穿戴,以及需要减小封装尺寸和重量的其他应用,尺寸:2.5 mm x 3 mm x 0.83 mm
  5. 支持 1.71V to 3.6V 供电

3、参考资料

ST 对于自己出的传感器,都会提供驱动 demo,放在 github,如下:

https://github.com/STMicroelectronics

其中分为不同的平台,有的是仅仅基于 C 语言的平台无关的驱动,有的是基于 STM32,有的是基于 Linux,有的是基于 Android,一开始学习的时候,建议大家下载平台无关的驱动:

图片

若后续大家想移植到 Linux、Android ,也可以在这里可以找到工程:

https://github.com/STMicroelectronics/STMems_Standard_C_drivers
https://github.com/STMicroelectronics/st-mems-android-linux-drivers-input
https://github.com/STMicroelectronics/STMems_Linux_IIO_drivers
https://github.com/STMicroelectronics/STMems_Android_Sensor_HAL_IIO

lsm6dso-pid 参考代码:

https://github.com/STMicroelectronics/STMems_Standard_C_drivers/tree/master/lsm6dso_STdC

arduino、micropython 参考代码:

https://github.com/arduino-libraries/Arduino_LSM6DSOX
https://github.com/micropython-Chinese-Community/mpy-lib/tree/master/sensor/LSM6DSO

数据手册下载,其中包含有中文应用手册:

https://www.st.com/zh/mems-and-sensors/lsm6dso.html

图片

4、引脚说明

一共 14 个 PIN 脚,每个引脚的详细说明可以参考数据手册。 总的来说就是 I2C 和 SPI 无法同时使用,因为它们有共用 PIN 脚。

图片

5、硬件模式

一般用模式 1,模式 2、模式 3、模式 4 比较复杂,可以外接传感器,摄像头等。

图片

6、I2C 读写地址

LSM6DSO 从机地址是 110101x ,最后一位 x 和一个 PIN 的状态有关系。 如果 SDO/SA0 是高,从机地址是 1101011。 如果 SDO/SA0 是低,从机地址是 1101010。

这个方案可以使得一路 I2C bus 挂两个 lsm6dso,同时使用。

加上读写位,总结如下:

图片

传输示意图如下:

图片图片

7、寄存器

该器件有 60+ 个寄存器,主要的几个如下:

1、设备 ID

只读,出厂已经固化在硬件里面了,可以通过读写这个寄存器,判断设备是否存在,通讯是否正常,设备的 ID 是 0x6C。

图片

2、加速度控制寄存器

这个寄存器可以设置加速度的量程、输出速率等;

图片图片

3、陀螺仪控制寄存器

这个寄存器可以设置陀螺仪的量程、输出速率等;

图片图片

4、状态寄存器

通过读取这个寄存器可以判断,传感器是否有新的数据。

图片

5、温度传感器

2个寄存器,输出的是有符号数据。

图片

6、陀螺仪数据传感器

总共 6 个寄存器,分 x、y、z 三轴的高位和低位,这里要注意,输出的是有符号数据。

图片

图片

图片

7、加速度数据传感器

总共 6 个寄存器,分 x、y、z 三轴的高位和低位,这里要注意,输出的是有符号数据。

图片

图片

图片

8、代码

博主用的是轮询去读数据,大家也可以配置成中断方式。 另外,博主是直接去各个数据寄存器去读数据,大家也可以配置成去器件 FIFO 中读数据。 该器件有 3Kbyte 的 FIFO,若使用压缩算法,可以达到 9Kbyte。

初始化部分:

i2c_init();
LSM6DSO_Check();
  
u8 LSM6DSO_Check(void)
{
 u8 temp;
 temp=LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_WHO_AM_I);
 if(temp==0X6C)
  return 0; 
 else
   return 1; 
}

LSM6DSO_WriteOneByte(LSM6DSO_ADDRESS,LSM6DSO_CTRL1_XL,ODR_XL_104Hz|FS_XL_2g);
LSM6DSO_WriteOneByte(LSM6DSO_ADDRESS,LSM6DSO_CTRL2_G,ODR_G_104Hz|FS_G_250);

读数据

while(1)
{
  status=LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_STATUS_REG);
  
  if(status & TEM_DATA_AVAILABLE)
  {
   temp_raw=LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_OUT_TEMP_L)|(LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_OUT_TEMP_H)<<8);
   temp_deg=temp_raw/TEMP_LSB_PER_DEG+TEMP_OFFSET_DEG;
   sprintf((char*)temperature,"temperature:%02f",temp_deg);
   LCD_ShowString(30,90,200,16,16,temperature);  
  }
  
  if(status & GYR_DATA_AVAILABLE)
  {
   gyr_x_raw = LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_OUTX_L_G)|(LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_OUTX_H_G)<<8);
   gyr_y_raw = LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_OUTY_L_G)|(LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_OUTY_H_G)<<8);
   gyr_z_raw = LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_OUTZ_L_G)|(LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_OUTZ_H_G)<<8);

   gyr_x = gyr_x_raw*GYR_LSB_250_PER;
   gyr_y = gyr_y_raw*GYR_LSB_250_PER;
   gyr_z = gyr_z_raw*GYR_LSB_250_PER;
   
   printf("Gyro:X:%02f mdps,Y:%02f mdps,Z:%02f mdps \\r\\n",gyr_x,gyr_y,gyr_z);
  }
  
  if(status & ACC_DATA_AVAILABLE)
  {
   acc_x_raw=LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_OUTX_L_A)|(LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_OUTX_H_A)<<8);
   acc_y_raw=LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_OUTY_L_A)|(LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_OUTY_H_A)<<8);
   acc_z_raw=LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_OUTZ_L_A)|(LSM6DSO_ReadOneByte(LSM6DSO_ADDRESS,LSM6DSO_OUTZ_H_A)<<8);

   acc_x=acc_x_raw*ACC_LSB_2G_PER;
   acc_y=acc_y_raw*ACC_LSB_2G_PER;
   acc_z=acc_z_raw*ACC_LSB_2G_PER;
   
   printf("Acc:X:%02f mg,Y:%02f mg,Z:%02f mg \\r\\n",acc_x,acc_y,acc_z);   
  }

寄存器定义

#define LSM6DSO_ADDRESS      0xD4

#define LSM6DSO_ID          0x6C

#define LSM6DSO_SDO_CRTL          0x02
#define LSM6DSO_FIFO_CTRL1        0x07  
#define LSM6DSO_FIFO_CTRL2        0x08
#define LSM6DSO_FIFO_CTRL3        0x09
#define LSM6DSO_FIFO_CTRL4        0x0A
#define LSM6DSO_COUNTER_BDR_REG1  0x0B
#define LSM6DSO_COUNTER_BDR_REG2  0x0C  
#define LSM6DSO_INT1_CTRL         0x0D
#define LSM6DSO_INT2_CTRL         0x0E
#define LSM6DSO_WHO_AM_I         0x0F
#define LSM6DSO_CTRL1_XL         0x10
  //bit[7:4]
typedef enum {
   ODR_XL_OFF                  = (0<<4),  
   ODR_XL_1Hz6_LOW_POWER_ONLY  = (11<<4),
   ODR_XL_12Hz5                = (1<<4),
   ODR_XL_26Hz                 = (2<<4),
   ODR_XL_52Hz                 = (3<<4),  
   ODR_XL_104Hz                = (4<<4),   
   ODR_XL_208Hz                = (5<<4),  
   ODR_XL_416Hz                = (6<<4),   
   ODR_XL_833Hz                = (7<<4), 
   ODR_XL_1k66Hz               = (8<<4), 
   ODR_XL_3k33Hz               = (9<<4), 
   ODR_XL_6k66Hz               = (10<<4),  
} lsm6dso_odr_xl_t;
  //bit[3:2]
typedef enum {
   FS_XL_2g                    = (0<<2),
   FS_XL_4g                    = (2<<2),
   FS_XL_8g                    = (3<<2),
   FS_XL_16g_SPIT_OIS_IU_FS    = (1<<2), /* check  XL_FS_MODE = ‘0’ in CTRL8_XL (17h) */
} lsm6dso_fs_xl_t;
#define ACC_LSB_2G_PER       0.061
#define ACC_LSB_4G_PER       0.122
#define ACC_LSB_8G_PER       0.244
#define ACC_LSB_16G_PER      0.488 

#define LSM6DSO_CTRL2_G     0x11
   //bit[7:4]
typedef enum {
   ODR_G_OFF                  = (0<<4),  
   ODR_G_12Hz5                = (1<<4),
   ODR_G_26Hz                 = (2<<4),
   ODR_G_52Hz                 = (3<<4),  
   ODR_G_104Hz                = (4<<4),   
   ODR_G_208Hz                = (5<<4),  
   ODR_G_416Hz                = (6<<4),   
   ODR_G_833Hz                = (7<<4), 
   ODR_G_1k66Hz               = (8<<4), 
   ODR_G_3k33Hz               = (9<<4), 
   ODR_G_6k66Hz               = (10<<4), 
   ODR_G_NOT_AVAILABLE        = (11<<4),
} lsm6dso_odr_g_t;
  //bit[3:2]
typedef enum {
   FS_G_250                   = (0<<2),
   FS_G_500                   = (1<<2),
   FS_G_1000                  = (2<<2),
   FS_G_2000                  = (3<<2),
} lsm6dso_fs_g_t;
    
#define GYR_LSB_250_PER        8.75
#define GYR_LSB_500_PER        17.50
#define GYR_LSB_1000_PER       35.0
#define GYR_LSB_2000_PER       70.0 
  
#define LSM6DSO_CTRL3_C         0x12
#define LSM6DSO_CTRL4_C         0x13
#define LSM6DSO_CTRL5_C        0x14
#define LSM6DSO_CTRL6_C        0x15
#define LSM6DSO_CTRL7_G          0x16
#define LSM6DSO_CTRL8_XL         0x17
#define LSM6DSO_CTRL9_XL         0x18
#define LSM6DSO_CTRL10_C         0x19
#define LSM6DSO_ALL_INT_SRC      0x1A
#define LSM6DSO_WAKE_UP_SRC      0x1B
#define LSM6DSO_TAP_SRC          0x1C
#define LSM6DSO_D6D_SRC          0x1D
#define LSM6DSO_STATUS_REG       0x1E
#define TEM_DATA_AVAILABLE   (1<<2)
#define GYR_DATA_AVAILABLE   (1<<1)
#define ACC_DATA_AVAILABLE   (1<<0)
  
#define LSM6DSO_OUT_TEMP_L       0x20
#define LSM6DSO_OUT_TEMP_H       0x21
#define TEMP_LSB_PER_DEG     256.0
#define TEMP_OFFSET_DEG      25

#define LSM6DSO_OUTX_L_G     0x22
#define LSM6DSO_OUTX_H_G     0x23
#define LSM6DSO_OUTY_L_G     0x24
#define LSM6DSO_OUTY_H_G     0x25
#define LSM6DSO_OUTZ_L_G     0x26
#define LSM6DSO_OUTZ_H_G     0x27

#define LSM6DSO_OUTX_L_A    0x28
#define LSM6DSO_OUTX_H_A     0x29
#define LSM6DSO_OUTY_L_A     0x2A
#define LSM6DSO_OUTY_H_A     0x2B
#define LSM6DSO_OUTZ_L_A     0x2C
#define LSM6DSO_OUTZ_H_A     0x2D
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 传感器
    +关注

    关注

    2522

    文章

    47984

    浏览量

    739682
  • 陀螺仪
    +关注

    关注

    44

    文章

    726

    浏览量

    97648
  • ST
    ST
    +关注

    关注

    32

    文章

    1093

    浏览量

    128125
  • 串口
    +关注

    关注

    14

    文章

    1483

    浏览量

    74480
  • 六轴传感器
    +关注

    关注

    1

    文章

    17

    浏览量

    16181
收藏 人收藏

    评论

    相关推荐

    线性NTC温度传感器使用指南

    线性NTC温度传感器使用指南 1.什么是线性NTC温度传感器
    发表于 01-14 08:52 2377次阅读

    LSM6DSR和LSM6DSO区别有多大?

    在开发LSM6DSR的软件,我有LSM6DSO的驱动代码,请问,LSM6DSR和LSM6DSO在开发方面区别大吗?我能否直接拿LSM6DSO
    发表于 03-11 08:09

    LSM6DSO评估板与SPI无法通信是何原因?如何解决

    我们一直在尝试为一个项目测试和调整 LSM6DSO 评估板 (STEVAL-MKI196V1),但在使用 SPI 与其通信时遇到了困难。当放置在 Profi-Mems 板
    发表于 12-15 06:34

    LSM6DSO中的ID无法检测到自由落体示例代码是什么原因呢

    大家好!我在带有 stm32l4 MCU 的定制板上安装了 LSM6DSO,我只使用 I2C 接口(我不使用中断)。我在 STMems 标准 C 驱动程序中使用 LSM6DSO 自由落体示例代码,我
    发表于 12-19 07:42

    我想知道lsm6dso传感器在什么情况下会重置呢?

    我正在为手表使用 lsm6dso 传感器。一开始,我使用以下函数来获取寄存器中的步骤。它在一个while循环中工作,可以正常工作。int32_t
    发表于 01-05 07:00

    LSM6DSO计步器如何设置?

    现在我正在使用 LSM6DSO 传感器计步功能。我发现它太敏感了,想改变它。我找到了四个计步器设置。它们是 ****_CMD_REG、****_DEB_STEPS_C
    发表于 01-09 07:28

    如何配置LSM6DSO并将其同步到树莓派?

    了 Unico GUI 程序,以配置我的惯性模块。当我打开它并选择我的惯性模块 (LSM6DSO) 时,然后我按“选择设备”,程序关闭。您需要知道它所连接的主板吗?因为我不知道惯性传感器连接到哪个主板。我得到
    发表于 01-12 09:20

    如何计算LSM6DSO度每秒满量程?

    在数据表中,它表​​示 LSM6DSO 中的陀螺仪在 +/-2000 dps 满量程时为 1LSb = 70 mdps。我很好奇这是如何获得的。对于带符号的 16 位数字,我得到 2000
    发表于 01-29 08:27

    MEMS LSM6DSD/LSM6DS3/LSM6DSO是否比LSM6DSR具有更好的“抗冲击性”?

    MEMS LSM6DSD、LSM6DS3、LSM6DSO 是否比 LSM6DSR 具有更好的“抗冲击性”?LSM6DSR数据表中找不到以下短
    发表于 02-02 09:21

    如何轻松进行lsm6dsolsm6dsox软件检测?

    我们为我们的开发使用两种类型的传感器lsm6dsolsm6dsox。有必要检测传感器 SW 的类型(无需打开设备)。这很困难,因为地址(我们使用 i2c)是相同的,
    发表于 02-03 11:24

    SPI的LSM6DSO问题如何处理?

    目前我们正在尝试在我们的项目中使用 LSM6DSO6 MEMS 传感器)。我们能够使用 ST 适配器板 STEVAL-MKI159V1 成功测试
    发表于 02-09 07:09

    LSM6DSO iNEMO惯性传感器模块相关的使用信息和应用提示

    LSM6DSO 是系统级封装的 3D 数字加速度计和 3D 数字陀螺仪,具有数字 I²C、SPI 和 MIPI I3CSM 串口标准输出,组合工作在高性能模式下功耗只要 0.55 mA。由于陀螺仪
    发表于 09-06 06:56

    LSM6DSO的应用笔记

    本文档旨在提供 ST LSM6DSO iNEMO 惯性传感器模块相关的使用信息和应用提示。LSM6DSO 是系统级封装的 3D 数字加速
    发表于 09-13 08:05

    线性NTC温度传感器使用指南

    线性NTC温度传感器使用指南
    发表于 06-30 19:39 1861次阅读

    工程师笔记|NUCLEO-G474RE 开发板扩展 LSM6DSO 实现 Data Fusion 演示

    的评估或工程演示时,往往需要快速地得到直观的评估效果。Unicleo-GUI 是针对运动 MEMS 和环境传感器扩展软件的 GUI,主要功能是演示 MEMS 传感器和算法。LSM6DSO 是一款具有
    的头像 发表于 11-27 18:30 1264次阅读