李军主席一行深入区县调研妇女儿童工作(图)

血氧仪开发套件 血氧仪开发套件
1. 血氧饱和度测量(40%~100%,精度 ±2%@70%~100%)
技术指标解析
测量范围:覆盖临床紧急低氧(40%)到正常(100%)场景,满足 ICU 重症监护与家庭健康监测需求;
精度分级:70%~100% 时 ±2%(临床诊断级),40%~70% 时 ±4%(低氧预警级),符合 YY/T 0784-2010 行业标准。
STM32 方案实现
硬件基础:12 位 ADC(ADS1258)采集光信号,分辨率达 0.08mV(3.3V 参考电压);双波长 LED(660nm 红光 / 940nm 近红外)分时驱动,减少环境光干扰。
软件算法:采用 Beer-Lambert 定律结合校准系数查表法,如前文中SPO2_Calculate函数通过 AC/DC 比值计算 SpO2;动态温度补偿:内置温度传感器修正光吸收系数随温度的漂移。
2. 脉率测量(30~250bpm,精度 ±1bpm)
技术指标解析
范围覆盖:从新生儿静息心率(30bpm)到运动极限心率(250bpm);
精度控制:±1bpm 满足临床心率变异性(HRV)分析需求。
STM32 方案实现
信号处理:带通滤波提取脉搏波频率(0.5~5Hz),抑制运动伪影;峰值检测算法(如前文中PulseRate_Detect函数)结合滑动平均滤波(8 点缓冲),消除异常脉冲。
抗干扰设计:采用自适应阈值跟踪脉搏波幅度变化,避免弱信号漏检;周期校验机制:若相邻脉率差 > 20%,则丢弃该次测量结果。
3. 弱信号处理(弱灌注强度≤0.3%)
技术指标解析
灌注指数(PI):≤0.3% 表示极弱血流(如失血性休克、低温症),传统设备易测量失败。
STM32 方案实现
硬件增强:高增益仪表运放(ISL28470)放大微弱光电流信号,增益可达 1000 倍;低噪声电源(ISL9001)抑制纹波对前端信号的干扰。
软件优化:自适应增益控制:当 PI<1% 时,自动提高 LED 驱动电流(如前文中NLAS4053模拟开关调节);小波变换去噪:分解信号至不同频段,保留脉搏波特征分量。
4. 彩色 OLED 同屏显示
功能架构
显示内容:数值区:SpO2(大字体突出)、脉率、PI 值;波形区:实时脉搏波(128 点趋势图);状态区:电池电量、信号质量图标。
STM32 驱动方案:SPI 接口控制 OLED 驱动 IC(如 SSD1351),刷新率≥25fps;动态刷新率调节:弱信号时提高刷新率至 50fps,增强波形稳定性。
5. 无信号自动关机
功耗管理逻辑
检测机制:连续 20 秒检测到 PI<0.2% 且 SpO2 值固定不变(如 40%),判定为无有效信号;硬件 watchdog(X5043)监控 MCU 运行状态,防止程序卡死导致功耗异常。
低功耗实现:STM32 进入 STANDBY 模式,功耗 < 10μA;切断 LED、OLED 等外设电源,仅保留 RTC(ISL12022M)计时。

