news 2026/4/30 1:43:41

MAX30102 + STM32 人体血氧饱和度(SpO₂)测量方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MAX30102 + STM32 人体血氧饱和度(SpO₂)测量方案

一、系统核心原理

1.1 测量原理(PPG光电容积描记法)

MAX30102 包含两个LED(红光660nm红外光880nm)和一个光电探测器。

  • 血红蛋白对不同波长光的吸收率不同
    • 氧合血红蛋白(HbO₂)吸收更多的红外光
    • 脱氧血红蛋白(Hb)吸收更多的红光
  • 计算公式
    SpO2=110−25×R SpO_2 = 110 - 25 \times RSpO2=11025×R
    其中R值(调制比率)是关键:
    R=ACred/DCredACir/DCir R = \frac{AC_{red}/DC_{red}}{AC_{ir}/DC_{ir}}R=ACir/DCirACred/DCred
    • ACACAC:脉搏波的交流成分(动态变化,代表心跳)。
    • DCDCDC:直流成分(静态基线,代表组织吸收和外界光)。

1.2 硬件连接表

MAX30102STM32F103C8T6说明
VIN3.3V电源输入
GNDGND共地
SDAPB7I2C1数据线(需4.7k上拉)
SCLPB6I2C1时钟线(需4.7k上拉)
INTPA0中断引脚(低电平有效,可选)
RDNC未使用

二、STM32驱动与算法实现

