尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

基于MAX86150的可穿戴心率血氧监测驱动开发实战解析

基于MAX86150的可穿戴心率血氧监测驱动开发实战解析 简介本资源是面向嵌入式开发工程师与可穿戴设备研发人员的MAX86150心电图与血氧饱和度传感器驱动工程包解决ECG/SpO₂双模生理信号采集中的硬件初始化、多通道数据读取、低功耗调度及原始信号预处理等核心问题。压缩包共246个文件涵盖40个C源文件含STM32底层驱动与算法接口、46个头文件定义寄存器映射与API函数、41个编译中间文件.d/.o及34个Keil工程配置文件.uvproj/.uvopt/.axf等完整支持基于STM32F10x平台的I²C通信、AFE参数配置、PPG光源时序控制与中断响应逻辑。已有770人学习下载资源结构清晰包含多版本工程备份.bak、启动脚本.sct、内存布局配置.sct及调试符号文件.map/.lst便于开发者快速移植、调试验证与二次开发。 最近在做一个可穿戴心率血氧监测的小项目核心传感器选了MAX86150。这颗芯片比较有意思它把心电图和血氧浓度检测集成在同一个封装里一颗芯片同时输出ECG和PPG两路数据直接省掉了我原本需要分开设计的模拟前端和光学前端。整个驱动从零开始写到调试稳定花了两天半时间最后整理成了一个驱动源码包。我这篇文章就把这个驱动包背后的设计思路、寄存器配置、数据处理流水线和踩过的坑一次说清楚给后面要搞MAX86150的朋友省点事。先说清楚这个东西能干什么适合谁看。如果你在做人体的心率、血氧、心电相关产品比如智能手环、心率胸带、指夹式血氧仪或者只是想用一颗现成芯片把ECG和SpO2采集链路先打通那么MAX86150是很好的选择。这篇文章适合MCU开发基础还不太扎实的初学者也适合已经会调I2C外设但第一次碰生物信号传感器的嵌入式工程师。我会尽量把驱动层、寄存器、滤波算法这些关键点拆开讲不绕弯子。1. 先搞清楚MAX86150是什么1.1 一颗芯片搞定心电和血氧的核心原理MAX86150是Maxim现在归ADI推出的一体化生物传感器模块内部同时集成了ECG模拟前端和PPG光学前端。这里的ECG就是我们常说的心电图信号它靠体表电极测量心脏电活动引起的电位差变化PPG则是光电容积脉搏波描记通过LED照射皮肤组织由光电二极管接收透射或反射的光检测血管内血容量随脉搏搏动的变化。两个技术方向在传统方案里是两套完全独立的电路ECG需要仪表放大器、右腿驱动、滤波网络PPG需要LED驱动、跨阻放大器、环境光抑制。MAX86150把这些全部做进一个模块里MCU只需要通过I2C总线读写寄存器就能同时拿到心电和脉动波形数据再在软件里处理出心率、心电波形和血氧浓度。对于小型便携设备来说这种集成度能省掉大量PCB面积和BOM成本。光电容积脉搏波用于血氧浓度计算的核心思路是利用氧合血红蛋白和脱氧血红蛋白对红光和红外光的吸收率差异。动脉血管随心脏搏动周期性充血所以光电二极管接收到的光强信号里包含一个跟随脉搏波动的交流分量AC和一个基本恒定的直流分量DC。把红光和红外光两路信号的AC/DC比值做归一化得到一个比值R再通过经验公式或者查表映射就能估算出血氧饱和度SpO2。具体算法我会在后面实操章节展开这里先记住这个模型。需要特别说明的是PPG光路设计对信号质量影响极大。反射式方案要把LED和光电二极管放在同一侧两者之间必须有遮光隔离否则光线会直接从封装表面“串光”到接收端导致光电二极管饱和数据完全没法用。MAX86150的光学模块在出厂前已经做了内部光路处理但PCB镜头开窗、传感器贴合皮肤的位置仍然需要你仔细设计这在我实际测试中踩了不少坑后面排查部分会详细说。1.2 驱动层需要从数据手册里提炼哪些关键信息拿到芯片的第一件事不是写代码而是读数据手册尤其是寄存器映射表和时序参数这两章。驱动层本质上做的事情很直观通过I2C配置寄存器让芯片内部的模拟前端按合适的增益、采样率、LED电流工作然后持续从FIFO读取数据。所以你需要从手册里确认的几类信息包括I2C从机地址、芯片上电复位时序、各功能模块的配置寄存器、FIFO状态寄存器、数据寄存器的字节序和通道排列。MAX86150的I2C地址我记得在手册的Slave Address章节7位地址形式是0x5E写驱动时注意根据你用的HAL库或者裸机I2C驱动模式做相应转换。我在项目里用的是STM32标准外设库风格的I2C直接把7位地址左移一位成8位形式。这里容易搞混如果你是照着别人的例程改一定先确认这个地址和你当前工程里的I2C地址模式是否匹配。驱动层的另一个重点是明确数据类型。MAX86150的ADC输出是高分辨率数据ECG和PPG各通道的样本会按照FIFO配置顺序依次排列在数据寄存器中。读取时如果不对齐字节序和通道顺序解出来的数据就是乱的后面所有算法都无从谈起。我会在初始化配置时把通道顺序固定下来读取端和解析端严格保持一致这一条在整个开发过程中帮我避免了很多排查困扰。2. 驱动开发前的硬件与工程准备2.1 硬件连接与原理图设计的几个关键细节MAX86150是光学模块加模拟前端硬件连接比普通I2C传感器讲究一点。除了标准的VDD、GND、SDA、SCL还需要注意LED电源引脚和中断输出引脚。LED供电建议单独走电源轨因为LED脉冲电流瞬态很大如果和MCU模拟部分共用一个LDO脉冲噪声会串进ECG信号里。我一开始图省事共用了3.3V结果ECG波形上明显有一簇一簇的周期性毛刺后来单独加了一个小封装LDO给LED供电毛刺立刻小了很多。ECG输入端的引脚也要特别注意。MAX86150的ECG通道需要外接电极通常是右臂、左臂、右腿驱动这几个电极点。电极到芯片输入引脚的走线尽量短并且在输入端加ESD保护和RC滤波。右腿驱动引脚对共模抑制很关键如果手边没有专用的右腿驱动电极至少也要把RLD引脚正确接到人体参考电极上否则50Hz工频干扰会大到波形没法看。SDA和SCL上拉电阻一般选4.7kΩ到10kΩ具体看I2C总线速率和走线长度。我习惯在原理图阶段就预留好上拉电阻位置如果后面发现信号沿太慢或者通信不稳定可以方便地调整。另外MAX86150的INT引脚建议接到MCU的外部中断输入因为FIFO数据满、溢出、ALC溢出等事件都可以通过中断通知MCU比轮询省资源这个在后面驱动层设计里会详细讲。供电电压和电平匹配也是常见坑点。MAX86150的数字接口电压范围要确认好如果MCU是5V电平需要加电平转换或者用开漏加外部上拉的方案不能直接硬接。3.3V MCU一般还好但我建议还是实测一下I2C引脚波形确保高电平能超过芯片VIH阈值低电平满足VIL要求避免偶发通信失败的问题。2.2 开发环境、驱动框架和调试工具的选型MCU我选的是STM32F103系列主要是手头现成的板子多HAL库和标准库都能用。驱动层源码我最终是写成了一套与具体RTOS和MCU库解耦的模块底层I2C读写函数通过函数指针注入这样方便以后移植到其他平台。如果你也是从零开始我建议别急着把驱动和业务逻辑揉在一起先分三层平台层管I2C读写和延时驱动层管寄存器配置和数据读取算法层管滤波和特征提取。后面调试和维护都会轻松很多。调试手段上串口打印是最快的CH340串口模块加一个USB转TTL基本够用。我在最初验证I2C通信时直接写了一个寄存器扫描函数把各个关键寄存器的值读出来打印到串口对比数据手册确认复位默认值。这一步能验证I2C底层读写是否正确也能排除芯片没焊好、地址不对这类低级问题比一上来就跑完整驱动高效得多。下载调试用ST-Link程序下载和在线断点调试一起搞定stlink驱动安装好之后CubMX生成的工程基本是开箱即用。调试波形数据时串口波特率建议大于115200因为ECG和PPG数据量都不小。我最后把原始波形数据用串口发到上位机Python脚本里画图同时打印关键参数定位问题非常方便。这一套组合下来从硬件验证到算法调优都有抓手强烈推荐你也搭一套。linux驱动开发的朋友可能会问这芯片能不能直接挂到Linux下通过iio子系统访问。如果项目是跑在嵌入式Linux上你完全可以按照字符设备驱动框架写一个简单的I2C驱动把MAX86150注册成iio设备然后把原始数据通过sysfs或者netlink通道上报。我这里主要基于MCU裸机场景但寄存器映射和初始化流程是通用的你可以直接参考。3. 驱动层设计从寄存器到底层读写3.1 寄存器地图与初始化时序的梳理MAX86150的寄存器空间不算复杂核心就是系统控制、FIFO配置、PPG配置、ECG配置、LED电流配置这几个模块。我在工程里把寄存器地址用宏定义全列出来好在代码里见名知义。下面这个表是我根据实际项目整理的核心寄存器映射具体每位定义建议以最新数据手册为准我手里这份是Rev A版。寄存器地址寄存器名称用途0x02FIFO_WRITE_PTRFIFO写指针指示下一个写入位置0x03OVF_COUNTERFIFO溢出计数器0x04FIFO_READ_PTRFIFO读指针读取前可手动更新0x05FIFO_DATAFIFO数据寄存器连续读可批量出队0x06FIFO_CONFIG_1采样平均、FIFO满阈值、滚动使能0x07FIFO_CONFIG_2中断行为、FIFO满中断使能等0x08SYSTEM_CONTROL复位、关断配置0x09PPG_CONFIG_1ADC量程、采样率、LED量程0x0APPG_CONFIG_2PPG通道采样平均相关0x0CLED1_PALED1红光脉冲幅度0x0DLED2_PALED2红外脉冲幅度0x0ELED3_PALED3绿光等脉冲幅度系统控制寄存器是整个初始化的起点上电后芯片默认处于关断状态必须先把SHUTDOWN位清零进入正常工作模式再写复位位让所有寄存器回到默认值然后等待一段时间让内部模拟电路稳定。这里有一个顺序问题值得注意先解除关断再触发复位还是先复位再解除关断我实测下来上电后先写复位再清关断位系统更稳定否则偶尔出现第一次读取的数据全是0的情况。FIFO_CONFIG_1里的采样平均选项会影响数据输出速率。打开采样平均可以降低噪声但代价是有效输出速率降低。我在ECG和PPG都取100SPS左右时采样平均设成2效果比较平衡。FIFO满阈值设成32样本也就是FIFO存满后产生中断MCU一次性把整个FIFO读空处理压力比较均匀。滚动使能可以根据需要开如果不想丢数就关掉滚动满了就报警。初始化完成之后建议把关键寄存器全部回读一遍和配置值比对确认写入成功。这个步骤虽然简单但在批量调试时特别有用尤其是有些寄存器写入后需要等待内部同步立刻读可能读到旧值。3.2 基于HAL库的I2C驱动封装底层I2C读写是整个驱动的基石。我基于STM32 HAL库封装了两个函数读寄存器和写寄存器。读寄存器通过寄存器地址加数据长度的组合用HAL_I2C_Mem_Read直接完成写寄存器用HAL_I2C_Mem_Write。封装的好处是后续驱动代码完全不用关心I2C时序细节替换到别的平台时只要改这两个函数的实现。#define MAX86150_I2C_ADDR (0x5E 1) // 7位地址左移成8位形式 int8_t max86150_read_reg(uint8_t reg_addr, uint8_t *buf, uint16_t len) { if (HAL_I2C_Mem_Read(hi2c1, MAX86150_I2C_ADDR, reg_addr, I2C_MEMADD_SIZE_8BIT, buf, len, 1000) ! HAL_OK) { return -1; } return 0; } int8_t max86150_write_reg(uint8_t reg_addr, uint8_t value) { if (HAL_I2C_Mem_Write(hi2c1, MAX86150_I2C_ADDR, reg_addr, I2C_MEMADD_SIZE_8BIT, value, 1, 1000) ! HAL_OK) { return -1; } return 0; }这里的超时时间我设置成1000ms正常I2C操作很快如果卡住说明总线异常HAL库会返回超时驱动层可以根据返回值做错误计数。实际运行中如果SDA被拉死HAL库重试几次后还是会失败这时要在上层做总线恢复处理最简单的办法是手动翻转SCL发送9个时钟脉冲把挂死的外设时钟状态机复位再重新初始化I2C外设。这个技巧在长跑测试中救过我几次。驱动层建议加一层带锁的访问保护如果代码里多个任务都可能访问MAX86150需要用互斥锁保证寄存器读写是原子的。裸机环境下可以在临界区里操作RTOS环境下挂信号量。我第一版忽略了这个问题导致LED电流配置和FIFO读取偶尔交错明明配置了红光和红外两个LED采集的数据却有一段全是同一个通道的值排查了很久才意识到是读写竞争。3.3 数据读取与FIFO管理MAX86150内部FIFO是驱动读取的关键。芯片会把采样完成的ECG和PPG样本按顺序写入FIFOFIFO满了可以配置成产生中断或者滚动覆盖。我的策略是开FIFO满中断去读。好处是MCU不用高频轮询可以在低功耗模式下睡大觉等数据攒满一批再醒来处理。每个FIFO样本按通道顺序排列我配置成按LED1(红光PPG)、LED2(红外PPG)、ECG的顺序出数据。每个通道的数据位宽在高分辨率模式下是3个字节也就是24bit但有效数据可能是19bit读取时需要做符号扩展或无符号处理。这里要特别注意ECG是有正负的差分信号必须按有符号数解析PPG虽然有符号位但实际处理时通常按无符号相对幅度用。我一开始把ECG当无符号数解析画出来的波形完全不对查了半天才发现是符号扩展的问题。FIFO读取建议采用连续读方式从FIFO_DATA寄存器一次性读出长度为“样本数×通道数×3字节”的数据块然后按顺序解析。这样效率和稳定性都比逐样本读取好很多。下面是我常用的FIFO读取逻辑#define MAX86150_FIFO_DATA 0x05 #define MAX86150_NUM_CHANNELS 3 // LED1 LED2 ECG int8_t max86150_read_fifo(uint8_t *buf, uint16_t samples) { uint16_t bytes_to_read samples * MAX86150_NUM_CHANNELS * 3; if (max86150_read_reg(MAX86150_FIFO_DATA, buf, bytes_to_read) ! 0) { return -1; } return 0; }这里还要额外处理FIFO写指针和读指针。正常流程是发生FIFO满中断后先读FIFO_WRITE_PTR和FIFO_READ_PTR计算当前有效样本数然后把FIFO_READ_PTR更新为最新读指针最后一次性读数据。实际调试中发现如果FIFO满中断来了却长时间不读OVF_COUNTER会一直累加导致数据时间戳对不齐所以应用层要保证中断响应足够快不能让数据积压超过FIFO容量。我在驱动层还专门加了一个FIFO溢出计数统计如果长时间运行后溢出次数持续增长说明MCU处理能力不够或者中断优先级太低需要优化读取策略。这个指标作为驱动稳定性的一个参考非常有用至少能帮你区分是底层丢数还是算法层问题。4. 核心算法ECG和血氧浓度怎么算4.1 ECG原始数据的滤波与预处理ECG原始数据从FIFO读出来之后不能直接拿来算心率和画波形必须在软件里做几级滤波。我实际采集到的ECG信号里有三类典型干扰一是50Hz工频及其谐波二是肌肉电噪声频率范围比较宽三是运动造成的基线漂移频率很低但幅度很大。针对这三类干扰我按顺序做了高通、陷波和低通处理。高通滤波用于去除基线漂移和电极极化电压截止频率一般在0.5Hz左右。这里我用了一阶IIR高通系数算起来简单MCU负担小。公式是 y[n] α * (y[n-1] x[n] - x[n-1])其中α由采样率和截止频率决定。采样率100SPS时α大约0.996我用整数定点实现避免浮点开销。注意这里如果采样率变了α一定要重算否则截止频率会偏波形会明显变形。低通滤波用于去除高频肌肉噪声截止频率我放在100Hz左右。心电信号的主要能量集中在0.05Hz到100Hz之间R波本身比较陡峭高频成分丰富截止频率太低会把R波磨平影响后续R波检测。我测试过150Hz和100Hz两档100Hz对噪声抑制更好R波幅值损失还在可接受范围内最终方案就定型为100Hz。50Hz陷波器专门对付工频干扰。在实验室环境用市电供电时这个滤波器的作用非常明显不加的话ECG波形上会叠加一层细密纹波。我用的双二阶IIR陷波器Q值选1左右带宽不能太宽否则会把附近频段的有用心电成分一起滤掉。具体实现时注意陷波器要在高通和低通之间串联顺序错了也会影响最终波形质量。4.2 R波检测与瞬时心率计算滤波之后的ECG是相对干净的准周期波形下一步是检测R波位置再根据相邻两个R波的时间间隔算出瞬时心率。R波检测我用的是自适应阈值法原理是将ECG信号取绝对值后通过移动窗口积分得到一个平滑的能量包络然后设置一个动态阈值超过阈值且符合不应期约束的峰值点标记为一次R波。阈值更新公式是 threshold 0.5 * peak_value 0.5 * previous_threshold这样能跟随信号幅值缓慢变化防止因为电极贴合松动导致信号变弱时漏检。不应期我设置为200ms这是因为正常心率下两个R波间隔不可能小于200ms超过这个值说明检测到的是T波或者噪声尖峰。这个参数在心率很高的时候要注意如果被测对象是儿童或者运动状态心率可能到180甚至200以上不应期需要适当缩短。瞬时心率计算就是60除以RR间期单位是ppm。但单个RR间期受呼吸和噪声影响波动很大直接显示会有明显跳动我在上层做了一级滑动平均取最近8个RR间期的平均值作为平滑心率。这种方法的滞后性大约2到3秒对可穿戴设备来说完全够用而且比那种用FFT估算心率的方案简单可靠得多。心电波形质量判断也是RC检测里的重要环节。我用信号幅度和基线漂移幅度做比值如果比值太小说明电极接触不良这时候标记为“弱信号”状态算法结果直接不显示避免给出错误心率。这一步在真实佩戴场景下很有价值因为你没法控制用户怎么戴硬件不够好时至少软件要能识别异常。4.3 血氧浓度SpO2计算原理与代码实现血氧浓度计算依赖的是红光和红外两路PPG信号。前面原理说过核心是组合出比值R (AC_red / DC_red) / (AC_IR / DC_IR)。这里的AC分量指的是由于动脉搏动引起的透射光或反射光的周期变化DC分量是皮肤组织、静脉血等对光的恒定吸收成分。MAX86150输出的PPG原始值是一个相对光强值首先要把每一段滑动窗口内的数据分成DC和AC两部分。DC分量可以通过滑动平均或者低通滤波得到时间常数大概1到2秒。AC分量则用原始信号减去DC分量获得。对AC信号再做一次带通滤波去除呼吸和运动造成的低频分量然后计算窗口内AC信号的峰峰值或者RMS值。我实测下来峰峰值算法在高噪声环境下稳定性更好RMS算法更适合波形较平稳的情况最终我选了峰峰值。得到两路AC/DC比值之后R的计算就很简单了。再把R值代入SpO2的经验公式我用的经典线性近似是SpO2 110 - 25 * R。这个公式在R值处于0.4到1.0区间内误差不大超过这个区间后建议改用查表法。MAX86150的应用笔记里会附带一条校准曲线不同LED波长和电路增益下曲线略有差异有条件的话最好用基准血氧仪做一次多点校准校准后的误差能控制到±2%以内。float max86150_calc_spo2(int32_t *red_ac, int32_t *red_dc, int32_t *ir_ac, int32_t *ir_dc) { float ratio ((float)(*red_ac) / (*red_dc)) / ((float)(*ir_ac) / (*ir_dc)); float spo2 110.0f - 25.0f * ratio; if (spo2 100.0f) spo2 100.0f; if (spo2 0.0f) spo2 0.0f; return spo2; }血氧计算的一个关键前提是红光和红外两路PPG的波形必须同步且同相位。MAX86150的FIFO数据是按顺序排放的只要保证每次读取时样本数和通道数对齐两路信号天然同步。但如果你把两路LED电流差值设得太大导致其中一路信号饱和或者过弱那么计算出来的R值就会失真。我调试时发现红光LED电流要明显大于红外LED因为红光在皮肤组织里的穿透和反射效率低需要的驱动电流更大具体电流值要根据佩戴位置实测调整。5. 调试验证与常见问题排查5.1 串口波形可视化和参数打印方案调试生物信号最怕的就是对着一个个数字看波形效率极低。我把MAX86150的原始数据和算法输出通过串口发到上位机用Python的matplotlib做实时绘制能直接看到ECG和PPG波形以及实时心率、血氧数值。这个方案对定位信号质量问题效果特别好比如电极松了、LED电流不合适、采样率不对一眼就能看出来。上位机协议我设计得很简单每帧数据带头部标识、数据长度、时间戳然后是ECG样本、红光PPG样本、红外PPG样本以及算法输出。波特率最好用921600或者更高否则在100SPS采样率下也会出现数据来不及传完的情况。初次调试时我用115200波特率就吃了亏波形一卡一卡的还以为是驱动问题后来才发现是串口带宽不够。Python端绘制时要注意把ECG和PPG分开两个子图坐标轴范围也要自适应因为ECG信号幅度通常在毫伏量级而PPG信号幅度和ADC码值相关两者数量级完全不同混在一个图里会互相压缩。我最后给ECG子图单独做了自动增益调整按最大值动态缩放这样能同时看到细节和整体形态。5.2 常见问题速查表与避坑技巧驱动调试过程中我遇到的问题不少捡典型的几个分享。首先是I2C通信失败或者偶发卡死大概率是硬件连接、上拉电阻和地址模式不匹配。先用I2C扫描程序看看能不能探测到设备地址探测不到就检查电源和焊接探测到了却读写不稳定就检查总线上拉和时序。这类问题出现的频率最高解决起来也最基础。其次是FIFO读出来的数据通道顺序错乱表现为红光和红外波形有一段时间互换。这种情况通常是通道配置多次修改后FIFO里残留了旧配置的数据导致解析端和写入端样本队列没有对齐。解决办法是在修改通道配置后先执行一次FIFO清空或者系统复位再开始正常采样。我在驱动层接口里专门加了一个reset函数每次参数变更后调用再也没出现过这种错乱。ECG波形幅度过小或者50Hz干扰大可以先检查电极贴片位置和皮肤准备再检查右腿驱动是否接好最后调整ECG增益寄存器。如果PPG波形饱和成平顶多半是LED电流太大或者光电二极管接收到的光太强要降低LED电流或增大ADC量程。反过来的情况波形太弱就加大LED电流、减少采样平均或者在FIFO配置里减小平均次数以提高有效输出率。我整理了一个常见问题速查表方便你快速定位问题现象可能原因排查与解决I2C探测不到设备接线错误、虚焊、地址不对检查电源、SDA/SCL上拉确认7位/8位地址模式I2C读写偶发超时总线负载重、电平不匹配降低总线速率检查上拉电阻必要时总线复位FIFO数据通道错乱修改通道后未清FIFO参数变更后执行复位或FIFO清空ECG波形太小电极接触差、增益低重新贴电极调整ECG增益寄存器ECG波形50Hz干扰RLD未接好、屏蔽差检查右腿驱动改善线缆屏蔽和滤波PPG波形饱和平顶LED电流过大、ADC量程不足降低LED电流增加ADC量程血氧值跳变剧烈AC分量提取不稳、LED电流不匹配增大滑动窗口优化两路LED电流配比这些经验都是常规文档里不太会写的但实际开发中真的能救急。另外还有一个小技巧长时间稳定性测试时我给驱动加了一个看门狗机制定时检查FIFO溢出计数和错误计数一旦超过阈值就自动重新初始化传感器。这样项目在跑数据采集任务时就不用担心偶发挂死前一夜挂机跑数据第二天早上看日志就能定位问题。6. 从驱动到产品化的几个延伸建议驱动能稳定输出波形只是第一步真正做产品时还有一个重要环节是运动伪迹抑制。人体活动时传感器和皮肤之间会发生相对位移PPG信号里会出现大幅度的运动干扰ECG也会因为电极移动产生基线骤变和噪声。针对这个我还在算法层加了简单的运动检测逻辑当PPG的AC分量幅度异常增大且波动频率和心率不一致时就判定为运动干扰暂时停止血氧和心率输出等信号恢复稳定再继续计算。这种策略虽然牺牲了连续性但保证了数据可信度。低功耗设计也是可穿戴设备的绕不开的话题。MAX86150驱动里有关断模式可以配置成间歇工作MCU定时唤醒打开传感器采样几秒钟计算完结果后关断传感器再睡。我实测下来在100SPS下连续工作电流约几毫安间歇工作可以把平均电流降到百微安级别。具体低功耗策略要根据产品形态选择但驱动层一定要预留关断和快速恢复的接口否则后续优化功耗非常被动。如果你准备把这个驱动包用在商业化产品上建议把算法层的滤波参数做成可配置的不同用户、不同佩戴部位的信号特征差异挺大。比如手指佩戴和手腕佩戴PPG信号幅度和噪声特征完全不同LED电流和滤波截止频率都需要调整。我会在驱动包里保留一个参数结构体使用者可以根据硬件调试结果灵活调整不用改代码逻辑。回顾整个MAX86150驱动开发过程我觉得最有价值的经验是三层分离的软件设计方法和数据可视化调试手段。前者让我从寄存器配置到算法处理都有清晰的代码边界后者让我能在几分钟内定位信号链路里的问题。最后再分享一个小技巧不要轻信仿真波形一定要拿真实人体数据测试但测试前做好静电保护我有一块板子就是因为没做ESD防护冬天手一摸传感器ECG输入引脚就坏了这点很多初学者容易忽略。本文还有配套的精品资源点击获取
返回列表