ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

LSM6DS3六轴传感器实战:从寄存器配置到低功耗可穿戴方案

LSM6DS3六轴传感器实战:从寄存器配置到低功耗可穿戴方案 从去年开始我手上的几个可穿戴项目几乎都换上了 LSM6DS3原因不复杂它把 3D 加速度计和 3D 陀螺仪塞进一颗 3mm x 3mm 的封装里还支持“始终开启”的低功耗工作模式这让做 TWS 耳机、智能手环、姿态追踪标签这类设备的方案省了不少事。最关键的是这颗传感器的硬件设计和驱动代码都已经很成熟哪怕你之前没摸过六轴传感器照着本文的思路也能在半天内把数据跑稳。这篇应用笔记不是数据手册的翻译而是把我从原理图设计到寄存器配置再到实际产品调试的完整链路整理成文适合正在选型、刚拿到开发板、或者已经在项目里遇到“数据乱飘”“中断不触发”“功耗压不下来”这类问题的朋友。1. 为什么“始终开启”在可穿戴产品里这么值钱先聊一个看起来很基础但很多人没有真正想透的点IMU 为什么要强调 Always-on我用一个很实际的场景说明。做智能门磁或者跌倒检测手环时产品要求主控 MCU 尽可能多地睡在低功耗模式里只有发生“有意义的事件”才醒来处理数据。传统方案里如果 MCU 必须每隔 10ms 醒来读一次传感器数据再算姿态那系统功耗基本被 MCU 的空转耗光了。而 LSM6DS3 这一类带内部状态机的传感器可以在 MCU 完全睡死的情况下自己完成数据采样、阈值判断、甚至简单的运动识别等检测到脚步、抬腕、撞击或者自由落体时再通过中断引脚把 MCU 叫醒。你算一笔账就明白了。LSM6DS3 在 1.6Hz 低功耗模式下加速度计加陀螺仪的典型电流大约是 0.36mA具体会因量程、ODR 和电源电压略有差异而 MCU 若保持全速运行即使只开一个 I2C 外设电流也常常在 5-10mA 以上。如果设备 95% 时间处于待机只有 5% 时间做算法处理用中断唤醒方案可以把系统平均功耗压掉一个数量级。这就是“始终开启”的价值它不是一颗传感器的噱头而是整套低功耗架构的基础。选型上市面上同类的选择其实不少。如果你只做 3D 加速度计功能型号里带“A”后缀或者更小的封装可以省成本如果项目对陀螺仪的零偏稳定性和温漂要求更高则要看 LSM6DSO 或 LSM6DSV 系列。但 LSM6DS3 的优势在生态成熟度和产能稳定性毕竟 ST 这颗料在穿戴设备领域铺货量很大原厂配套的驱动和应用笔记资料也全遇到疑难杂症时搜一圈基本都有答案。2. 上手前必须搞懂的三组核心概念2.1 量程、分辨率与灵敏度别只看“16g/2000dps”LSM6DS3 的加速度计支持 ±2/±4/±8/±16g陀螺仪支持 ±125/±250/±500/±1000/±2000dps。很多人以为量程越大越好实际不然——量程越大单位 LSB 对应的物理量越大静态噪声和微弱信号的分辨能力就越差。以加速度计为例各量程对应的灵敏度即每 LSB 代表的毫 g 数是这样的量程灵敏度mg/LSB典型应用场景±2g0.061倾角检测、姿态参考、精确运动分析±4g0.122普通跌倒检测、计步±8g0.244动态冲击、动作识别±16g0.488剧烈撞击、跌落检测我自己的习惯是凡是需要算倾角、算姿态的算法加速度计一律先选 ±2g因为倾角分辨率最高且日常设备根本不会出现超过 2g 的静态加速度。只有做碰撞检测时才会把量程拨到 ±16g让剧烈冲击不至于削顶。陀螺仪类似航向姿态参考系统通常用 ±250dps 或 ±500dps做游戏手柄、云台的手动转动检测才需要更高量程。你要明白量程只是满幅刻度不是精度承诺选高了数据会变得粗糙。2.2 ODR 与功耗的权衡以及“陀螺仪可以更省电”这件事ODROutput Data Rate是传感器内部产生新数据的频率。LSM6DS3 的加速度计 ODR 可以从 1.6Hz 一直开到 6.66kHz陀螺仪也能到 6.66kHz但别忘了每开一档频率电流都会肉眼可见地往上走。数据手册里标注的功耗一般是在低 ODR 下的典型值当你把两个传感器都开到 833Hz 甚至更高时电流可能逼近 1.5mA这在电池类产品里几乎不可接受。这里有一个很反直觉的点陀螺仪在低功耗场景下往往可以比加速度计配置得更“低频”甚至直接关闭。很多静态或者缓变的应用比如倾角检测、震动监测根本不需要陀螺仪输出只有动态姿态才需要它。所以我在做超低功耗设备时会先把加速度计维持在 1.6Hz 或 12.5Hz 作为“环境感知”一旦判断有运动再动态把陀螺仪切到 104Hz 或 208Hz。这个思路在 ST 的驱动里也有现成的 API后面我会给出一段可执行的例子。2.3 FIFO 和中断把“每毫秒读数据”变成“攒一批再读”如果你还是让 MCU 每 10ms 就去读一次传感器寄存器那“始终开启”的意义就削弱了一半。LSM6DS3 内部带一个 8KB 的 FIFO先进先出缓存传感器可以按设定 ODR 持续填充数据MCU 只需要每隔一段时间把 FIFO 里的数据“打包”读走其余时间继续睡觉。这个机制能大幅降低 I2C 总线唤醒次数和 MCU 运行时长。与之配合的是传感器中断。ST 在 LSM6DS3 里做了一个可灵活配置的中断路径INT1 和 INT2 两个引脚都可以路由到 FIFO 水印、数据就绪、唤醒检测、步数计、倾斜检测等多种事件。设计产品时你完全可以让传感器在检测到“动作超过阈值”时才拉高 INT1MCU 从 deep sleep 醒来后先批量读 FIFO处理完再继续睡。这套模型几乎贯穿所有可穿戴设备的低功耗软件架构。3. 硬件设计不踩坑供电、总线和中断引脚3.1 供电与去耦一些小细节决定稳定性LSM6DS3 的主供电 VDD 支持 1.71V 到 3.6VIO 供电 VDD_IO 也支持 1.71V 到 3.6V。设计时注意 VDD_IO 不应高于 VDD否则可能出现片上电平转换器工作异常。最稳妥的做法是让 VDD 和 VDD_IO 都接同一个 1.8V 或 3.3V 电源轨并各放一个 100nF 去耦电容尽量靠近 VDD 引脚。很多人在 LSM6DS3 上遇到“数据偶尔跳变”的问题排到最后发现是电源纹波太大。因为 MEMS 传感器内部是一个极微小的电容检测结构电源毛刺会直接耦合进模拟前端。我的习惯是在 VDD 上再加一个 1-10uF 的钽电容或者陶瓷电容并在 PCB 布局时让 GND 引脚就近打过孔接到主地平面。另外如果系统里存在射频天线或者马达要特别注意传感器不要铺在强干扰源正下方这会省去后面很多调噪声的时间。3.2 用 I2C 还是 SPI先看 PCB 走线和引脚复用LSM6DS3 同时支持 I2C最高 400kHz和 SPI最高 10MHz。I2C 只需要 SDA 和 SCL 两根线市面上绝大多数 MCU 都有硬件 I2C 外设接线最省SPI 则有 MISO/MOSI/SCLK/CS 四根线适合数据量大、需要更快吞吐率的场景。实际项目里如果只是跑 100Hz 的频率I2C 完全够用还能省两个 GPIO。但有一个坑必须提示I2C 模式时 SDx/SA0 引脚的接法决定了从机地址。把 SA0 拉低地址是 0x6B拉高地址是 0x6A。很多人在原厂 demo 板和高低温箱里跑得好好的一到自己画板子就发现扫描不到设备八成就是 SA0 被悬空了或者跟某个 GPIO 复用冲突。设计时别把 SA0 留成浮空直接接一个 10k 电阻到 GND一劳永逸。SPI 模式下原厂一般推荐用 CS 引脚做硬件片选如果你想让两根总线兼容可以保留 I2C 引脚并通过寄存器切换但成本是电路复杂度和潜在误触发风险。我的建议是能固定一种总线就固定一种别为了“以后可能升级”把两个接口都引出来这只会增加 BOM 和调试难度。3.3 中断引脚的规划和路由表LSTM6DS3 的 INT1 和 INT2 并不只是“两根中断线”而是一个可编程路由表。INT1_CTRL地址 0x0D和 INT2_CTRL地址 0x0E里分别置位对应 bit就能决定“步数计中断”“FIFO 满”“唤醒检测”“倾斜检测”等事件从哪个引脚出来。MD1_CFG0x5E和 MD2_CFG0x5F则进一步控制交互事件比如双击、单击的路由。硬件设计前建议把产品逻辑先想清楚MCU 打算用哪个 GPIO 接 INT1这个 GPIO 能不能被配置为低功耗唤醒源唤醒时 MCU 是上升沿触发还是下降沿触发LSM6DS3 的中断输出极性可以通过寄存器配置默认高电平有效。如果在极低功耗场景里我倾向把中断脚设为“推挽输出且事件发生时拉高”因为 MCU 的唤醒逻辑通常是上升沿或高电平唤醒省一个反向电阻。4. 驱动初始化与三种数据读取路径4.1 初始化寄存器序列一个稳定的起点进入主题前先说清楚LSM6DS3 的寄存器非常多你没必要全配一遍但有几个关键的必须按顺序来。下面是我在项目里沉淀下来的一套最小初始化序列适用于 I2C 接口目标配置是加速度计 ±2g、104Hz、陀螺仪 ±500dps、104Hz、FIFO 关闭、中断关闭。跑通以后你再往里面加 FIFO 和中断逻辑。#include stdint.h // 假设已经封装好 i2c_write_reg(i2c_addr, reg, val) #define LSM6DS3_I2C_ADDR 0x6B // 取决于 SA0 电平 #define LSM6DS3_WHO_AM_I 0x0F #define LSM6DS3_CTRL1_XL 0x10 #define LSM6DS3_CTRL2_G 0x11 #define LSM6DS3_CTRL3_C 0x12 #define LSM6DS3_CTRL6_C 0x15 #define LSM6DS3_CTRL7_G 0x16 #define LSM6DS3_WHO_AM_I_VALUE 0x69 int lsm6ds3_init(void) { uint8_t id 0; // 第 1 步读设备 ID验证 I2C 通信和地址是否正确 i2c_read_reg(LSM6DS3_I2C_ADDR, LSM6DS3_WHO_AM_I, id, 1); if (id ! LSM6DS3_WHO_AM_I_VALUE) { return -1; // 通信异常或器件不对 } // 第 2 步软件复位确保前一次配置不残留 uint8_t ctrl3_c 0x01; // BOOT 1 i2c_write_reg(LSM6DS3_I2C_ADDR, LSM6DS3_CTRL3_C, ctrl3_c); delay_ms(10); // 等待内部上电和启动结束 // 第 3 步配置加速度计 // CTRL1_XL: ODR_XL 104Hz(0x40), FS_XL ±2g(0x00), BW_XL 400Hz uint8_t ctrl1_xl 0x40; i2c_write_reg(LSM6DS3_I2C_ADDR, LSM6DS3_CTRL1_XL, ctrl1_xl); // 第 4 步配置陀螺仪 // CTRL2_G: ODR_G 104Hz(0x40), FS_G ±500dps(0x04) // 注意这里位域不是按简单二进制排列需要参考数据手册 Table 23 uint8_t ctrl2_g 0x44; i2c_write_reg(LSM6DS3_I2C_ADDR, LSM6DS3_CTRL2_G, ctrl2_g); // 第 5 步关掉不需要的高通滤波等根据产品需要设置 // CTRL7_G 默认一般不用改调试时先跑默认 return 0; }这段代码看起来简单但有两处容易翻车一是软件复位后要留足时间建议至少 10ms太短会导致后续寄存器写入被复位过程吞掉二是 CTRL2_G 的值FS_G 字段不是简单的(FS 编码) 2不同量程对应二进制码是±250dps0x00±500dps0x04±1000dps0x08±2000dps0x0C。拿不到寄存器定义时请先打开数据手册的“Register description”章节核对别凭感觉拼 byte。4.2 三种读取数据的方式轮询、中断、FIFO初始化跑通后接下来要决定软件架构采用哪种数据读取路径。我按工程复杂度从小到大列一下。方式一轮询读取。最简单代码几句话但 MCU 得反复查询 STATUS_REG0x1E里 XLDA 和 GDA 位。数据手册建议读取加速度计数据时先读 STATUS_REG 确认新数据就绪再连续读 OUT_X_L_XL0x28到 OUT_Z_H_XL0x2D共 6 个字节陀螺仪同理读 OUT_X_L_G0x22到 OUT_Z_H_G0x27共 6 个字节。注意同一轴的高低位要一起读避免读到“半新半旧”的数据。方式二中断读取。配置 INT1 引脚为数据就绪中断MCU 进入低功耗中断来了一次读一小批。这能省不少功耗但每个数据样本都触发一次中断高频场景会比较浪费。方式三FIFO 批量读取。把传感器 FIFO 配置为“流模式”或“水印模式”当 FIFO 里攒到指定样本数水印时触发中断MCU 醒来一次把整批数据读走。这是高速数据采集和低功耗系统的“黄金路径”。FIFO 配置的代码我给出一个核心片段。假设我们希望在 FIFO 攒满 16 个加速度计样本后产生中断#define LSM6DS3_FIFO_CTRL1 0x06 #define LSM6DS3_FIFO_CTRL2 0x07 #define LSM6DS3_FIFO_CTRL3 0x08 #define LSM6DS3_FIFO_CTRL4 0x09 #define LSM6DS3_FIFO_CTRL5 0x0A #define LSM6DS3_INT1_CTRL 0x0D // 水印设为 16 个样本FIFO_CTRL1 低字节FIFO_CTRL2 高字节 i2c_write_reg(addr, LSM6DS3_FIFO_CTRL1, 0x10); i2c_write_reg(addr, LSM6DS3_FIFO_CTRL2, 0x00); // FIFO 模式选为“水印模式”并选择写入 FIFO 的数据源包含加速度计 // FIFO_CTRL5 同时决定了 FIFO 的优先顺序一般默认即可 i2c_write_reg(addr, LSM6DS3_FIFO_CTRL5, 0x11); // 根据数据手册取合适值 // INT1 上使能 FIFO 阈值中断 i2c_write_reg(addr, LSM6DS3_INT1_CTRL, 0x08); // INT1_FTH 1这里要注意 FIFO_CTRL5 的配置本质上是“把哪一路数据源送入 FIFO 以及 FIFO 模式”不同 OD R和模式组合下寄存器值差异很大。建议对照数据手册 Table 64 附近的说明或者先在无 FIFO 模式下跑通数据再逐步把 FIFO 加进来别一次性全开。从 FIFO 读数据时可以直接连续读 0x2E 开始的地址。LSM6DS3 在 FIFO 模式下从 0x2E 连续读出的是 FIFO 中的数据而不是 OUT_X_L_XL。读取长度按 6 字节一组加速度计如果同时写入了陀螺仪就是 12 字节一组计算。读完 FIFO_STATUS1/2 寄存器里的 FSS 字段会告诉你当前还剩多少组数据。4.3 数据换算从原始寄存器到物理量无论哪种读取方式最终都要把原始 int16 数据换算成 g 和 dps。以 ±2g 加速度计为例灵敏度是 0.061 mg/LSB那么物理加速度(g) 原始值 * 0.061 / 1000±500dps 陀螺仪灵敏度是 17.50 mdps/LSB换算公式物理角速度(dps) 原始值 * 17.50 / 1000为了性能我一般不用浮点数做在线换算而是定点化把灵敏度拆成“分子/分母”用 32 位整数计算最后只保留需要的精度。比如要输出 0.001g 分辨率可以乘以 1000 再除以 16384因为 ±2g 时 1g 对应 16384 LSB。下面的代码片段是两个轴的示例// 加速度计 ±2g 模式下1g 16384 LSB typedef struct { int16_t raw[3]; // X, Y, Z 原始值 int32_t mg[3]; // 换算后的毫 g } acc_data_t; void acc_convert(acc_data_t *d) { d-mg[0] ((int32_t)d-raw[0] * 1000) / 16384; d-mg[1] ((int32_t)d-raw[1] * 1000) / 16384; d-mg[2] ((int32_t)d-raw[2] * 1000) / 16384; }注意int16 转 int32 时要先把符号位正确扩展。C 语言里如果直接int32_t v d-raw[0]一般没问题因为 int16_t 会被自动符号扩展但如果你用过uint16_t存原始数据换算时就容易把负数变成很大的正数这是新手最常见的 bug。5. 把“始终开启”落到实处的完整场景睡眠-唤醒-记录前面讲的都是基础模块这一节我拿一个典型应用把整条链路串起来做一个锂电池供电的便携式倾斜报警标签平时 MCU 睡死传感器以 12.5Hz 运行一旦检测到设备倾角变化超过阈值MCU 被中断唤醒并记录一段运动数据到 Flash。软件场景拆成四个状态状态传感器配置MCU 状态唤醒源SYSTEM_IDLEAccel 12.5Hz, Gyro 关闭Deep SleepINT1 唤醒检测SYSTEM_CAPTUREAccel 104Hz, Gyro 104HzActive无SYSTEM_SEND不变Active无SYSTEM_SLEEP_AGAINAccel 12.5HzDeep SleepINT1在 IDLE 状态下我们利用 LSM6DS3 的运动检测功能Act 寄存器组里的 SLEEP 和 WAKE_UP 事件把倾角变化转换为中断。配置上会用到 WAKE_UP_THS0x6B、WAKE_UP_DUR0x6C和 MD1_CFG 里的 INT1_WU 位。原理很简单传感器内部计算加速度矢量变化当超过阈值并持续一定时间后拉高 INT1。MCU 被唤醒后首先把传感器 ODR 从 12.5Hz 升到 104Hz同时打开陀螺仪开始缓存运动数据记录 5 秒后再次把传感器切回低功耗模式自己进入 sleep。这里有一个必须提醒的点从 IDLE 到 CAPTURE 的切换过程不要跨状态直接重写全部寄存器否则可能造成中间态数据异常。安全做法是“先升 ODR 再开陀螺仪”顺序反过来可能导致短暂时间内陀螺仪数据无效。代码逻辑如下void sys_enter_capture(void) { // 1. 关唤醒中断避免采集过程中反复触发 i2c_write_reg(addr, 0x5E, 0x00); // MD1_CFG 清除 INT1_WU // 2. 打开陀螺仪先设为较低 ODR i2c_write_reg(addr, 0x11, 0x40); // CTRL2_G 104Hz, ±500dps // 3. 加速度计升到高 ODR i2c_write_reg(addr, 0x10, 0x50); // CTRL1_XL 208Hz, ±2g // 4. 清 FIFO开始采集 i2c_write_reg(addr, 0x0A, 0x00); // 先关 FIFO i2c_write_reg(addr, 0x0A, 0x02); // 再开 FIFO 流模式 }为什么要先开陀螺仪再升加速度计 ODR因为陀螺仪上电后需要几百微秒到几毫秒的稳定时间而加速度计切换 ODR 几乎瞬间就能出新数据。如果你先把加速度计升到 208Hz陀螺仪还在启动这段时间内 F FIFO 里会混入“只有加表数据”的畸形组合后期解算姿态时对齐会很难受。实际测试中这套流程让设备在 IDLE 状态的平均电流压到了 40uA 以下含 MCU 睡眠漏电和 LDO 静态功耗一旦触发唤醒CAPTURE 阶段系统电流约 4mA持续 5 秒一次事件的总功耗约 20mAs。对 100mAh 的电池来说按每天触发 50 次计算寿命依然相当可观。6. 实测中常见的坑与完整排查链路6.1 第一个坑读 WHO_AM_I 返回 0xFF 或 0x00这是最常见的问题基本可以断定 I2C 通信没建立。排查链路如下用逻辑分析仪或示波器抓 SCL 和 SDA看看有没有 ACK 应答。如果 SDA 一直拉不高说明上拉电阻没焊或者 MCU 的 I2C 引脚配置成了开漏而没使能内部上拉。检查 SA0 引脚是否悬空以及 I2C 扫描地址是不是用了 0x6A/0x6B 之外的值。检查传感器供电VDD 和 VDD_IO 是否都有稳定的电压。VDD_IO 没接总线电平会被拉死。我遇到过最隐蔽的情况是VDD 供电但 VDD_IO 由另一个可关断的 LDO 控制MCU 先枚举外设时 LDO 还没开启导致枚举失败。这个问题排查了很久最后是在设备树里加了 VDD_IO 的电源依赖才解决。6.2 第二个坑数据在重力场下静止时Z 轴加速度不是 1g如果你把传感器平放在桌面上读数应该是 X≈0Y≈0Z≈1g或 -1g取决于轴向定义。如果三个轴都有明显的直流偏移先别急着改算法可能是 PCB 贴装方向和你预期不一致参考坐标系没对齐。你先用原厂示例程序或上位机看原始值把传感器分别翻转到六个面记下每个面各轴的极性再去调整算法里的轴映射矩阵。还有可能是传感器本身存在零偏。加速度计的零偏一般很小但陀螺仪的零偏在加电瞬间会有一定温漂。做姿态算法前一定要先做静态零偏标定方法是把设备静止放置 1-2 秒取几百个样本平均作为陀螺仪的零偏补偿值。6.3 第三个坑中断不触发或触发一次后不再触发这个问题的排查链路我按优先级整理成一个表格检查点操作常见原因中断源是否配置读取 INT1_CTRL / MD1_CFG 确认对应 bit 置 1只配了传感器 ODR忘记配中断路由中断极性/模式确认是电平触发还是边沿触发是否与 MCU 唤醒配置一致MCU 配置成下降沿唤醒但传感器配了高电平有效是否被内部锁存部分事件中断是 latched 模式读状态寄存器后才会清中断处理函数里没读对应状态寄存器中断引脚是否复用检查 GPIO 是否被其他外设占用PCB 上 INT1 和某个按键或调试脚短接INT1 不触发时最快的排查方法是用示波器直接量 INT1 引脚。如果事件发生后引脚有电平变化说明传感器侧正常问题在 MCU 配置如果完全没变化就从传感器寄存器配置开始查。别用万用表去量这种微秒级脉冲测不出结果。6.4 第四个坑I2C 读取数据时偶发错位或值跳变这个坑通常和“多字节连续读”有关。LSM6DS3 支持“自动增量地址”也就是发一个起始地址后能连续读多个字节硬件会自动地址递增。但如果你的 I2C 驱动在连续读跨页或者跨寄存器区域时没有正确处理地址回卷就会读到错位的数据。最稳的办法是老老实实按寄存器地址分段读加速度计 6 字节、陀螺仪 6 字节、状态寄存器单独读。另外如果 FIFO 开启后你读 0x2E 地址但中途改变过 FIFO 模式或者 ODRFIFO 里的数据旧配置可能残留。所以我习惯在进入新状态时先清 FIFO写 FIFO_CTRL5 为 0关闭再写入目标模式重新开启并等待 FIFO_STATUS 显示空后再开始。6.5 第五个坑功耗测下来比数据手册高很多功耗异常排查先分清楚是传感器本身耗电还是外围漏电。测量方法很简单把传感器附近的去耦电容摘掉用万用表串联在 VDD 供电脚测到的就是传感器净电流。如果传感器净电流正常但整个板子在睡眠时电流高就要去查 LDO 静态电流、MCU 未配置的引脚漏电、以及有没有接了错误电平的 GPIO。在配置层面最容易导致传感器功耗偏高的情况是没有把 ODR 降到最低、陀螺仪一直处于高 ODR、FIFO 一直处于流模式刷新导致内部逻辑常开、或者 ODR 配置“开了但没真正生效”比如只写了 CTRL1_XL 的 ODR 字段却忘了配置 CTRL6_C 中的低功耗模式位。调试建议是先配成最低功耗组合实测电流再逐项打开功能每次测量一次定位到具体是哪个功能模块把功耗拉高的。7. 最后分享一个“省电 好用”的小技巧如果你做的产品既要求低功耗又要求拿到数据时足够新鲜那么我强烈建议把 LSM6DS3 的“低功耗模式 FIFO 水印”组合用透。一个很实用的配置是加速度计 ODR 设为 12.5HzFIFO 水印设为 8 个样本MCU 每 0.64 秒被唤醒一次一次读 8 组数据然后继续睡。这样可以保证你拿到的数据不是突发大块而是“每隔几秒一批”既有连续性又不用 MCU 频繁跑动。按这个思路我手上的一个环境振动监测点已经连续运行了半年电池没换过MCU 平均电流只有 30 多微安。产品逻辑也简单平时只记录振动强度如果检测到超过阈值的持续振动才把高 ODR 的完整波形数据存到 SD 卡。这套东西做起来不复杂核心就是把“传感器始终开启”的能力真正用进软件架构里而不是买一颗功能强大的传感器结果还让 MCU 像个勤杂工一样每毫秒跑一次总线。LSM6DS3 这颗料的文档和示例代码都很全我建议你拿到手后先别急着改代码把数据手册的 Register description 表从头到尾翻一遍尤其是 CTRL1_XL、CTRL2_G、FIFO_CTRL5、MD1_CFG 这几页。很多“玄学问题”最后都能在寄存器图里找到答案。
返回列表