6. 历史数据存储与管理
存储架构
硬件配置:串行 Flash(M25P16,16Mbit)可保存≥2000 条记录(每条含 SpO2、脉率、时间戳);I2C 接口 EEPROM(M24C64)存储校准参数与用户配置。
软件功能:周期性存储:每 5 分钟自动保存一次数据,支持手动触发保存;数据管理:支持按日期查询、删除指定记录,FIFO 循环覆盖旧数据。
7. 屏幕旋转功能
实现方案
硬件:三轴加速度传感器(LIS33DE)检测设备姿态,分辨率达 ±2g;
程序示例:基于 STM32F103 的血氧仪数据处理
以下是核心功能的 C 语言实现(使用 HAL 库):
/* 头文件与宏定义 */#include "stm32f10x_hal.h"#include "math.h"#define SAMPLE_RATE 1000 // 采样率1kHz#define BUFFER_DEPTH 256 // 数据缓冲区深度#define RED_LED_PORT GPIOA // 红光LED端口#define RED_LED_PIN GPIO_PIN_0 #define IR_LED_PORT GPIOA // 近红外LED端口#define IR_LED_PIN GPIO_PIN_1#define ADC_CHANNEL_RED 0 // 红光ADC通道#define ADC_CHANNEL_IR 1 // 近红外ADC通道/* 全局变量 */ADC_HandleTypeDef hadc;
DMA_HandleTypeDef hdma_adc;uint16_t adcBuffer[2][BUFFER_DEPTH]; // ADC数据缓冲区 {红光, 近红外}float redSignal[BUFFER_DEPTH]; // 红光信号float irSignal[BUFFER_DEPTH]; // 近红外信号uint8_t spo2Value = 97; // 血氧饱和度uint16_t pulseRate = 72; // 脉率(bpm)uint8_t perfusionIndex = 0; // 灌注指数/* 函数声明 */void SystemInit(void);void MX_GPIO_Init(void);void MX_ADC_Init(void);void MX_DMA_Init(void);void SPO2_Calculate(void);void PulseRate_Detect(void);void OLED_Display(void);void PowerManagement_Check(void);/* 主函数 */int main(void){ /* 系统初始化 */
HAL_Init();
SystemInit();
/* 外设初始化 */
MX_GPIO_Init();
MX_ADC_Init();
MX_DMA_Init();
/* 启动ADC_DMA传输 */
HAL_ADC_Start_DMA(&hadc, (uint32_t*)adcBuffer, 2 * BUFFER_DEPTH);
/* 主循环 */
while (1)
{ /* 血氧与脉率计算 */
SPO2_Calculate();
PulseRate_Detect();
/* 显示数据 */
OLED_Display();
/* 低功耗检查 */
PowerManagement_Check();
/* 延时处理 */
HAL_Delay(10);
}
}/* ADC初始化 */void MX_ADC_Init(void){
ADC_ChannelConfTypeDef sConfig = {0};
hadc.Instance = ADC1;
hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
hadc.Init.EOCSelection = ADC_EOC_SEQ_CONV;
hadc.Init.ContinuousConvMode = ENABLE;
hadc.Init.NbrOfConversion = 2; // 红光+近红外双通道
HAL_ADC_Init(&hadc); /* 配置红光通道 */
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;
HAL_ADC_ConfigChannel(&hadc, &sConfig);
/* 配置近红外通道 */
sConfig.Channel = ADC_CHANNEL_1;
HAL_ADC_ConfigChannel(&hadc, &sConfig);
}/* 血氧饱和度计算 */void SPO2_Calculate(void){ static float redAC[BUFFER_DEPTH], redDC[BUFFER_DEPTH]; static float irAC[BUFFER_DEPTH], irDC[BUFFER_DEPTH]; float ratio, spo2;
/* 1. 转换ADC值为电压信号(假设参考电压3.3V) */
for (uint16_t i = 0; i < BUFFER_DEPTH; i++) {
redSignal[i] = (float)adcBuffer[0][i] * 3.3f / 4096.0f;
irSignal[i] = (float)adcBuffer[1][i] * 3.3f / 4096.0f;
}
/* 2. 分离AC和DC分量(简化版,实际需滤波) */
for (uint16_t i = 0; i < BUFFER_DEPTH; i++) {
redDC[i] = redSignal[i] * 0.95f + redDC[i] * 0.05f; // 一阶低通滤波求DC
redAC[i] = redSignal[i] - redDC[i]; // AC分量
irDC[i] = irSignal[i] * 0.95f + irDC[i] * 0.05f;
irAC[i] = irSignal[i] - irDC[i];
}
/* 3. 计算AC/DC比值 */
float sumRedAC = 0, sumRedDC = 0; float sumIrAC = 0, sumIrDC = 0; for (uint16_t i = 0; i < BUFFER_DEPTH; i++) {
sumRedAC += fabs(redAC[i]);
sumRedDC += fabs(redDC[i]);
sumIrAC += fabs(irAC[i]);
sumIrDC += fabs(irDC[i]);
}
float ratioRed = sumRedAC / sumRedDC; float ratioIr = sumIrAC / sumIrDC;
/* 4. 计算灌注指数(PI) */
perfusionIndex = (uint8_t)((ratioRed + ratioIr) * 10);
/* 5. 根据Beer-Lambert定律计算SpO2(简化公式) */
ratio = ratioRed / ratioIr; if (ratio > 1.0f) ratio = 1.0f / ratio; // 范围限定
spo2 = 94.0f - 25.0f * ratio; // 经验公式,实际需校准
/* 6. 结果校准与限幅 */
if (spo2 > 100) spo2 = 100; if (spo2 < 40) spo2 = 40;
spo2Value = (uint8_t)spo2;
}/* 脉率检测 */void PulseRate_Detect(void){ static uint32_t lastPeakTime = 0; static float peakBuffer[8] = {0}; static uint8_t peakIndex = 0; uint32_t currentTime = HAL_GetTick(); float maxAmplitude = 0; uint16_t peakPosition = 0;
/* 1. 寻找脉搏波峰值(简化版,实际需带通滤波) */
for (uint16_t i = 0; i < BUFFER_DEPTH; i++) { if (redSignal[i] > maxAmplitude) {
maxAmplitude = redSignal[i];
peakPosition = i;
}
}
/* 2. 计算脉搏周期(需排除异常峰值) */
if (maxAmplitude > 0.1f && currentTime - lastPeakTime > 300 && currentTime - lastPeakTime < 2000) { uint32_t periodMs = currentTime - lastPeakTime;
pulseRate = (uint16_t)(60000.0f / periodMs); // ms转bpm
lastPeakTime = currentTime;
/* 3. 滑动平均滤波,平滑脉率显示 */
peakBuffer[peakIndex] = pulseRate;
peakIndex = (peakIndex + 1) % 8;
float avgPulse = 0; for (uint8_t i = 0; i < 8; i++) {
avgPulse += peakBuffer[i];
}
pulseRate = (uint16_t)(avgPulse / 8);
}
}/* OLED显示函数 */void OLED_Display(void){ /* 实际项目中需调用OLED驱动库 */
char displayBuf[32];
/* 显示血氧饱和度 */
sprintf(displayBuf, "SpO2: %d%%", spo2Value);
OLED_DrawString(0, 0, displayBuf);
/* 显示脉率 */
sprintf(displayBuf, "PR: %dbpm", pulseRate);
OLED_DrawString(0, 20, displayBuf);
/* 显示灌注指数 */
sprintf(displayBuf, "PI: %d", perfusionIndex);
OLED_DrawString(0, 40, displayBuf);
/* 绘制简化脉搏波形 */
for (uint16_t i = 0; i < 128; i++) { uint16_t point = i * BUFFER_DEPTH / 128; uint8_t y = (uint8_t)(redSignal[point] * 30 + 50);
OLED_DrawPoint(i, y);
}
}/* 低功耗管理 */void PowerManagement_Check(void){ static uint32_t noSignalTime = 0; static uint8_t signalStatus = 0;
/* 1. 检测信号有效性(通过灌注指数判断) */
if (perfusionIndex > 1) {
signalStatus = 1;
noSignalTime = HAL_GetTick();
} else { if (signalStatus) {
signalStatus = 0;
noSignalTime = HAL_GetTick();
}
}
/* 2. 无信号超过20秒则关机 */
if (!signalStatus && HAL_GetTick() - noSignalTime > 20000) { /* 关闭外设,进入待机模式 */
HAL_ADC_Stop_DMA(&hadc);
HAL_GPIO_WritePin(RED_LED_PORT, RED_LED_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(IR_LED_PORT, IR_LED_PIN, GPIO_PIN_RESET);
OLED_PowerOff();
/* 进入低功耗模式 */
HAL_PWR_EnterSTANDBYMode();
}
}
应用场景:支持手持、桌面等多场景使用,自动适配显示方向。
功能协同与临床价值示意图

典型应用案例
秦皇岛康泰医学:采用 STM32F101C6T6 方案,结合 LIS33DE 与 M25P80 Flash,实现 24 小时连续监测,数据可通过 USB 导出至医院 HIS 系统;
北京超思电子:在远程血氧监护仪中加入 4G 通信模块,当 SpO2<90% 且持续 5 分钟时,自动向家属手机推送报警信息,结合历史数据存储功能,支持医生远程调阅趋势图。
技术对比表(STM32 方案 vs 传统方案)
功能点 | STM32 方案优势 | 传统方案局限 |
弱信号处理 | 自适应增益 + 小波去噪,PI≤0.3% 可用 | PI<1% 时测量失效 |
数据存储 | 16Mbit Flash 支持 7 天连续记录 | 仅保存最近 200 条记录 |
屏幕旋转 | 实时姿态检测,用户体验更友好 | 固定方向显示,视角受限 |
功耗控制 | STANDBY 模式 < 10μA,续航≥15 小时 | 待机功耗 > 50μA,续航 < 8 小时 |
评论