2.1 核心宏定义与变量(max30102.h

#ifndef__MAX30102_H#define__MAX30102_H#include"stm32f10x.h"#include"i2c.h"// 假设已有I2C底层驱动// MAX30102 寄存器地址#defineMAX30102_INT_STATUS0x00#defineMAX30102_FIFO_DATA0x07#defineMAX30102_FIFO_CONF0x08#defineMAX30102_MODE_CONF0x09#defineMAX30102_SPO2_CONF0x0A#defineMAX30102_LED_CONF0x0C#defineMAX30102_PART_ID0xFF// 算法相关#defineFIFO_DEPTH32// FIFO深度#defineSAMPLE_RATE100// 采样率100Hz#defineBUFFER_SIZE100// 数据处理缓冲区// 全局变量externvolatileuint32_tir_buffer[BUFFER_SIZE];externvolatileuint32_tred_buffer[BUFFER_SIZE];externvolatileuint8_tfifo_wptr;voidMAX30102_Init(void);voidMAX30102_ReadFIFO(void);floatMAX30102_CalcSpO2(void);#endif

2.2 传感器初始化(max30102.c

#include"max30102.h"#include"delay.h"#include"usart.h"volatileuint32_tir_buffer[BUFFER_SIZE];volatileuint32_tred_buffer[BUFFER_SIZE];volatileuint8_tdata_ready=0;/** * @brief MAX30102初始化 */voidMAX30102_Init(void){uint8_tpart_id;// 1. 读取Part ID,确认通信正常part_id=I2C_ReadReg(MAX30102_PART_ID);printf("MAX30102 Part ID: 0x%02X\r\n",part_id);// 2. 复位传感器I2C_WriteReg(0x09,0x40);// MODE_CONFIG: RESET=1Delay_ms(10);// 3. 配置FIFOI2C_WriteReg(MAX30102_FIFO_CONF,0x0F);// FIFO_A_FULL=0, FIFO_ROLLOVER_EN=1// 4. 配置模式:SpO2模式I2C_WriteReg(MAX30102_MODE_CONF,0x03);// MODE=011 (SpO2 mode)// 5. 配置SpO2:100Hz采样,411us脉宽,18位分辨率I2C_WriteReg(MAX30102_SPO2_CONF,0x27);// SPO2_ADC_RGE=01(411us), SPO2_SR=111(100Hz)// 6. 配置LED电流(非常重要!)// 红光: 6.4mA, 红外: 6.4mA (根据手指透光率调整)I2C_WriteReg(MAX30102_LED_CONF,0x24);// LED1_PA=0x2, LED2_PA=0x4// 7. 清中断I2C_ReadReg(MAX30102_INT_STATUS);printf("MAX30102 Init OK!\r\n");}/** * @brief 读取FIFO数据 */voidMAX30102_ReadFIFO(void){uint8_tfifo_data[6];staticuint8_tbuf_index=0;// 读取3个字节的RED数据 + 3个字节的IR数据I2C_ReadMulti(MAX30102_FIFO_DATA,fifo_data,6);// 拼接数据 (18-bit)red_buffer[buf_index]=((uint32_t)fifo_data[0]<<16)|((uint32_t)fifo_data[1]<<8)|(uint32_t)fifo_data[2];red_buffer[buf_index]&=0x3FFFF;// 掩码18位ir_buffer[buf_index]=((uint32_t)fifo_data[3]<<16)|((uint32_t)fifo_data[4]<<8)|(uint32_t)fifo_data[5];ir_buffer[buf_index]&=0x3FFFF;buf_index++;if(buf_index>=BUFFER_SIZE){buf_index=0;data_ready=1;// 标记数据已满,可以进行计算}}

2.3 核心算法:血氧计算(spo2_algorithm.c

这是最关键的部分,包含滤波和峰值检测。

#include"max30102.h"#include"math.h"// 滑动平均滤波器staticvoidMovingAverageFilter(uint32_t*input,float*output,intsize){intwindow=5;for(inti=window;i<size;i++){floatsum=0;for(intj=0;j<window;j++){sum+=input[i-j];}output[i]=sum/window;}}// 直流分量提取(低通滤波)staticfloatExtractDC(float*signal,intsize){floatsum=0;for(inti=0;i<size;i++){sum+=signal[i];}returnsum/size;}// 交流分量提取(去除直流后的峰值检测)staticfloatExtractAC(float*signal,intsize){floatdc=ExtractDC(signal,size);floatmax_val=signal[0];floatmin_val=signal[0];for(inti=0;i<size;i++){if(signal[i]>max_val)max_val=signal[i];if(signal[i]<min_val)min_val=signal[i];}return(max_val-min_val);// AC幅度 = 峰峰值}/** * @brief 计算血氧饱和度 */floatMAX30102_CalcSpO2(void){floatred_filtered[BUFFER_SIZE];floatir_filtered[BUFFER_SIZE];if(!data_ready)return0;// 1. 滑动平均滤波去噪MovingAverageFilter((uint32_t*)red_buffer,red_filtered,BUFFER_SIZE);MovingAverageFilter((uint32_t*)ir_buffer,ir_filtered,BUFFER_SIZE);// 2. 计算R值floatred_ac=ExtractAC(red_filtered,BUFFER_SIZE);floatred_dc=ExtractDC(red_filtered,BUFFER_SIZE);floatir_ac=ExtractAC(ir_filtered,BUFFER_SIZE);floatir_dc=ExtractDC(ir_filtered,BUFFER_SIZE);if(red_dc==0||ir_dc==0)return0;floatR=(red_ac/red_dc)/(ir_ac/ir_dc);// 3. 转换为SpO2(经验公式,需校准)floatspo2=110.0f-25.0f*R;// 限制范围if(spo2>100.0f)spo2=100.0f;if(spo2<70.0f)spo2=0.0f;returnspo2;}

2.4 主程序调用(main.c

#include"stm32f10x.h"#include"delay.h"#include"usart.h"#include"i2c.h"#include"max30102.h"intmain(void){floatspo2_value;uint32_theart_rate=0;// 系统初始化Delay_Init();USART_Init(115200);I2C_Init();printf("System Start...\r\n");// 传感器初始化MAX30102_Init();while(1){// 读取FIFO数据MAX30102_ReadFIFO();// 数据满了就计算if(data_ready){spo2_value=MAX30102_CalcSpO2();// 输出结果printf("SpO2: %.1f%%, HR: %lu BPM\r\n",spo2_value,heart_rate);data_ready=0;// 清空标志位}Delay_ms(10);// 控制循环速度}}

参考代码 使用MAX30102搭配stm32开发板对人体血氧饱和度进行测量www.youwenfan.com/contentcsu/56129.html

三、关键调试与校准指南

3.1 常见问题排查

现象原因解决方案
读数一直为0LED电流太小增大LED_CONF寄存器值(如0x7F对应最大电流)
读数跳动剧烈手指未压紧或漏光使用遮光罩,手指用力按压传感器
血氧低于90%环境光干扰确保传感器被完全覆盖,避免强光直射
FIFO溢出读取速度太慢提高I2C时钟(400kHz),或增加FIFO中断

3.2 校准方法

  1. 基准校准:使用医用级指夹血氧仪作为基准,对比你的设备读数。
  2. 公式微调
    • 如果你的读数普遍偏高:增大公式中的25.0f系数。
    • 如果你的读数普遍偏低:减小公式中的25.0f系数。
  3. 分段校准:不同的人种、肤色对光的吸收率不同,建议在85%-99%区间分别校准。

3.3 硬件优化建议

  1. 遮光处理:MAX30102必须配合黑色硅胶指套使用,否则环境光会淹没微弱的血氧信号。
  2. 电源稳定性:在VIN引脚并联100nF和10µF电容,防止电源噪声导致数据抖动。
  3. 手指接触:确保手指指甲盖朝上,指腹紧贴传感器透镜,不要用力按压导致血流阻断。

四、总结

本方案实现了基于STM32和MAX30102的完整血氧监测系统。核心难点不在于I2C驱动,而在于信号处理算法。实际应用中,建议加入心率计算(通过PPG间期)运动伪影消除算法,以获得更稳定的医疗级数据。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/30 1:41:34

告别数据丢失焦虑:用DiskGenius给老硬盘MBR转GPT的保姆级图文教程

告别数据丢失焦虑&#xff1a;用DiskGenius给老硬盘MBR转GPT的保姆级图文教程 老旧硬盘里的数据就像一本本珍贵的相册&#xff0c;承载着无数回忆。当我们需要将这些"记忆宝库"迁移到新设备时&#xff0c;MBR分区格式往往会成为绊脚石。本文将手把手教你如何用DiskGe…

作者头像 李华
网站建设 2026/4/30 1:28:33

终极指南:用Cursor-Free-VIP轻松绕过API限制,免费享受Pro功能

终极指南&#xff1a;用Cursor-Free-VIP轻松绕过API限制&#xff0c;免费享受Pro功能 【免费下载链接】cursor-free-vip [Support 0.45]&#xff08;Multi Language 多语言&#xff09;自动注册 Cursor Ai &#xff0c;自动重置机器ID &#xff0c; 免费升级使用Pro 功能: Youv…

作者头像 李华
网站建设 2026/4/30 1:27:22

从零到一:解密Pixelle-Video如何用AI引擎重塑短视频创作范式

从零到一&#xff1a;解密Pixelle-Video如何用AI引擎重塑短视频创作范式 【免费下载链接】Pixelle-Video &#x1f680; AI 全自动短视频引擎 | AI Fully Automated Short Video Engine 项目地址: https://gitcode.com/GitHub_Trending/pi/Pixelle-Video 在内容创作领域…

作者头像 李华
网站建设 2026/4/30 1:16:23

ARM异常处理与ESR寄存器深度解析

1. ARM异常处理机制概述 在ARMv8/v9架构中&#xff0c;异常处理是处理器响应硬件或软件事件的核心机制。当发生中断、系统调用、指令执行错误等事件时&#xff0c;处理器会暂停当前执行流&#xff0c;跳转到预设的异常向量表处执行对应的处理程序。异常处理涉及多个关键组件协同…

作者头像 李华
网站建设 2026/4/30 1:12:38

KH Coder:5分钟掌握零代码文本挖掘,多语言内容分析利器

KH Coder&#xff1a;5分钟掌握零代码文本挖掘&#xff0c;多语言内容分析利器 【免费下载链接】khcoder KH Coder: for Quantitative Content Analysis or Text Mining 项目地址: https://gitcode.com/gh_mirrors/kh/khcoder 面对海量文本数据&#xff0c;您是否感到无…

作者头像 李华