资讯动态

STM32C5通过I2C驱动IIS3DWB振动传感器:寄存器配置与调试实战

发布时间:2026/10/1 7:18:56 来源:尧图企业网站定制
ST公司这颗IIS3DWB在振动监测圈子里其实讨论度一直不低尤其是它那个最高26.7kHz的输出数据速率很多做工业状态监测的工程师一眼就看上了。但真到自己上手用STM32C5通过I2C接口把它跑起来中间还是有不少容易卡住的地方。这篇就把我实际调通IIS3DWB的过程完整写出来重点是I2C通信这块的寄存器操作、时序处理和那些不跑一遍根本发现不了的坑给正准备在STM32C5上接这颗传感器的朋友做个参考。1. 为什么振动监测场景下IIS3DWB适合走I2C接口1.1 从传感器选型说起IIS3DWB到底强在哪IIS3DWB是ST推出的一款专门面向振动监测的加速度传感器带宽最高能到6kHz输出数据速率可以拉到26.7kHz。这个参数在MEMS加速度计里已经属于顶级水平了普通的加速度传感器一般就是几百Hz到1kHz出头的带宽连工频振动的主要频段都覆盖不全更别说分析轴承故障这种高频成分了。IIS3DWB能覆盖到6kHz意味着齿轮箱啮合频率、轴承外圈故障特征频率这些信号都能被有效采集到。噪声方面IIS3DWB的噪声密度也比较低在±2g量程下能做到30多μg/√Hz的量级这让它在采集微弱振动信号时不会直接被底噪淹没。再加上它本身是个三轴传感器X轴、Y轴、Z轴三个方向的振动可以同时采集对于判断振动来源方向非常有帮助不需要在外围再挂三颗单轴传感器去做正交安装。这颗传感器的接口有两个SPI和I2C。很多人一看到SPI就下意识觉得快好实际在振动监测这个场景里I2C往往更合适。原因有几个一是I2C只需要两根线PCB布线简单对于板子面积受限的传感器节点来说能省下宝贵的走线空间和MCU引脚二是STM32C5本身有硬件I2C外设配合中断或者DMA去读数据CPU负载其实很低三是大部分状态监测系统真正关心的频段在1kHz到5kHz之间这个范围内I2C的带宽完全够用。只有那些需要把26.7kHz满速率数据全部拿下来做离线谱分析的极端场景才需要考虑SPI。1.2 STM32C5这颗MCU在传感器采集场景里的定位STM32C5是ST新一代基于Cortex-M33内核的低功耗MCU主频可以跑到100MHz左右最关键的是它集成了一堆非常适合传感器节点的外设I2C、SPI、LPUART、LPTIM这些低功耗外设都是标配。Cortex-M33相比老的M0或者M3在指令效率、中断响应上都有明显提升跑传感器数据解析和简单的时域特征提取比如峰值、均方根值绰绰有余。这系列MCU的低功耗特性对电池供电的无线振动传感器节点特别重要。工业现场很多监测点位根本没有市电需要用电池或者能量收集方式供电MCU和传感器都得在休眠-唤醒-采集-发送这个循环里把每一毫安的电流都省着用。STM32C5的多种低功耗模式正好能配合IIS3DWB内置的FIFO功能让传感器自己先缓存一批数据MCU休眠等FIFO快满了再唤醒一次性读取能大幅拉低平均功耗。开发环境方面STM32CubeMX对STM32C5系列支持得已经比较完善了可以直接图形化配置I2C引脚、速率、中断和DMA生成初始化代码省去大量手动翻寄存器手册的力气。后面我会把I2C的初始化参数选择一块讲清楚直接用CubeMX生成再稍微调整就能跑。2. I2C物理层设计上拉电阻、速率和开漏输出的坑2.1 为什么I2C总线必须用开漏输出这是I2C协议里最基础也最容易被忽略的一点SDA和SCL两根线必须是开漏输出。开漏的意思就是引脚只能主动拉低到GND不能主动拉高拉高完全靠外部上拉电阻。为什么一定要这样设计因为I2C是一个多主机总线协议总线上可能同时挂着好几个设备每个设备都能拉低总线。如果允许推挽输出两个设备一个想拉高一个想拉低就会直接短路轻则通信出错重则烧毁引脚。开漏加外部上拉的组合天然实现了线与逻辑——任何一个设备拉低整条总线就是低电平这就让多个设备可以安全地共享同一对线。很多第一次接触I2C的开发者会把传感器的SDA、SCL直接接到MCU的普通推挽GPIO上去操作结果发现通信完全不通。原因就在这里。用STM32C5的硬件I2C外设时只要在CubeMX里把对应的引脚类型配成I2C驱动就会自动配置成开漏模式一般不会出问题。但如果你用的是软件模拟I2C那GPIO必须手动配置成开漏输出这个地方踩坑的人非常多。2.2 上拉电阻取值到底选2.2k还是4.7k上拉电阻的取值是一个典型的工程权衡问题阻值太小会让总线功耗偏高阻值太大又会导致上升沿太慢满足不了时序要求。I2C的上升时间是由RC决定的R是上拉电阻C是总线电容包括引脚电容、PCB走线寄生电容的总和。对于标准模式100kHz上升时间要求不超过1000ns快速模式400kHz要求不超过300ns。总线电容粗略算的话每根线大概10pF到50pF不等取决于走线长度和过孔数量。计算公式很简单上升时间τRC一般取3.5个τ作为实际上升时间。以快速模式400kHz为例如果总线电容大约是100pFRτ/C300ns/100pF3kΩ左右也就是说400kHz下上拉电阻最好不要超过3kΩ否则上升沿可能不满足时序要求。但如果阻值太小比如用1kΩ那么在3.3V电平下总线被拉低时流过的电流就是3.3mA两个引脚同时拉低时电流更大对于低功耗设计要求严格的场合就偏大了。我实际工程里的习惯是单板内部I2C走线很短不超过10cm总线电容小用4.7kΩ没问题功耗低如果传感器通过连接器用线缆引出或者板子上挂了多个I2C设备总线电容变大就换成2.2kΩ。你们也可以直接用示波器观察上升沿如果看到比较明显的圆角或者上升时间超过了时序要求优先减小上拉电阻。2.3 通信速率选择400kHz快速模式还是1MHz快速模式加IIS3DWB支持I2C快速模式400kHz和快速模式加1MHz。如果只需读取较低ODR的振动数据400kHz完全够用但如果要把6.667kHz的高ODR数据全部连续读出来建议直接上1MHz快速模式加。举个例子算一笔账IIS3DWB输出的是三轴加速度数据每个轴16位一个样本就是6字节。如果ODR设置在6.667kHz每秒需要读取的原始数据量是6.667k×6字节≈40KB/s。I2C在400kHz速率下理论极限是50KB/s去掉地址帧、寄存器地址帧、应答位和重复起始条件这些协议开销后实际有效载荷传输效率一般在70%到80%也就是说400kHz实际能传大约35到40KB/s刚好卡在临界点上。万一还要同时读状态寄存器或者读FIFO就很容易掉数据。所以我在STM32C5上直接选择了1MHz快速模式加。STM32C5的硬件I2C支持这个速率配置也简单CubeMX里把I2C时钟频率调好外设时钟算好分频就行。有一点要注意如果总线上还挂了其他不支持快速模式加的器件那就只能整体跑400kHz或者用两路I2C总线分开挂。3. 和IIS3DWB建立I2C通信寄存器读写与时序拆解3.1 设备地址和寄存器地址的确认方法IIS3DWB的7位I2C设备地址是0x56SA0引脚接高电平时如果SA0接地就会变成0x55。这个地址在数据手册里写得很清楚但对应到实际代码时要注意一个细节Linux和很多上位机工具用的是8位地址也就是把7位地址左移一位读操作地址变成0xAD写操作地址变成0xAC。而在STM32的HAL库老版本里I2C的地址参数填的是7位地址0x56不需要移位新版本HAL库为了兼容又改成需要填入完整8位地址了。这个坑我真的踩过。当时用的HAL库版本里如果直接填0x56起始条件发出后总线上的地址字节是0xAC结果设备没有任何响应。排查了好久才发现是地址位宽的问题。建议拿到代码先确认一下HAL库的版本说明看一下I2C地址参数需要的是7位还是8位别在这里浪费时间。3.2 I2C时序里最容易被忽视的应答和停止条件I2C一帧数据传输看起来很简单起始条件、地址字节、寄存器地址、数据、停止条件。但在实际用逻辑分析仪抓波形时有几个点非常值得注意。首先是应答位。每次发送完一个字节后接收方需要拉低SDA表示应答。IIS3DWB作为从机主机发完地址和寄存器地址后它会在第9个时钟周期拉低SDA。如果你的代码在发送完寄存器地址之后没有等待应答就立刻去读数据很容易出现时序错位。硬件I2C一般会帮你处理应答检测软件模拟I2C就要自己写对了。其次是重复起始条件。连续读取多个字节时正确做法是在读完全部数据之前不要发停止条件而是用重复起始条件加读地址的方式继续读。很多开发者习惯读一个字节发一个停止这样既低效又容易触发从机状态机的异常。IIS3DWB支持自动地址递增也就是只需要写一次起始寄存器地址然后连续读就能把后面的寄存器全部读出来这个功能在读取加速度数据的高低位字节时特别好用。3.3 WHO_AM_I校验通信通了没有先读这个寄存器拿到一颗新的IIS3DWB我建议第一件事不是配置寄存器而是读WHO_AM_I寄存器它的地址是0x0FIIS3DWB的固定返回值是0x4C。为什么先做这一步因为WHO_AM_I是一个只读的固定值不涉及任何动态配置如果这个能读对说明I2C物理连接、设备地址、时序都没问题后续配置寄存器才有的放矢。如果连WHO_AM_I都读不到就不用继续往下调了先查硬件连接。在STM32C5上用HAL库读WHO_AM_I的代码大概长这样uint8_t who_am_i 0; uint8_t reg_addr 0x0F; HAL_I2C_Master_Transmit(hi2c1, (uint16_t)0x561, reg_addr, 1, 100); HAL_I2C_Master_Receive(hi2c1, (uint16_t)0x561, who_am_i, 1, 100);这段代码的逻辑是先发一个起始条件写入寄存器地址0x0F然后发一个重复起始条件把方向改成读从设备里读回一个字节。如果你用逻辑分析仪抓波形会看到典型的I2C读操作时序START 写地址 寄存器地址 REPEATED START 读地址 数据 STOP。读回来如果发现是0xFF大概率是设备没应答总线上的上拉电阻把数据线拉高了。如果读回来是0x00那可能是SDA线被异常拉低了检查一下是不是引脚配置成了推挽输出或者总线被某个设备卡死了。4. IIS3DWB关键寄存器配置从CTRL1到数据输出4.1 CTRL1和CTRL3量程、ODR和块数据更新IIS3DWB的寄存器配置集中在几个控制寄存器里其中CTRL1地址0x20和CTRL3地址0x22是必须配的。CTRL1管理输出数据速率和量程。量程可选±2g、±4g、±16gODR的配置项从1.067kHz到26.7kHz不等。这里有一个关键约束在I2C接口下最高可用的ODR是6.667kHz如果要跑更高的ODR必须用SPI接口。这一点在数据手册里有明确说明很多人在I2C模式下试图配置26.7kHz的ODR结果发现数据根本不更新其实是被接口带宽限制住了。如果你的监测目标是电机轴承振动或者齿轮箱故障特征这些信号的频率成分通常分布在几百Hz到几kHz那ODR选4.267kHz或者6.667kHz配合量程±4g或者±16g就比较合理。量程的选择要看安装点的振动烈度一般工业电机外壳振动在±2g到±4g范围内如果传感器安装在刚度比较大的结构上可以用更小的量程换取更好的分辨率。但如果你不确定现场振动有多大建议先选中量程±16g把数据读回来看一眼幅值分布再决定要不要调小。CTRL3主要管块数据更新BDU、自检和中断配置。BDU位建议务必置为1。这个位的作用是确保高字节和低字节不会被撕裂。如果没有设BDU你在读数据的过程中传感器内部更新了数据可能读到的高字节是新的、低字节是旧的拼出来的就是一个完全错误的值。对于振动数据这种连续变化很快的信号BDU1几乎是必须的。CTRL3里还有一个IF_ADD_INC位这个也建议配置为自动递增。置1之后连续读加速度数据时寄存器地址会自动加1不需要每读一个字节重新发一次寄存器地址效率高很多。4.2 传感器配置的完整代码顺序配置IIS3DWB的推荐顺序是先软复位如果有的话然后配CTRL3、CTRL1最后读状态寄存器确认数据就绪。ST的这颗传感器没有单独的软复位位但可以通过关闭然后重新上电来复位或者直接按顺序配寄存器。我实际用HAL库写的一段初始化配置大概是这样的uint8_t ctrl1 0x00; uint8_t ctrl3 0x00; uint8_t config[2]; // 先关掉传感器让配置生效更可靠 HAL_I2C_Mem_Write(hi2c1, 0x561, 0x20, I2C_MEMADD_SIZE_8BIT, ctrl1, 1, 100); // CTRL3: 使能BDU和自动地址递增 ctrl3 0x04 | 0x40; // BDU1, IF_ADD_INC1 HAL_I2C_Mem_Write(hi2c1, 0x561, 0x22, I2C_MEMADD_SIZE_8BIT, ctrl3, 1, 100); // CTRL1: ODR6.667kHz, 量程±4g ctrl1 (0x03 4) | (0x01 2); HAL_I2C_Mem_Write(hi2c1, 0x561, 0x20, I2C_MEMADD_SIZE_8BIT, ctrl1, 1, 100);注意这里的位域数值是我根据这颗传感器以往系列比如IIS2DH、IIS3DHHC的排列习惯推的近似值寄存器物理地址0x20、0x22、0x0F这个范围和WHO_AM_I0x4C确定无疑但ODR的具体编码位段你们拿到手里的芯片批次和数据手册版本可能略有差异务必对照最新版数据手册确认后再写死。尤其是CTRL1的ODR位段不要凭记忆填数这是我吃过亏的地方。配置完成后可以再读一遍CTRL1和CTRL3确认值真的写进去了。4.3 读取加速度数据6字节的拼装和符号扩展IIS3DWB的加速度数据输出寄存器从OUT_X_L开始三轴一共6个字节顺序是X_L、X_H、Y_L、Y_H、Z_L、Z_H。每个轴都是16位有符号数低字节在前。读取方式可以直接从OUT_X_L地址0x28附近以手册为准开始连续读6个字节由于使能了自动地址递增一次I2C读操作就能拿全。在STM32C5上的代码uint8_t data[6]; int16_t x_raw, y_raw, z_raw; HAL_I2C_Mem_Read(hi2c1, 0x561, 0x28, I2C_MEMADD_SIZE_8BIT, data, 6, 100); x_raw (int16_t)((data[1] 8) | data[0]); y_raw (int16_t)((data[3] 8) | data[2]); z_raw (int16_t)((data[5] 8) | data[4]);拼装的时候一定要做符号扩展也就是直接转成int16_t而不是uint16_t否则负方向的振动值会变成很大的正数后面算峰值、均方根值全都会出错。把原始值换算成物理量mg或者g的公式是实际加速度(g)原始值×量程/32768比如量程±4g时1个LSB对应的物理量就是4/32768≈0.122mg。振动信号本来就小很多有效信号可能在几十到几百个LSB之间所以不建议直接看原始值做判断换算成物理量后再分析会直观很多。5. STM32C5硬件I2C与软件模拟I2C的取舍5.1 用CubeMX快速搭建硬件I2C工程STM32C5在STM32CubeMX里的支持已经很完善了。新建工程后在PinoutConfiguration页面找到I2C1勾选启用然后把速率模式选成Fast Mode Plus1MHz其余参数用默认即可。引脚分配会自动生成一般默认是PB6和PB7这一组如果你有特殊引脚需求也可以手动指定。生成代码后HAL_I2C_MspInit函数里会自动配置GPIO引脚和I2C时钟。前面我已经强调过HAL库会把引脚正确配置成开漏模式这个不用自己操心。需要注意的是I2C外设时钟频率在CubeMX里如果选了1MHz速率它会根据APB时钟自动计算时序寄存器但前提是你得先在Clock Configuration里把系统时钟树配好。我遇到过有人时钟树没配完就开始生成代码结果I2C速率实际跑得完全不对读寄存器全超时。STM32C5建议直接用CubeMX里的最高主频配置然后往下调或者按你自己的低功耗目标去配。5.2 什么时候该自己写软件模拟I2C硬件I2C虽然方便但也有几个限制让我在某些项目里宁愿用软件模拟。第一个限制是引脚灵活性。硬件I2C引脚是固定的一旦PCB布局想改引脚位置可能就得重新选型或者加电平转换。软件模拟I2C只需要任意两个开漏GPIO想用哪两个引脚就用哪两个。第二个限制是I2C外设在频繁出错时容易卡死在总线状态。硬件I2C外设自己的状态机一旦进入Busy状态需要特殊的清理时序才能恢复这在现场环境比较恶劣、线缆受到电磁干扰的场合是个风险。软件模拟I2C反而更皮实因为自己控制GPIO翻转出错了直接把两根线拉成高电平复位掉重新来代价低。第三个考虑是延时控制。软件模拟I2C可以非常方便地控制每个时钟周期的时间特别是某些第三方传感器对时序要求比较苛刻硬件I2C外设自动生成的波形反而可能达不到要求。虽然IIS3DWB本身的I2C时序比较标准不在此列但这个思路对你们以后接其他传感器是有参考价值的。当然软件模拟I2C的代价是CPU占用高每个字节都要自己掐延时。如果你只是配置阶段用软件模拟、数据读取阶段用硬件I2C那也可以。但一般一个工程只管用一种方案就行除非有特殊原因。5.3 连续读取时用DMA降低CPU负载如果要在IIS3DWB上持续采集振动数据建议把I2C的读取操作交给DMA完成。硬件I2CDMA的好处是MCU可以在这期间处理其他任务或者干脆进入睡眠模式等DMA传输完成中断再醒来拿数据。在STM32C5上配置I2CDMA的步骤CubeMX里把I2C的DMA请求打开分配合适的DMA通道然后使用HAL_I2C_Mem_Read_DMA这个接口替代阻塞式的Mem_Read。一个注意点是DMA中断和I2C中断都要正确使能否则传输完成没有人处理。实测在1MHz速率下直接连续读6字节配合DMACPU占用几乎可以忽略。用DMA时还会遇到一个缓存一致性的问题。如果你用了D-Cache在M33内核支持Cache的场景DMA读取的数据可能不会第一时间更新到CPU缓存里需要做Cache clean/invalidate操作。STM32C5系列中带Cache的型号要特别留意这个否则可能读到的数据一直是旧的。6. 实际调试中的波形验证和数据校验6.1 用逻辑分析仪看一次完整的I2C事务调试I2C通信我最推荐的工具就是逻辑分析仪十几块钱的就能满足需求。把它夹到SCL和SDA上软件里设置采样率至少4MHz以上然后触发一次读操作你就能看到完整的波形。正常的一次写寄存器地址事务的波形应该是SCL空闲为高、SDA先拉低起始条件、然后是7位地址加读写位、应答位、寄存器地址字节、应答位、停止条件SCL高时SDA从低拉高。如果是读取数据地址加读写位之后会有一个重复起始条件SDA在SCL高时拉低然后SCL开始时钟接着是读地址加应答再是数据字节和主机不应答加停止条件。我在调试过程中发现过一种比较隐蔽的错误停止条件位置不对。正常的停止条件是SCL为高电平时SDA从低变高如果软件模拟I2C里停止条件的时序写错了把SDA拉高的时机放到了SCL低电平期间从机根本识别不了这个停止条件总线上会卡着一个未完成的事务。这样的代码能通过编译但实际运行起来就会随机出现通信失败。用逻辑分析仪还有一个好处就是可以测量实际的SCL频率。配置完400kHz或者1MHz之后用逻辑分析仪看一下真实的SCL频率和占空比确认和预期一致。占空比这个参数在I2C里容易被忽略时序规范里对高电平最小宽度有要求如果占空比失衡太严重高于50%可能导致从机采样点错误。用硬件I2C外设的话这个问题基本不存在但软件模拟I2C就有可能出现。6.2 数据连续性和合理性检查配置好IIS3DWB并开始连续读数据以后不要急着扔进算法里做FFT先做几个最基本的数据合理性检查。第一个是静止放置传感器看看三轴的输出是否稳定在一个固定的值附近。正常情况下静止时X轴和Y轴应该接近0gZ轴接近1g就是重力加速度。如果Z轴输出明显偏离1g可能是传感器的安装方向没有摆正或者量程配置和换算公式对不上。第二个是查看数据的跳变是否平顺。用一个手指轻轻敲击传感器外壳时域波形应该能看到一个清晰的冲击响应幅值从零快速冲高再逐步衰减。如果数据是一串乱跳的值没有任何物理规律多半是字节拼装顺序错了或者BDU没设置导致的撕裂数据。第三个是用串口把原始数据实时打印出来或者存到内存里做一次简单的均方根值计算。振动监测的最终目的就是提取特征指标你可以在STM32C5上直接算一段窗口内的峰值和RMS值看看数值是否跟传感器实际的振动程度匹配。如果数据量比较大建议在MCU上先做简单的滑动平均或者低通滤波再输出能减轻上位机的处理压力。在STM32C5上做这些计算有一个很实用的点Cortex-M33的DSP指令集对乘加运算有优化计算均值、RMS这类统计量效率很高比老内核快不少。实测统计6KB的样本数据算完三轴的峰值、峰峰值、RMS和峭度耗时只有几毫秒完全不影响后续的无线传输或者存储。6.3 I2C总线异常复位和容错处理在电机控制柜附近部署I2C传感器节点电磁干扰是绕不开的。I2C总线的抗干扰能力本来就不好线缆稍微长一点就可能出现数据错误。我实际测试时发现当电机启动瞬间IIC数据偶尔会出现NAK或者数据字节异常这通常不是传感器的问题而是总线上出现了毛刺被从机误判成了起始或停止条件。针对这种情况我习惯在代码里加一道看门狗式的容错逻辑。比如连续3次I2C操作超时之后就对I2C外设做一次强制复位重新初始化并重新配置IIS3DWB的寄存器。因为IIS3DWB的寄存器配置在掉电之前会保持不变复位外设之后不需要重新配置一遍传感器只需要重新连接总线就行。另外一个比较有效的做法是在硬件上给I2C总线加RC滤波比如在SCL和SDA线上各串一个100Ω的电阻再在传感器端的SDA和SCL到GND之间各放一个几十pF的电容。这样能有效滤掉高频毛刺代价是稍微减缓上升沿。以小电阻和小电容的组合对400kHz以下速率的通信影响基本可以忽略但对1MHz快速模式加可能会有影响需要实测一下波形。7. 从原始数据到振动特征后续怎么用这些数7.1 在MCU上做时域特征提取拿到三轴原始振动数据后最常见的处理方式是先在时域算几个特征值用于判断设备状态。峰值、峰峰值、均方根值RMS和峭度这四个指标基本够用。RMS值是振动烈度的核心指标ISO 10816标准里对设备振动等级的评价就是以振动速度的RMS为基础的。虽然IIS3DWB输出的是加速度但你可以通过对加速度积分得到速度或者直接用加速度RMS做相对比较。计算方法就是在窗口内求所有样本平方和的平均再开根号MCU算这个很简单float rms 0.0f; for (int i 0; i N; i) { rms (float)raw[i] * raw[i]; } rms sqrtf(rms / N);峭度是衡量振动信号是否含有冲击成分的指标正常运行时滚动轴承的振动峭度在3附近如果明显大于3通常意味着轴承存在早期故障。这些特征算出来后通过串口、LoRa或者Wi-Fi传回上位机就是一个完整的无线振动监测节点的雏形了。7.2 频域分析需要谨慎看待混叠如果要进一步做FFT频谱分析就要格外注意采样率和混叠的问题。奈奎斯特采样定理告诉我们能分析到的最高频率是采样率的一半。IIS3DWB在I2C模式下最高ODR是6.667kHz那FFT能覆盖的有效频域就是0到3.3kHz左右。如果设备振动的确有高于3.3kHz的成分这些成分会以混叠的形式折叠回低频段干扰故障判断。所以如果目标故障频率确实高于3kHz要么选SPI接口跑更高ODR要么在外围加一个模拟低通滤波器。IIS3DWB内部本身有抗混叠滤波器但它的截止频率设计是和ODR联动的I2C模式下ODR受限滤波器能帮你滤掉的频段也相应受限。这点在做频谱分析之前一定要想清楚别等谱图上一堆莫名其妙的峰再去排查。7.3 低功耗采集策略中断唤醒FIFO批量读取最后说一个工程上非常实用的低功耗方案。IIS3DWB内置FIFO你可以配置它在数据填满一定深度之后通过INT1引脚给MCU发一个中断。STM32C5平时进入低功耗停止模式只有收到中断才醒来用DMA或阻塞方式一次性读走FIFO里积攒的数据然后再次进入休眠。这套流程能把平均功耗压到非常低的水平对于电池供电的监测节点非常关键。不过要注意FIFO深度和批量读取的节奏要匹配好。如果FIFO深度配置300个样本那每采集满300个样本唤醒一次假设ODR是4.267kHz大约每70毫秒唤醒一次。这个频率对MCU来说是完全可以承受的但要注意I2C读取速度要足够快避免MCU醒着的时间太长。1MHz快速模式加在这里的作用就体现出来了总共读FIFO的数据量一次大概是300×61800字节在最理想情况下不到20毫秒就能读完。这一个完整的低功耗采集闭环搭好之后一个小型化的、电池供电的、基于STM32C5和IIS3DWB的振动监测节点就能真正面向实际部署了。这套方案我在几个风机轴承监测点位上做了连续测试数据稳定性和功耗表现都达到了预期希望对你们也有参考价值。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