尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

STM32C5通过SPI读取IIS3DWB加速度计实现振动监测

发布时间:2026/9/28 19:33:37

资讯中心
01
ARTICLE

STM32C5通过SPI读取IIS3DWB加速度计实现振动监测

STM32C5通过SPI读取IIS3DWB加速度计实现振动监测
前两周在调一个工业设备振动监测的小项目主控换成了STM32C5传感器选ST的IIS3DWB通信走SPI。跟以前用MPU6050测风扇转速完全不是一回事这次是要拿真正的振动波形IIS3DWB这种机械带宽能做到6kHz左右的宽带加速度计才有价值。整个调通过程不算复杂但SPI时序、片选、寄存器地址这些地方确实够我记一篇笔记。如果你也打算在STM32C5上用SPI读IIS3DWB这篇文章应该能帮你把路走直一点。1. 为什么用IIS3DWB而不是普通加速度计又为什么走SPI1.1 振动监测对加速度计的带宽要求先说选型逻辑。很多人一听“加速度计”第一反应就是MPU6050、ADXL345这些消费级芯片。它们在无人机、姿态检测里确实够用但拿来做设备振动监测问题就出在带宽上。电机轴承故障、齿轮啮合、泵的空化现象这些振动特征频率往往不是基频本身而是基频的高次谐波几十赫兹到几千赫兹都有。普通消费级加速度计的可用带宽通常只有1kHz上下高频信息根本进不来频谱上一片衰减轴故障特征就看不出来。IIS3DWB是ST专门为振动状态监测出的三轴加速度计输出数据率可以做到26.7kHz机械带宽最高约6kHz。这个“机械带宽”指的是MEMS敏感结构本身能真实响应的频率范围不是数字滤波器标出来的数值所以在齿轮箱、风机这类中高频振动场景下它是更合适的传感器。另外它还是工业级器件温度范围、稳定性都比消费级加速度计靠谱。我手头这个项目要长时间挂在设备旁边并不想隔三差五去校准一次所以IIS3DWB这种自带稳定性的传感器就更合适了。1.2 SPI与I2C的选择逻辑IIS3DWB同时支持I2C和SPI但在这个项目里我直接选了SPI基本没犹豫。I2C速率上限不高虽然现在很多I2C总线能跑到1MHz但和SPI的10MHz相比差距还是很大的。振动监测需要高采样率26.7kHz下三轴数据持续往外吐I2C的吞吐会成为一个瓶颈尤其是后面还要边采集边做FFT数据通道越宽越好。SPI这边是4线SCLK、SDI、SDO、CSB主从之间一问一答全双工适合高速连续读数据。对于IIS3DWB来说SPI时钟最高可以到10MHz16位数据点三轴加上寄存器地址一个采样点下来开销很小完全能跟得上26.7kHz的输出率。参数IIS3DWB典型指标说明量程±2g / ±4g / ±8g振动监测常用±4g或±8g输出数据率667Hz到26.7kHz带宽需求高就选26.7kHz平坦带宽最高约6kHz这是区别于普通加速度计的核心数据输出格式16位有符号补码每轴两字节解析比较直接SPI时钟最高10MHz支持mode 0和mode 3工作温度工业级适合长期在线监测2. IIS3DWB这颗传感器SPI侧到底长什么样2.1 引脚与通信模式接线方面没有太多弯弯绕绕CSB接GPIOSCLK接SPI时钟SDI接MOSISDO接MISO。有些同学会问SDI和SDO是不是能串起来做半双工IIS3DWB确实也支持这种配置但我建议第一版先老老实实用4线全双工别为了省一根线给自己添乱。SPI工作模式上IIS3DWB支持mode 0和mode 3。mode 0是SCLK空闲为低数据在上升沿采样mode 3是SCLK空闲为高数据在下降沿采样。两种模式都能通但有一个原则主控和传感器必须约定一致。如果你在CubeMX里选了mode 0传感器侧没有额外接线去改那就保持mode 0别中途去切。数据格式默认是MSB first8位数据这也是绝大多数MEMS传感器的默认方式。有人喜欢把SPI配成16位数据帧对IIS3DWB来说没必要反而会让寄存器地址和数据的字节边界变得很别扭。保持在8位模式一字节一字节读是最省心的。2.2 寄存器读写的基本规则IIS3DWB的寄存器访问规则和ST其他MEMS传感器非常像写操作时发送的第一个字节是寄存器地址最高位为0读操作时发送的第一个字节是寄存器地址最高位需要置1。也就是说读寄存器时实际发送的地址是寄存器地址 | 0x80。这一点很多人第一次会忘。如果直接拿寄存器地址去读芯片会把它当成写操作后续数据根本回不来。我用过不少ST传感器这个“读标志位置1”的习惯一旦形成后面换型号也不容易踩坑。多字节读取时IIS3DWB支持地址自动递增。也就是说只要把起始寄存器地址发出去后续SCLK时钟持续给芯片会把连续地址的数据依次送出来。三轴加速度数据一共六个寄存器如果自动递增没打开就得一轴一轴分别读每读一次都要拉一次片选、发一次地址效率低不说还可能把三轴数据的时间戳错开。2.3 时钟树上的分频计算SPI速率不是想配多少就配多少。IIS3DWB的SPI时钟上限是10MHz超过就是超规格使用短期内可能没事长期稳定性和误码率都没保障。在实际配置时先看CubeMX的Clock Configuration里SPI外设挂在哪条总线上。比如我这边把APB时钟配到80MHzSPI1也跑在80MHz总线上想要10MHz的SPI时钟分频系数就是8。如果APB配到了100MHz那分频8就变成12.5MHz已经超限了就得用分频16得到6.25MHz虽然慢一点但稳。有一个很实用的小建议CubeMX的Baud Rate Prescaler下拉框里看到的是分频系数不是最终速率。先算好总线时钟再做除法别看着下拉框里的数值就顺手选了。3. STM32CubeMX里搭C5的SPI工程3.1 SPI外设的CubeMX配置STM32C5虽然是新系列但CubeMX里的配置逻辑和G4、F4这些老熟人基本一致上手不费劲。用C5和G4做对比时SPI外设这部分差别不大主要是一个总线挂载位置、引脚复用差异的问题不用把它想得太特殊。在CubeMX里我选的是SPI1模式设为Full-Duplex Master数据宽度8位MSB firstCPOL为LowCPHA为1 Edge也就是mode 0。Baud Rate Prescaler按上面算好的分频系数选。如果你在C5上找不到SPI外设先去Pinout页面确认引脚有没有选中复用功能。很多新手直接在Pinout视图里点了某个引脚却没有把它分配给SPI结果生成代码里根本不出SPI句柄。正确做法是点击引脚后选择SPI1_SCK、SPI1_MOSI、SPI1_MISO这几个复用选项而不是随便配一个GPIO。3.2 片选用软件GPIO而不是硬件NSS片选CSB我强烈建议用普通GPIO手动控制不要依赖STM32的硬件NSS。原因很简单IIS3DWB的一帧通信可能是“1字节地址 N字节数据”片选必须在这整个过程中保持低电平。如果使用了硬件NSS它在SPI帧结束时会自动拉高那你每次只能读一字节多字节连续读就不好做。另外很多STM32的硬件NSS功能在一些封装下和其他功能复用容易产生误导。手动GPIO控制CSB会更直观读之前拉低发完地址、读完数据之后拉高。这个“低电平持续时间”也方便你用逻辑分析仪判断是哪里出了问题。我用的是PB6作为CSB实际引脚可以根据你的电路板来定。关键是CubeMX里把这个引脚配成GPIO_Output初始化时默认输出高电平因为IIS3DWB的片选是低有效不通信时就必须保持高电平。3.3 初始化校验与HAL句柄CubeMX生成代码后第一步不是写业务逻辑而是确认HAL_SPI_MspInit里有GPIO复用和SPI外设时钟使能。如果生成代码后SPI没有时钟多半是MspInit里缺了__HAL_RCC_SPI1_CLK_ENABLE()这在地图配置正确时一般不会出现但值得扫一眼。初始化完成后可以用HAL_SPI_GetState(hspi1)看看外设状态。我习惯在初始化后面加一个简单校验把SPI句柄的Instance和Init参数打印出来看一眼确认Prescaler没有变成默认值。这个问题很隐蔽CubeMX里改了分频但如果你后来手动改过代码可能又被覆盖回去。我手头STM32C5板子的调试串口是USART1所以调试时我会在初始化之后打印一行SPI1 init ok再往下走。省掉的这一步后面可以少排查很多莫名其妙的问题。4. 用HAL库把振动数据抓出来4.1 第一步读WHO_AM_I不管什么传感器第一次上板最该做的都是读WHO_AM_I。IIS3DWB的WHO_AM_I寄存器地址是0x0F读出来的值通常是0x7B。这个校验能一次性确认三件事接线对不对、SPI配置对不对、片选时序对不对。我封装了一个通用读函数核心思想是发地址字节然后继续给SCLK同时从MISO收数据。因为HAL的HAL_SPI_TransmitReceive是全双工发送和接收同时进行所以在读数据那几拍里主机要发送0x00占位。#define IIS3DWB_WHO_AM_I 0x0F #define IIS3DWB_CTRL1 0x20 #define IIS3DWB_CTRL2 0x21 #define IIS3DWB_STATUS_REG 0x1E #define IIS3DWB_OUT_X_L 0x28 uint8_t tx[4], rx[4]; tx[0] (IIS3DWB_WHO_AM_I | 0x80); // 读操作最高位置1 tx[1] 0x00; tx[2] 0x00; tx[3] 0x00; HAL_GPIO_WritePin(CSB_GPIO_Port, CSB_Pin, GPIO_PIN_RESET); HAL_SPI_TransmitReceive(hspi1, tx, rx, 4, 10); HAL_GPIO_WritePin(CSB_GPIO_Port, CSB_Pin, GPIO_PIN_SET); uint8_t who_am_i rx[1]; // 第一个回包是地址阶段的占位数据真正数据从rx[1]开始这里有个细节HAL_SPI_TransmitReceive发4个字节接收也会收4个字节。第一个字节对应的是从机在收到地址时的MISO输出一般没意义从第二个字节开始才是0x0F寄存器里的数据。所以WHO_AM_I读取的是rx[1]不是rx[0]。这个“偏移一位”问题是SPI读MEMS传感器最标准的坑之一。4.2 配置传感器ODR、满量程、模式读回WHO_AM_I正确之后再去写配置寄存器。IIS3DWB的CTRL1负责ODR和轴使能CTRL2负责满量程和自动地址递增这一类功能。具体位段建议以数据手册为准因为ST传感器的位定义比较细不同系列之间会有差异。我给一个参考框架// 以手册的ODR码表和FS码表为准 // 这里只是演示CTRL1的高4位放ODR低3位放轴使能 uint8_t ctrl1 (IIS3DWB_ODR_26_7KHZ 4) | 0x07; // X/Y/Z全开 uint8_t ctrl2 (IIS3DWB_FS_8G 2) | IIS3DWB_BDU_EN; // FS8g同时开BDU iis3dwb_write_reg(IIS3DWB_CTRL1, ctrl1); iis3dwb_write_reg(IIS3DWB_CTRL2, ctrl2);BDU是Block Data Update打开之后数据寄存器的高低位字节会同步更新避免你读取时正好赶上寄存器刷新出现高字节和低字节属于不同采样点的问题。高频率振动时X/Y/Z数据跳变得很快这个位打开对数据质量很有帮助。写寄存器函数比读函数更简单发送的第一个字节是寄存器地址最高位为0后面跟上要写的值整个过程中片选保持低电平。4.3 连续读取三轴6字节IIS3DWB三轴数据以16位补码格式存储在输出寄存器里。以X轴为例低字节在前高字节在后。如果自动地址递增已经打开可以直接从OUT_X_L开始连续读6个字节一次把X/Y/Z全部拿回来。uint8_t tx[7], rx[7]; tx[0] (IIS3DWB_OUT_X_L | 0x80); // 读操作起始地址0x28 for (int i 1; i 7; i) tx[i] 0x00; HAL_GPIO_WritePin(CSB_GPIO_Port, CSB_Pin, GPIO_PIN_RESET); HAL_SPI_TransmitReceive(hsp1, tx, rx, 7, 10); HAL_GPIO_WritePin(CSB_GPIO_Port, CSB_Pin, GPIO_PIN_SET); int16_t acc_x (int16_t)(((uint16_t)rx[2] 8) | rx[1]); int16_t acc_y (int16_t)(((uint16_t)rx[4] 8) | rx[3]); int16_t acc_z (int16_t)(((uint16_t)rx[6] 8) | rx[5]);注意tx[0]之后发的是6个0x00所以总长度是7。接收时rx[0]还是地址阶段占位rx[1]到rx[6]才是六个有效数据字节。如果对手册确认后发现数据输出寄存器是三字节一轴的24位格式那原理是一样的只是起始地址之后要多读3个字节24位补码需要手动左移到int32_t里。不同批次的传感器固件和型号版本可能有差异拿到芯片后先根据实际寄存器宽度来定。4.4 把原始数值换算成g值读出来的int16_t是补码满量程范围内最大值是32767对应的物理量由当前满量程决定。以±8g为例比例关系为g_value acc_raw * (8.0f / 32768.0f)也就是每LSB约0.244mg。如果选±2g每LSB约0.061mg±4g每LSB约0.122mg。采样率和量程之间需要做个取舍量程越小分辨率越高但对大幅振动容易削顶量程太大分辨率会下降。我这边设备振动幅度不大但也存在偶发冲击所以选±8g牺牲一点低位分辨率保证冲击波形不被切掉。在程序里我习惯先把原始值存成int16_t数组等需要分析时再转float而不是每读一次就转一次。这样保存下来的波形是最原始的后面换量程、换校准系数都不用重新采集。5. 调试实录SPI读IIS3DWB最容易翻车的四件事5.1 mode 0与mode 3的选择以及读回0x7B变0xF6我调试第一天就碰到一个很经典的怪现象WHO_AM_I读回来不是0x7B而是0xF6。一眼看过去像是芯片坏了实际上是相位差导致的字节错位。SPI的采样边沿差了一个时钟相位数据线上同一组比特被主控在错误的边沿采样后就会整体偏移或者完全错乱。0xF6其实是0x7B的按位取反再凑出来的现象具体值是左移一位还是右移一位跟你的相位配置有关。解决方式很简单先把CubeMX里的CPOL和CPHA明确设为mode 0CPOLLowCPHA1 Edge或者mode 3CPOLHighCPHA2 Edge但不要用mode 1或mode 2。IIS3DWB手册明确支持mode 0和mode 3这两个里任选一个都行。我最终用了mode 0后面所有代码都按mode 0来。5.2 CS低电平持续时间不足数据移位一个字节第二个坑出在片选上。我用GPIO控制CSB本来以为不会有问题但有一次读出来的数据整体往后偏移了一个字节X轴数据变成了地址占位字节Y轴数据跑到了X轴的位置。原因很直接片选拉低之后SCLK时钟给早了或者SPI速度太快传感器还没准备好前几个时钟没有被正确解释。这类问题最有效的排查手段是逻辑分析仪。把CSB、SCLK、SDI、SDO四根线接上抓一帧数据看CSB拉低到SCLK第一个上升沿之间到底有没有足够的间隔。ST传感器一般要求在CSB有效之后需要一小段建立时间主控这边可以在CSB拉低后加一个极短的空操作延时或者把SPI时钟稍微调低一点比如从10MHz降到5MHz先确认功能正常再慢慢把速度提回去。5.3 时钟分频算错通信偶发错位还有一个隐蔽问题SPI时钟在10MHz以下时一切正常一旦超过IIS3DWB上限问题就变得非常随机有时读几十次才错一次有时一开机就错。后来查CubeMX时钟树才发现我APB总线已经配成了80MHzSPI分频选了4等于SPI时钟20MHz超了10MHz一倍。传感器在这种速率下根本没有保证能偶尔通已经算给面子了。遇到随机错位第一步不是改代码而是回去看时钟树。SPI时钟不是“能通就行”是要低于数据手册上限的。我后来分频改成8SPI时钟正好10MHz连续抓了几万包都没错。如果APB是其他频率宁可选择更低一档的SPI速率也不要卡在上限边缘。5.4 用逻辑分析仪核对波形调试SPI逻辑分析仪比示波器更适合。示波器看模拟波形好不好逻辑分析仪直接解码协议。我用的是几十块钱的逻辑分析仪软件里选择SPI协议把CSB、SCLK、SDI、SDO分别标好抓一帧就能看到地址、数据、片选区间比对着寄存器手册猜快太多。重点看三件事一是CSB低电平期间SCLK有多少个边沿多一拍少一拍都会导致字节错位二是SDI上的数据是否和寄存器地址一致特别是读操作的最高位有没有置1三是SDO线上数据回传的时间点是否和数据手册的时序图吻合。只要这三条对WHO_AM_I基本一次就能读回来。6. 原始加速度拿到之后下一步怎么接振动分析6.1 时域波形与频域FFT拿到原始加速度值只解决了“能被单片机读到”的问题真正的振动分析在信号处理这一层。以26.7kHz采样率为例三轴数据持续采集每路信号理论上能看到约13kHz以内的频谱正好覆盖IIS3DWB 6kHz平坦带宽后面的余量。做FFT之前有几个细节要注意先去掉均值不然0Hz附近的直流分量会特别大把低频故障特征盖住然后加窗常用汉宁窗最后观察频谱中的峰值对照设备转频的谐波来定位问题。这些处理可以在STM32C5上跑也可以把原始数据通过串口传到上位机做看数据量和实时性需求。6.2 C5平台上的数据吞吐能力STM32C5的Cortex-M33内核自带DSP指令跑1024点FFT并不吃力。但在连续采集场景里真正影响稳定性的是数据搬运而不是计算本身。我建议用SPI的DMA接收配合定时器或外部中断触发把数据先放到内存环形缓冲里主循环只做搬运和信号处理避免让CPU在SPI中断里疲于奔命。IIS3DWB在26.7kHz ODR下三轴每采样点6字节每秒约160KB数据。这个量级对C5来说非常轻松即使不加DMA也能用轮询读回来。但如果后续要做长时间连续监测DMA几乎是必须的否则SPI中断会挤占FFT计算时间系统会变得不稳定。还有一点如果你准备把多组数据打包发送去上位机我比较推荐自己定义一个简单的帧结构例如帧头、时间戳、三轴原始值、校验字节。这样即使串口传输偶尔丢包也能通过帧头和校验快速识别不至于把后面的数据全部解析错。最后分享一个我调这套组合时觉得特别管用的土办法在正式做FFT和频谱分析之前先把IIS3DWB平放在桌面上串口打印三轴原始值。正常情况下Z轴应该读到接近1gX轴和Y轴接近0。这一步能同时验证满量程选择、符号方向、数据高低字节顺序比直接看频谱定位错误要快得多。等平台读数稳定了再把它装到设备上去采集真实振动心里就有底了。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。