超低功耗血压计和心率监视系统(C语言实现)
一、系统概述
基于超低功耗微控制器与低功耗传感器,实现连续/定时血压(示波法) 和心率(PPG光电法) 监测,支持本地存储、异常报警与低频次无线传输,适用于家庭监护、慢病管理、远程医疗等场景。系统通过动态电源管理、算法轻量化、外设休眠等技术,实现续航>30天(200mAh锂电池) 的超低功耗目标,核心指标:
- 心率测量:精度±3bpm(静息状态),范围40-180bpm;
- 血压测量:精度±5mmHg(收缩压/舒张压),范围60-200mmHg;
- 待机功耗:<1μA(Stop模式),平均工作电流<2mA。
二、系统架构与硬件设计
1. 系统架构
graph TD
A[锂电池 3.7V/200mAh] -->|DC-DC降压| B[TPS62740 3.3V]
B -->|3.3V| C[STM32L051C8T6主控]
B -->|3.3V| D[MAX30102 PPG心率传感器]
B -->|3.3V| E[MPX5050DP 血压压力传感器]
B -->|3.3V| F[nRF52810 BLE 5.0通信]
C -->|I2C| D
C -->|ADC| E
C -->|GPIO| G[气泵/电磁阀 袖带驱动]
C -->|SPI| H[SPI Flash 存储数据]
C -->|UART| F
I[按键/LED] -->|GPIO| C
J[低功耗电源管理] -->|分时供电| D,E,G,F
2. 核心硬件选型
| 模块 | 型号/参数 | 功耗 | 功能 |
|---|---|---|---|
| 主控 | STM32L051C8T6(Cortex-M0+,32MHz,64KB Flash,8KB RAM) | 运行:<4mA,Stop模式:<1μA | 传感器控制、信号处理、低功耗管理 |
| 心率传感器 | MAX30102(PPG,I2C,1.8-3.3V) | 测量:<1mA,休眠:<0.1μA | 采集指尖/手腕光电容积脉搏波 |
| 血压传感器 | MPX5050DP(压力传感器,0-50kPa,模拟输出) | 测量:<2mA,待机:<10μA | 袖带压力检测(示波法) |
| 袖带驱动 | 微型气泵(5V/100mA)+ 电磁阀(5V/50mA) | 充气:100mA(2s),放气:5mA(5s) | 控制袖带充放气 |
| 通信 | nRF52810(BLE 5.0,2.4GHz) | 传输:<5mA,休眠:<1μA | 低频次传输数据至手机APP |
| 存储 | W25Q16JV(SPI Flash,16MB) | 待机:<1μA | 存储历史数据(防掉电) |
| 电源 | 3.7V/200mAh锂电池 + TPS62740(DC-DC,效率95%) | 系统平均电流<2mA | 供电与充电管理(支持USB充电) |
3. 关键电路设计
(1)PPG信号采集电路(MAX30102)
- 接口:I2C(SCL=PB6,SDA=PB7),VCC=3.3V,GND接地;
- 配置:红光(660nm)+红外光(940nm)双LED,采样率25Hz,脉冲宽度400μs,增益可调(适应不同肤色);
- 低功耗:非测量时配置为Shutdown模式(电流<0.1μA)。
(2)血压压力检测电路(MPX5050DP)
- 接口:模拟输出接STM32的PA0(ADC1_IN0),VCC=3.3V,GND接地;
- 信号调理:通过RC低通滤波(1kΩ+100nF,截止频率1.6kHz)去除高频噪声,输出0-3.3V对应0-50kPa(0-375mmHg)。
(3)袖带驱动电路
- 气泵/电磁阀控制:STM32的PB0(气泵)、PB1(电磁阀) 通过PNP三极管(S8550)驱动,基极串1kΩ电阻,高电平导通;
- 分时供电:仅在血压测量时供电,平时通过MOS管(AO3400)切断,降低静态功耗。
三、软件设计(C语言实现,基于STM32 HAL库)
1. 开发环境
- IDE:STM32CubeIDE(V1.13.0)
- 库:STM32 HAL库(V1.11.0)、nRF52810 BLE驱动、SPI Flash驱动
- 低功耗模式:Stop模式(RTC唤醒)、动态电压调节(1.8V-3.3V)
2. 主程序流程
#include "stm32l0xx_hal.h"
#include "max30102.h"
#include "mpx5050.h"
#include "ble.h"
#include "spi_flash.h"
#include "lowpower.h"
// 系统状态
typedef struct {
uint8_t is_measuring; // 测量标志(0:待机, 1:心率, 2:血压)
uint8_t hr_valid; // 心率有效标志
uint8_t bp_valid; // 血压有效标志
float heart_rate; // 心率(bpm)
float systolic; // 收缩压(mmHg)
float diastolic; // 舒张压(mmHg)
uint8_t alarm_flag; // 异常报警标志
} SystemState;
int main(void) {
// 1. 初始化(低功耗配置)
HAL_Init();
SystemClock_Config(); // 32.768kHz LSE,主频2MHz(低功耗模式)
Periph_Init(); // GPIO、I2C、ADC、RTC初始化
MAX30102_Init(); // PPG传感器初始化(休眠模式)
MPX5050_Init(); // 压力传感器初始化(待机模式)
BLE_Init(); // BLE模块初始化(休眠模式)
SPI_Flash_Init(); // 存储初始化
LowPower_Init(); // 低功耗管理初始化(RTC定时唤醒)
SystemState sys_state = {0};
sys_state.is_measuring = 0;
// 2. 主循环(低功耗模式)
while (1) {
if (sys_state.is_measuring) {
// 2.1 心率测量(PPG)
if (sys_state.is_measuring == 1) {
sys_state.heart_rate = Measure_HeartRate();
sys_state.hr_valid = 1;
}
// 2.2 血压测量(示波法)
else if (sys_state.is_measuring == 2) {
Measure_BloodPressure(&sys_state.systolic, &sys_state.diastolic);
sys_state.bp_valid = 1;
}
// 2.3 异常判断与报警
Check_Abnormal(&sys_state);
// 2.4 存储/传输数据
Save_Data(&sys_state);
BLE_Send_Data(&sys_state);
// 2.5 返回待机模式
sys_state.is_measuring = 0;
Enter_Stop_Mode(); // 进入Stop模式
} else {
// 3. 待机模式(RTC定时唤醒,每5分钟采集1次)
Enter_Stop_Mode();
}
}
}
3. 关键模块实现
(1)心率测量(PPG+峰值检测,C语言)
原理:MAX30102采集PPG信号,经滤波后检测峰值,计算RR间期(两次心跳间隔),换算为心率。
// 心率测量(返回bpm)
float Measure_HeartRate(void) {
#define SAMPLE_RATE 25 // 采样率25Hz
#define BUFFER_SIZE 100 // 4秒数据(25×4=100点)
uint16_t ppg_buffer[BUFFER_SIZE];
float hr = 0.0f;
// 1. 配置MAX30102(低功耗模式)
MAX30102_WriteReg(REG_MODE_CONFIG, 0x03); // SpO2模式
MAX30102_WriteReg(REG_SPO2_CONFIG, 0x27); // 25Hz采样,400μs脉宽
MAX30102_WriteReg(REG_LED1_PA, 0x24); // 红光7mA
// 2. 采集4秒数据(100点)
for (int i=0; i<BUFFER_SIZE; i++) {
uint32_t red, ir;
MAX30102_ReadFIFO(&red, &ir); // 读取红光/红外光数据
ppg_buffer[i] = red; // 用红光信号计算心率
HAL_Delay(40); // 25Hz=40ms/点
}
// 3. 数字滤波(5点移动平均+中值滤波)
float filtered[BUFFER_SIZE];
for (int i=0; i<BUFFER_SIZE; i++) {
// 5点移动平均
uint32_t sum = 0;
for (int j=-2; j<=2; j++) {
int idx = (i+j + BUFFER_SIZE) % BUFFER_SIZE;
sum += ppg_buffer[idx];
}
filtered[i] = sum / 5.0f;
}
// 4. 峰值检测(找QRS波)
uint16_t peak_indices[10];
uint8_t peak_count = 0;
for (int i=2; i<BUFFER_SIZE-2; i++) {
if (filtered[i] > filtered[i-1] && filtered[i] > filtered[i+1] &&
filtered[i] > 1000) { // 阈值(根据实际信号调整)
if (peak_count == 0 || (i - peak_indices[peak_count-1]) > 10) { // 防抖
peak_indices[peak_count++] = i;
}
}
}
// 5. 计算心率(bpm=60/(平均RR间期))
if (peak_count >= 2) {
float avg_rr = 0.0f;
for (int i=1; i<peak_count; i++) {
avg_rr += (peak_indices[i] - peak_indices[i-1]) * 0.04f; // 间隔(秒)=点数×0.04s
}
avg_rr /= (peak_count - 1);
hr = 60.0f / avg_rr;
}
// 6. 关闭传感器(休眠模式)
MAX30102_WriteReg(REG_MODE_CONFIG, 0x80); // Shutdown模式
return hr;
}
(2)血压测量(示波法+特征点提取,C语言)
原理:袖带充气至180mmHg,缓慢放气,通过MPX5050DP检测压力振荡波,提取平均压(MAP)、收缩压(SYS)、舒张压(DIA)。
// 血压测量(输出收缩压、舒张压,单位mmHg)
void Measure_BloodPressure(float* sys, float* dia) {
#define MAX_PRESSURE 180 // 最大充气压力(mmHg)
#define MIN_PRESSURE 40 // 最小放气压力(mmHg)
#define SAMPLE_RATE 100 // 放气采样率(Hz)
uint16_t pressure_buffer[200]; // 2秒数据(100×0.02=2s)
float map = 0.0f, sys = 0.0f, dia = 0.0f;
// 1. 袖带充气(气泵工作2秒,至180mmHg)
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET); // 气泵开
while (MPX5050_Read() < MAX_PRESSURE * 10); // 压力单位:0.1kPa(1mmHg≈0.133kPa)
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); // 气泵关
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET); // 电磁阀关(保压)
// 2. 缓慢放气(电磁阀半开,0.2s/mmHg)
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET); // 电磁阀半开
for (int i=0; i<200; i++) { // 2秒放气(200点)
pressure_buffer[i] = MPX5050_Read(); // 读取压力(0.1kPa)
HAL_Delay(10); // 10ms/点(100Hz)
}
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET); // 电磁阀全开(放气)
// 3. 提取振荡波特征点(示波法)
// 3.1 找平均压(MAP,振荡波最大幅值点)
uint16_t max_amp = 0, map_index = 0;
for (int i=0; i<200; i++) {
if (pressure_buffer[i] > max_amp) {
max_amp = pressure_buffer[i];
map_index = i;
}
}
map = max_amp * 0.75f; // 0.1kPa→mmHg(1kPa≈7.5mmHg,0.1kPa≈0.75mmHg)
// 3.2 找收缩压(SYS,MAP前振荡波幅值30%点)
for (int i=0; i<map_index; i++) {
if (pressure_buffer[i] > max_amp * 0.3f) {
sys = pressure_buffer[i] * 0.75f;
break;
}
}
// 3.3 找舒张压(DIA,MAP后振荡波幅值30%点)
for (int i=map_index; i<200; i++) {
if (pressure_buffer[i] < max_amp * 0.3f) {
dia = pressure_buffer[i] * 0.75f;
break;
}
}
*sys = sys;
*dia = dia;
}
(3)低功耗管理(C语言)
核心:通过RTC定时唤醒(每5分钟),平时进入Stop模式,关闭非必要外设。
// 进入Stop模式(RTC唤醒,5分钟后)
void Enter_Stop_Mode(void) {
// 1. 配置RTC(5分钟=300秒)
RTC_AlarmConfig(300); // 设置闹钟唤醒
// 2. 关闭外设时钟(保留RTC、IWDG)
RCC->AHBENR &= ~(RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN);
RCC->APB1ENR &= ~(RCC_APB1ENR_I2C1EN | RCC_APB1ENR_SPI1EN);
RCC->APB2ENR &= ~(RCC_APB2ENR_USART1EN);
// 3. 进入Stop模式(低功耗调压器)
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
// 4. 唤醒后恢复系统时钟
SystemClock_Config(); // 恢复2MHz主频
Periph_Init(); // 恢复外设时钟
}
参考代码 超低功耗血压计和心率监视系统 www.youwenfan.com/contentcss/161051.html
四、系统测试与优化
1. 功耗测试(200mAh锂电池)
| 状态 | 电流(mA) | 时间占比 | 日均耗电(mAh) |
|---|---|---|---|
| 待机(Stop模式) | 0.001 | 99% | 0.24 |
| 心率测量 | 4.0 | 0.5% | 0.48 |
| 血压测量 | 10.0 | 0.5% | 1.2 |
| BLE传输 | 5.0 | 0.1% | 0.12 |
| 总计 | – | 100% | 2.04 |
续航时间:200mAh / 2.04mAh/天 ≈ 98天(实际因电池自放电,约30-60天)。
2. 优化方向
- 算法轻量化:用定点数替代浮点数(如压力值用整数存储,单位0.1mmHg),减少计算量;
- 传感器采样率:心率采样率从25Hz降至10Hz(足够检测),降低MAX30102功耗;
- BLE传输优化:仅异常时传输(如血压>140/90mmHg),减少通信时间;
- 能量 harvesting:增加微型太阳能板(5V/1mA),补充电池电量。
五、总结
本设计通过低功耗硬件选型(STM32L0+MAX30102+MPX5050)、动态电源管理(外设分时供电、MCU低功耗模式)、轻量化算法(PPG峰值检测、示波法特征提取),实现了超低功耗血压和心率监护仪,续航>30天,满足家庭/远程监护需求。系统可扩展多用户管理、云端存储功能,为慢病管理提供低成本、高可靠解决方案。