lsm6dsv16x
1、特性1.1、架构与数据处理三通道架构分别用于 UI、EIS、OIS 数据处理可编程有限状态机支持加速度计、陀螺仪、外部传感器高速数据处理最高 960Hz 采样率内置低功耗传感器融合算法集成机器学习运算内核可导出特征与滤波数据适配 AI 应用嵌入式自适应自配置ASC功能1.2、低功耗与常驻运行加速度计、陀螺仪支持 “永久在线” 工作模式功耗极低高性能组合模式下功耗仅 0.65mA供电规格模拟电源电压1.71V ~ 3.6V独立 IO 电源宽压区间1.08V ~ 3.6V1.3、传感器量程规格加速度计满量程可选±2g / ±4g / ±8g / ±16g这里的g 重力加速度1g ≈ 9.8 m/s²代表地球标准重力。 这是加速度计的满量程测量范围芯片可软件配置切换这四档量程。±2 g测量范围-19.6 ~ 19.6 m/s² 适合计步、姿态判断、手机平放 / 倾斜检测、日常 UI 翻转精度最高。±4 g测量范围-39.2 ~ 39.2 m/s² 适合轻度运动、走路慢跑、小幅晃动检测。±8 g测量范围-78.4 ~ 78.4 m/s² 适合跑步、跳跃、颠簸场景、防抖基础采集。±16 g测量范围-156.8 ~ 156.8 m/s² 适合剧烈震动、跌落检测、高速运动、工业冲击采集。芯片 ADC 总采样位数固定量程越小单 bit 分辨率越高测量越精细±2g灵敏度最高微小晃动都能识别双击、抬手亮屏±16g量程最大但微小加速度变化分辨能力最弱陀螺仪满量程可选±125 / ±250 / ±500 / ±1000 / ±2000 / ±4000 dpsdps degrees per second度每秒是陀螺仪的量程单位代表设备每秒旋转的角度。 这组参数是陀螺仪可配置的满量程测量范围用来检测物体旋转、转动动作。±125 dps量程最小、分辨率最高适合缓慢小幅转动手机屏幕翻转、日常姿态微调、UI 交互。±250 dps轻度转动适合普通手持设备日常姿态检测、慢速云台防抖。±500 dps手机常规拍摄 EIS 电子防抖、日常短视频拍摄。±1000 dps边走边拍、走路录像、小幅运动防抖。±2000 dps快速转动、跑步拍摄、运动镜头、手持云台大幅度摇摆。±4000 dps最大量程适合极速旋转、剧烈运动、快速甩动、航拍、高速运动拍摄能捕捉超大角度转动。量程越小如 ±125dps每 1bit 代表的角度变化极小微小转动都能精准捕捉防抖、姿态检测精度更高量程越大如 ±4000dps能测高速旋转但对细微转动的分辨能力会下降。g重力加速度测直线加速度、重力、震动、跌落、步数dps度 / 秒测旋转、转动、摇晃专门给 OIS 光学防抖、EIS 电子防抖提供数据。1.4、存储与接口智能 FIFO 缓冲区最大 4.5KB主通信接口SPI / I²C/ MIPI I3C® v1.1支持与主控数据同步辅助 SPI 接口输出陀螺仪、加速度计 OIS 防抖数据OIS 防抖功能可通过辅助 SPI、主接口SPI/I²C/MIPI I3C v1.1配置主接口独立 EIS 电子防抖通道配套专用滤波内置模拟集线器用于 ADC 采集与模拟输入数据处理1.5、运动 姿态检测功能高级计步套件步数检测、步数统计有效运动检测、倾斜检测标准中断触发源自由落体、唤醒、6 轴 / 4 轴姿态、单击、双击1.6、人机交互 UI 模块内置 Qvar 静电传感器支持触控交互单击、双击、三击、长按、左右滑动L/R–R/L swipe1.7、内置外设片内温度传感器Qvar 静电传感器UI 交互专用1.8、系统兼容性符合 Android 系统标准1.9、封装与环保标准小型化尺寸2.5 mm × 3 mm × 0.83 mmECOPACK 环保封装符合 RoHS 标准2、IIC接口2.1、接线这款芯片兼容iic和spi笔者这里使用的是iic接口图片来源春节不发货LSM6DSV16XTR模块六轴传感器,内置算法融合,AI应用-淘宝网接线如下VCC接3.3VGND接地CS接3.3V拉高是iic模式拉低是spi模式ADO/MISOSDO/SA0决定iic从机地址SDO/SA0接GND地址0X6ASDO/SA0接VCC地址0X6B必须固定电平不能悬空SCL/SCLKSCL/SPC、SDA/MOSISDA/SDI/SDO正常接iic主机对应的接口这里实物的接口名称和数据手册的接口名称不一样括号里面的是数据手册的名称数据手册这里描述了SDO/SA0接GND地址0X6ASDO/SA0接VCC地址0X6BLSM6DSV16X 作为 I2C 从机通信流程固定主机发起始信号 ST发送 7 位从地址 读写位等待芯片应答 SAK应答成功后主机发送8 位寄存器子地址 SUB要读 / 写的芯片内部寄存器地址比如 CTRL1、MLC 相关寄存器寄存器地址自动递增功能由寄存器CTRL3 (0x12)的 IF_INC 位控制。写操作R/W 位 0发送从地址 写位 → ACK → 寄存器子地址 → 连续发多字节数据总线方向不变直接写入对应寄存器。读操作R/W 位 1流程起始 ST → 从地址 (写) → ACK → 寄存器子地址 →重复起始信号 SR→ 再发从地址 (读) → 读取芯片返回的数据。通俗讲I2C 读传感器必须先发一次 “写地址” 指定寄存器再发重复起始切换读模式不能直接发读地址。列名含义Command操作类型Read读/ Write写SAD[6:1]芯片固定高 6 位从机地址固定二进制110101不可修改SAD[0] SA0最低位由硬件引脚SDO/SA0电平决定SA0 接 GND → 0SA0 接 3.3V (VDD) → 1R/WI2C 读写控制位0 写操作1 读操作SADR/W完整 8 位 I2C 总线传输字节二进制 十六进制场景 1SA0 接 GNDSAD [0]0Write 写操作SAD [6:1]110101 SAD [0]0 R/W0 二进制110101000xD4对应你说的从机地址 0x6A7 位地址是 0110101即 0x6A写字节 0x6A10xD4Read 读操作SAD [6:1]110101 SAD [0]0 R/W1 二进制110101010xD5读字节 0x6A 1 | 1 0xD5场景 2SA0 接 3.3VSAD [0]1Write 写操作SAD [6:1]110101 SAD [0]1 R/W0 二进制110101100xD6对应你说的从机地址 0x6B7 位地址 011010110x6B写字节 0x6B10xD6Read 读操作SAD [6:1]110101 SAD [0]1 R/W1 二进制110101110xD7读字节 0x6B 1 | 1 0xD7SA0/GND → 7 位地址0x6A写指令0xD4读指令0xD5SA0/VCC → 7 位地址0x6B写指令0xD6读指令0xD77 位从机地址软件驱动里配置的设备 ID0x6A / 0x6B8 位总线发送字节硬件 I2C 实际发出去的字节0xD4/D5/D6/D7是 7 位地址左移 1 位最低位填充 R/W 读写标记3、初始化这里以nRF54l15外接lsm6dsv16x为例SCL/SCLKSCL/SPC、SDA/MOSISDA/SDI/SDO正常接iic主机对应的接口硬件实现iic。一般调试这些芯片时先获取设备ID因此需要查询设备id存放的地址整理一下所需要的寄存器地址#define LSM6DSV16X_I2C_ADDR 0x6A // 对应原理图SA0/SDO下拉 #define LSM6DSV16X_WHO_AM_I 0x0F // 设备ID寄存器默认0x70 #define LSM6DSV16X_CTRL1 0x10 // 启动加速度计 #define LSM6DSV16X_CTRL2 0x11 // 启动陀螺仪 #define LSM6DSV16X_CTRL3 0x12 // BDU/IF_INC #define LSM6DSV16X_CTRL6 0x15 // 陀螺仪量程/低通滤波器配置 #define LSM6DSV16X_CTRL8 0x17 // 加速度计量程/低通滤波器配置 #define LSM6DSV16X_TEMP_OUT_L 0x20 // 温度数据低8位 #define LSM6DSV16X_TEMP_OUT_H 0x21 // 温度数据高8位 #define LSM6DSV16X_GYRO_XOUT_L 0x22 // 陀螺仪X轴数据低8位 #define LSM6DSV16X_GYRO_XOUT_H 0x23 // 陀螺仪X轴数据高8位 #define LSM6DSV16X_GYRO_YOUT_L 0x24 // 陀螺仪Y轴数据低8位 #define LSM6DSV16X_GYRO_YOUT_H 0x25 // 陀螺仪Y轴数据高8位 #define LSM6DSV16X_GYRO_ZOUT_L 0x26 // 陀螺仪Z轴数据低8位 #define LSM6DSV16X_GYRO_ZOUT_H 0x27 // 陀螺仪Z轴数据高8位 #define LSM6DSV16X_ACCEL_XOUT_L 0x28 // 加速度X轴数据低8位 #define LSM6DSV16X_ACCEL_XOUT_H 0x29 // 加速度X轴数据高8位 #define LSM6DSV16X_ACCEL_YOUT_L 0x2A // 加速度Y轴数据低8位 #define LSM6DSV16X_ACCEL_YOUT_H 0x2B // 加速度Y轴数据高8位 #define LSM6DSV16X_ACCEL_ZOUT_L 0x2C // 加速度Z轴数据低8位 #define LSM6DSV16X_ACCEL_ZOUT_H 0x2D // 加速度Z轴数据高8位 #define LSM6DSV16X_WHO_AM_I_VAL 0x70 // 期望的WHO_AM_I返回值先列出这么多阅读数据手册后初始化的时候需要完成以下几步1配置总线行为: BDU IF_INC必须最先配置2设置陀螺仪量程3设置加速度计量程4启动加速度计5启动陀螺仪3.1、配置总线行为寄存器说明如下Bit7BOOT内存重启默认值为01是重启内存数据Bit6BDUBlock Data Update数据锁存更新默认值为1高低字节全部读完后才更新下一组采样数据Bit2IF_INC寄存器地址自动自增默认值为1I2C/SPI/MIPI I3C 多字节读写时地址自动 1Bit0SW_RESET软件复位默认值为0软件全局复位所有控制寄存器恢复出厂默认值写入 1 后硬件自动清零该位所以这里需要1开启 BDU 数据锁存保证 16 位传感器数据读取完整不错乱2开启 I2C 寄存器地址自动自增支持连续批量读写寄存器3关闭 BOOT 重载、关闭软件复位、所有保留位清零即向0x12地址写入0100 0100// 后期用宏定义替换 lsm6dsv16x_write(0x12, 0x44);3.2、设置陀螺仪量程Bit6~Bit4LPF1_G_BW [2:0] 陀螺仪一阶低通滤波带宽选择数值越小滤波越强、噪声抑制越好但信号延迟变大。LPF1_G_BW[2:0]滤波特性常用场景推荐000通带宽高频保留多噪声大适合高速运动采集001 / 010 / 011中等滤波平衡噪声与响应速度100中强滤波运动识别 MLC 常规推荐档位101强滤波小幅抖动抑制明显110极强滤波仅保留极低频率运动111最强滤波适合静止、慢动作识别Bit3~Bit0FS_G [3:0] 陀螺仪量程选择Full ScaleFS_G[3:0]陀螺仪量程特殊说明0000±125 dps默认量程低速姿态检测0001±250 dps日常人体运动首选0010±500 dps快速转身、手部动作0011±1000 dps大幅度快速旋转0100±2000 dps高速旋转场景1100±4000 dps极限高速必须关闭 OIS 防抖功能其余编码保留禁止配置如果不需要滤波设置±500 dps的量程这里向0x15地址写入0000 0010// 后期用宏定义替换 lsm6dsv16x_write(0x15, 0x02);3.3、设置加速度计量程Bit7~Bit5HP_LPF2_XL_BW [2:0] 加速度二阶滤波带宽选择Bit3XL_DUAL_EN 加速度双通道模式Bit1~Bit0FS_XL [1:0] 加速度计量程选择FS_XL[1:0]量程适用场景00±2 g姿态、倾角、缓慢人体运动MLC 首选分辨率最高01±4 g日常行走、手部动作10±8 g跑跳、剧烈运动11±16 g冲击、跌落检测如果这里只设置加速度计量程为±8 g则向0x17写入0000 0010// 后期用宏定义替换 lsm6dsv16x_write(0x17, 0x02);3.4、启动加速度计Bit6~Bit4 OP_MODE_XL [2:0] 加速度计工作模式编码模式名称特性 MLC 适用建议000High-performance mode高性能默认噪声最低、采样精度最高MLC 运动识别首选功耗中等001High-accuracy ODR mode高精度采样采样时序更稳定功耗略高于高性能模式010保留禁止配置011ODR-triggered mode采样触发模式外部信号触发采样普通 I2C 轮询场景不用100Low-power mode 12 次均值低功耗低功耗2 次采样平均噪声小幅上升101Low-power mode 24 次均值低功耗更低功耗4 次均值平滑更强、延迟变大110Low-power mode 38 次均值低功耗最低功耗8 次均值适合长待机静止检测111Normal mode标准模式性能、功耗折中噪声高于高性能模式Bit3~Bit0 ODR_XL [3:0] 加速度输出采样率ODR_XL[3:0]输出频率 (Hz)支持的工作模式0000断电 Power-down全部模式通用休眠关闭加速度00011.875仅低功耗模式00107.5高性能 / 标准模式001115低功耗 / 高性能 / 标准010030低功耗 / 高性能 / 标准010160低功耗 / 高性能 / 标准0110120低功耗 / 高性能 / 标准0111240低功耗 / 高性能 / 标准1000480高性能 / 标准1001960高性能 / 标准10101.92k高性能 / 标准10113.84k仅高性能模式11007.68k仅高性能模式其余编码保留禁止配置这里选择加速度计高性能模式、加速度输出采样率 120Hz向0x10写入0000 0110// 后期用宏定义替换 lsm6dsv16x_write(0x10, 0x06);3.5、启动陀螺仪OP_MODE_G [2:0] 陀螺仪工作模式Bit6~Bit4编码模式说明 MLC 选型000High-performance mode默认高性能噪声最低MLC 运动识别首选功耗中等001High-accuracy ODR mode采样时序更精准功耗略高010保留禁止配置011ODR-triggered mode外部触发采样普通 I2C 轮询不用100Sleep mode陀螺仪休眠仅保留基础电路101Low-power mode低功耗数据均值平滑噪声上升110 / 111保留禁止配置ODR_G [3:0] 陀螺仪输出采样率Bit3~Bit0ODR_G[3:0]频率支持模式0000Power-down 断电全部模式通用关闭陀螺仪00017.5 Hz低功耗 / 高性能001015 Hz低功耗 / 高性能001130 Hz低功耗 / 高性能010060 Hz低功耗 / 高性能0101120 Hz低功耗 / 高性能MLC 步态推荐0110240 Hz低功耗 / 高性能1000480 Hz仅高性能1001960 Hz仅高性能10101.92 kHz仅高性能10113.84 kHz仅高性能11007.68 kHz仅高性能其余编码保留禁止配置这里选择陀螺仪高性能模式、陀螺仪输出采样率 120Hz向0x11写入0000 0101// 后期用宏定义替换 lsm6dsv16x_write(0x11, 0x05);3.6、读加速度计、陀螺仪数据读高位、低位再或起来即可也可连续读地址连续不再赘述。4、完整代码4.1、lsm6dsv16x.h#ifndef LSM6DSV16X_H #define LSM6DSV16X_H #include stdint.h #define LSM6DSV16X_I2C_ADDR 0x6A // 对应原理图SA0/SDO下拉 #define LSM6DSV16X_WHO_AM_I 0x0F // 设备ID寄存器默认0x70 #define LSM6DSV16X_CTRL1 0x10 // 启动加速度计 #define LSM6DSV16X_CTRL2 0x11 // 启动陀螺仪 #define LSM6DSV16X_CTRL3 0x12 // BDU/IF_INC #define LSM6DSV16X_CTRL6 0x15 // 陀螺仪量程/低通滤波器配置 #define LSM6DSV16X_CTRL8 0x17 // 加速度计量程/低通滤波器配置 #define LSM6DSV16X_TEMP_OUT_L 0x20 // 温度数据低8位 #define LSM6DSV16X_TEMP_OUT_H 0x21 // 温度数据高8位 #define LSM6DSV16X_GYRO_XOUT_L 0x22 // 陀螺仪X轴数据低8位 #define LSM6DSV16X_GYRO_XOUT_H 0x23 // 陀螺仪X轴数据高8位 #define LSM6DSV16X_GYRO_YOUT_L 0x24 // 陀螺仪Y轴数据低8位 #define LSM6DSV16X_GYRO_YOUT_H 0x25 // 陀螺仪Y轴数据高8位 #define LSM6DSV16X_GYRO_ZOUT_L 0x26 // 陀螺仪Z轴数据低8位 #define LSM6DSV16X_GYRO_ZOUT_H 0x27 // 陀螺仪Z轴数据高8位 #define LSM6DSV16X_ACCEL_XOUT_L 0x28 // 加速度X轴数据低8位 #define LSM6DSV16X_ACCEL_XOUT_H 0x29 // 加速度X轴数据高8位 #define LSM6DSV16X_ACCEL_YOUT_L 0x2A // 加速度Y轴数据低8位 #define LSM6DSV16X_ACCEL_YOUT_H 0x2B // 加速度Y轴数据高8位 #define LSM6DSV16X_ACCEL_ZOUT_L 0x2C // 加速度Z轴数据低8位 #define LSM6DSV16X_ACCEL_ZOUT_H 0x2D // 加速度Z轴数据高8位 #define LSM6DSV16X_WHO_AM_I_VAL 0x70 // 期望的WHO_AM_I返回值 /* ------------------------------------------------------------------ */ /* CTRL1 — bit[6:4]OP_MODE_XL[2:0], bit[3:0]ODR_XL[3:0] */ /* ------------------------------------------------------------------ */ #define LSM6DSV16X_OP_MODE_HIGH_PERF (0x00 4) /* 000: high-performance (default) */ #define LSM6DSV16X_OP_MODE_NORMAL (0x07 4) /* 111: normal mode */ #define LSM6DSV16X_ODR_XL_POWER_DOWN 0x00 #define LSM6DSV16X_ODR_XL_15HZ 0x03 #define LSM6DSV16X_ODR_XL_30HZ 0x04 #define LSM6DSV16X_ODR_XL_60HZ 0x05 #define LSM6DSV16X_ODR_XL_120HZ 0x06 #define LSM6DSV16X_ODR_XL_240HZ 0x07 /* ------------------------------------------------------------------ */ /* CTRL2 — bit[6:4]OP_MODE_G[2:0], bit[3:0]ODR_G[3:0] */ /* ------------------------------------------------------------------ */ #define LSM6DSV16X_ODR_G_POWER_DOWN 0x00 #define LSM6DSV16X_ODR_G_15HZ 0x02 #define LSM6DSV16X_ODR_G_30HZ 0x03 #define LSM6DSV16X_ODR_G_60HZ 0x04 #define LSM6DSV16X_ODR_G_120HZ 0x05 #define LSM6DSV16X_ODR_G_240HZ 0x06 /* ------------------------------------------------------------------ */ /* CTRL6 (0x15) — bit[3:0]FS_G[3:0] 陀螺仪量程 */ /* ------------------------------------------------------------------ */ #define LSM6DSV16X_FS_G_125DPS 0x00 /* ±125 dps */ #define LSM6DSV16X_FS_G_250DPS 0x01 /* ±250 dps */ #define LSM6DSV16X_FS_G_500DPS 0x02 /* ±500 dps */ #define LSM6DSV16X_FS_G_1000DPS 0x03 /* ±1000 dps */ #define LSM6DSV16X_FS_G_2000DPS 0x04 /* ±2000 dps */ /* ------------------------------------------------------------------ */ /* CTRL8 (0x17) — bit[1:0]FS_XL[1:0] 加速度计量程 */ /* ------------------------------------------------------------------ */ #define LSM6DSV16X_FS_XL_2G 0x00 /* ±2g */ #define LSM6DSV16X_FS_XL_4G 0x01 /* ±4g */ #define LSM6DSV16X_FS_XL_8G 0x02 /* ±8g */ #define LSM6DSV16X_FS_XL_16G 0x03 /* ±16g */ /** * brief 通用控制 * BDU1: 读完整对才更新输出寄存器防撕裂 * IF_INC1: 连续读时地址自动递增burst read 必须置位 */ #define LSM6DSV16X_CTRL3_BDU (1 6) #define LSM6DSV16X_CTRL3_IF_INC (1 2) /** * brief lsm6dsv16x初始化函数 */ void lsm6dsv16x_init(void); /** * brief 指定地址读数据 * param reg_address 指定的地址 * return 读出的数据 */ uint8_t lsm6dsv16x_read(uint8_t reg_address); /** * brief 指定地址读数据 * param reg_address 指定的地址 * param data 写入的数据 */ void lsm6dsv16x_write(uint8_t reg_address, uint8_t data); /** * brief 获取设备ID */ uint8_t lsm6dsv16x_get_id(void); /** * brief 获取数据寄存器的值 * param acc_x 加速度寄存器x轴数据LSB 0.244 mg/LSB±8g 量程 * param acc_y 加速度寄存器y轴数据 * param acc_z 加速度寄存器z轴数据 * param gyro_x 陀螺仪寄存器x轴数据LSB 17.5 mdps/LSB±500dps 量程 * param gyro_y 陀螺仪寄存器y轴数据 * param gyro_z 陀螺仪寄存器z轴数据 * param temp 温度传感器的数据°C raw / 256.0f 25.0f */ void lsm6dsv16x_get_data(int16_t *acc_x, int16_t *acc_y, int16_t *acc_z, int16_t *gyro_x, int16_t *gyro_y, int16_t *gyro_z, int16_t *temp); #endif注加速度、陀螺仪的高性能模式编码都是000移位4后数值完全一致因此我混着用了4.2、lsm6dsv16x.c#include lsm6dsv16x.h #include zephyr/kernel.h #include zephyr/device.h #include zephyr/drivers/i2c.h #include zephyr/logging/log.h LOG_MODULE_REGISTER(lsm6dsv16x, LOG_LEVEL_DBG); #define I2C_NODE DT_NODELABEL(lsm6dsv16x) static const struct i2c_dt_spec dev_i2c I2C_DT_SPEC_GET(I2C_NODE); /** * brief lsm6dsv16x初始化函数 */ void lsm6dsv16x_init(void) { if (!device_is_ready(dev_i2c.bus)) { LOG_ERR(I2C bus %s not ready, dev_i2c.bus-name); return; } uint8_t id lsm6dsv16x_get_id(); if (id ! LSM6DSV16X_WHO_AM_I_VAL) { LOG_ERR(WHO_AM_I mismatch: got 0x%02X, expect 0x%02X, id, LSM6DSV16X_WHO_AM_I_VAL); return; } LOG_INF(WHO_AM_I OK: 0x%02X, id); // 配置总线行为: BDU IF_INC必须最先配置 lsm6dsv16x_write(LSM6DSV16X_CTRL3, LSM6DSV16X_CTRL3_BDU | LSM6DSV16X_CTRL3_IF_INC); // 设置陀螺仪量程: 陀螺仪量程 ±500dps lsm6dsv16x_write(LSM6DSV16X_CTRL6, LSM6DSV16X_FS_G_500DPS); // 设置加速度计量程: 加速度计量程 ±8g lsm6dsv16x_write(LSM6DSV16X_CTRL8, LSM6DSV16X_FS_XL_8G); // 启动加速度计: 加速度计 high-performance 120Hz lsm6dsv16x_write(LSM6DSV16X_CTRL1, LSM6DSV16X_OP_MODE_HIGH_PERF | LSM6DSV16X_ODR_XL_120HZ); // 启动陀螺仪: 陀螺仪 high-performance 120Hz lsm6dsv16x_write(LSM6DSV16X_CTRL2, LSM6DSV16X_OP_MODE_HIGH_PERF | LSM6DSV16X_ODR_G_120HZ); LOG_INF(lsm6dsv16x init done); } /** * brief 指定地址读数据 * param reg_address 指定的地址 * return 读出的数据 */ uint8_t lsm6dsv16x_read(uint8_t reg_address) { uint8_t data 0; int ret i2c_reg_read_byte_dt(dev_i2c, reg_address, data); if (ret ! 0) { LOG_ERR(i2c_reg_read_byte_dt failed: %d, ret); return 0; } return data; } /** * brief 指定地址读数据 * param reg_address 指定的地址 * param data 写入的数据 */ void lsm6dsv16x_write(uint8_t reg_address, uint8_t data) { int ret i2c_reg_write_byte_dt(dev_i2c, reg_address, data); if (ret ! 0) { LOG_ERR(i2c_reg_write_byte_dt failed: %d, ret); } } /** * brief 获取设备ID */ uint8_t lsm6dsv16x_get_id(void) { return lsm6dsv16x_read(LSM6DSV16X_WHO_AM_I); } /** * brief 获取数据寄存器的值 * param acc_x 加速度寄存器x轴数据LSB 0.244 mg/LSB±8g 量程 * param acc_y 加速度寄存器y轴数据 * param acc_z 加速度寄存器z轴数据 * param gyro_x 陀螺仪寄存器x轴数据LSB 17.5 mdps/LSB±500dps 量程 * param gyro_y 陀螺仪寄存器y轴数据 * param gyro_z 陀螺仪寄存器z轴数据 * param temp 温度传感器的数据°C raw / 256.0f 25.0f */ void lsm6dsv16x_get_data(int16_t *acc_x, int16_t *acc_y, int16_t *acc_z, int16_t *gyro_x, int16_t *gyro_y, int16_t *gyro_z, int16_t *temp) { // uint8_t data_high, data_low; // data_high lsm6dsv16x_read(LSM6DSV16X_ACCEL_XOUT_H); // 读取加速度寄存器X轴的高8位 // data_low lsm6dsv16x_read(LSM6DSV16X_ACCEL_XOUT_L); // 读取加速度寄存器X轴的低8位 // *acc_x (data_high 8) | data_low; // 通过指针返回回去 // data_high lsm6dsv16x_read(LSM6DSV16X_ACCEL_YOUT_H); // 读取加速度寄存器y轴的高8位 // data_low lsm6dsv16x_read(LSM6DSV16X_ACCEL_YOUT_L); // 读取加速度寄存器y轴的低8位 // *acc_y (data_high 8) | data_low; // 通过指针返回回去 // data_high lsm6dsv16x_read(LSM6DSV16X_ACCEL_ZOUT_H); // 读取加速度寄存器z轴的高8位 // data_low lsm6dsv16x_read(LSM6DSV16X_ACCEL_ZOUT_L); // 读取加速度寄存器z轴的低8位 // *acc_z (data_high 8) | data_low; // 通过指针返回回去 // data_high lsm6dsv16x_read(LSM6DSV16X_GYRO_XOUT_H); // 读取陀螺仪寄存器x轴的高8位 // data_low lsm6dsv16x_read(LSM6DSV16X_GYRO_XOUT_L); // 读取陀螺仪寄存器x轴的低8位 // *gyro_x (data_high 8) | data_low; // 通过指针返回回去 // data_high lsm6dsv16x_read(LSM6DSV16X_GYRO_YOUT_H); // 读取陀螺仪寄存器y轴的高8位 // data_low lsm6dsv16x_read(LSM6DSV16X_GYRO_YOUT_L); // 读取陀螺仪寄存器y轴的低8位 // *gyro_y (data_high 8) | data_low; // 通过指针返回回去 // data_high lsm6dsv16x_read(LSM6DSV16X_GYRO_ZOUT_H); // 读取陀螺仪寄存器z轴的高8位 // data_low lsm6dsv16x_read(LSM6DSV16X_GYRO_ZOUT_L); // 读取陀螺仪寄存器z轴的低8位 // *gyro_z (data_high 8) | data_low; // 通过指针返回回去 // data_high lsm6dsv16x_read(LSM6DSV16X_TEMP_OUT_H); // 读温度的高8位 // data_low lsm6dsv16x_read(LSM6DSV16X_TEMP_OUT_L); // 读温度的低8位 // *temp (data_high 8) | data_low; /* * LSM6DSV16X 输出寄存器从 0x20 开始连续排列IF_INC1 * [0x20~0x21] TEMP * [0x22~0x27] GYRO XYZ * [0x28~0x2D] ACCEL XYZ * 共 14 字节一次 burst 读完。 * * 与MPU6050不同这里是小端低字节在低地址 */ uint8_t buf[14] {0}; int ret i2c_burst_read_dt(dev_i2c, LSM6DSV16X_TEMP_OUT_L, buf, sizeof(buf)); if (ret ! 0) { LOG_ERR(burst read failed: %d, ret); return; } /* 小端拼装 */ *temp (int16_t)(buf[1] 8 | buf[0]); /* TEMP */ *gyro_x (int16_t)(buf[3] 8 | buf[2]); /* GYRO X */ *gyro_y (int16_t)(buf[5] 8 | buf[4]); /* GYRO Y */ *gyro_z (int16_t)(buf[7] 8 | buf[6]); /* GYRO Z */ *acc_x (int16_t)(buf[9] 8 | buf[8]); /* ACC X */ *acc_y (int16_t)(buf[11] 8 | buf[10]); /* ACC Y */ *acc_z (int16_t)(buf[13] 8 | buf[12]); /* ACC Z */ }4.3、设备树i2c21 { status okay; clock-frequency I2C_BITRATE_STANDARD; // 100kHz pinctrl-0 i2c21_default; pinctrl-1 i2c21_sleep; pinctrl-names default, sleep; zephyr,concat-buf-size 257; lsm6dsv16x: lsm6dsv16x6a { compatible st,lsm6dsv16x, i2c_device; reg 0x6a; status okay; }; }; pinctrl { // iic21 i2c21_default: i2c21_default { group1 { // 按实际接线修改 psels NRF_PSEL(TWIM_SCL, x, y), NRF_PSEL(TWIM_SDA, x, y); bias-pull-up; nordic,drive-mode NRF_DRIVE_S0D1; }; }; i2c21_sleep: i2c21_sleep { group1 { // 按实际接线修改 psels NRF_PSEL(TWIM_SCL, x, y), NRF_PSEL(TWIM_SDA, x, y); low-power-enable; }; }; };4.4、main.c#include zephyr/kernel.h #include zephyr/drivers/spi.h #include zephyr/devicetree.h #include lsm6dsv16x.h #include zephyr/logging/log.h void test02() { lsm6dsv16x_init(); uint8_t device_id lsm6dsv16x_get_id(); LOG_INF(MPU6050s device is 0x%02x\n, device_id); int16_t acc_x, acc_y, acc_z, gyro_x, gyro_y, gyro_z, temp; // 1. 读取原始数据 lsm6dsv16x_get_data(acc_x, acc_y, acc_z, gyro_x, gyro_y, gyro_z, temp); LOG_INF(acc: x %d, y %d, z %d | gyro: x %d, y %d, z %d | temp %d\n, acc_x, acc_y, acc_z, gyro_x, gyro_y, gyro_z, temp); } int main(void) { while (1) { test02(); k_msleep(1000); LOG_INF(running - test ver 1.0); } return 0; }