多功能医疗健康手表(心率/体温/计步)C语言实现
一、系统概述
基于低功耗嵌入式系统,实现一款集心率测量、体温检测、计步功能于一体的医疗健康手表。核心采用STM32L051C8T6(Cortex-M0+,32MHz,超低功耗)为主控,搭配PPG心率传感器(MAX30102)、红外体温传感器(MLX90614)、三轴加速度计(ADXL345),通过I2C/SPI接口通信,结合信号滤波、特征提取算法实现健康数据监测,支持OLED显示、按键交互和低功耗续航(目标:7天续航)。
二、硬件设计
2.1 核心组件
| 模块 | 型号/参数 | 功能说明 |
|---|---|---|
| 主控 | STM32L051C8T6(64KB Flash,8KB RAM) | 传感器驱动、数据处理、低功耗管理、显示控制 |
| 心率传感器 | MAX30102(I2C,红光+红外LED,PPG) | 采集光电容积脉搏波信号,计算心率(BPM) |
| 体温传感器 | MLX90614(I2C,非接触红外) | 测量体表温度(精度±0.5℃,范围32~42℃) |
| 加速度计 | ADXL345(I2C/SPI,±16g,13位分辨率) | 检测三轴加速度,实现计步功能 |
| 显示模块 | 0.96寸OLED(I2C,SSD1306) | 显示心率、体温、步数、电量等状态 |
| 电源 | 3.7V/200mAh锂电池+TP4056充电管理 | 供电与充电控制,支持低功耗模式 |
2.2 硬件连接
| 模块 | 引脚(STM32L051C8T6) | 通信接口 | 说明 |
|---|---|---|---|
| MAX30102 | PB6(SCL)、PB7(SDA) | I2C1 | 心率信号采集(PPG波形) |
| MLX90614 | PB6(SCL)、PB7(SDA) | I2C1 | 体温数据读取(目标温度) |
| ADXL345 | PB10(SCL)、PB11(SDA) | I2C2 | 三轴加速度采集(计步用) |
| OLED | PB6(SCL)、PB7(SDA) | I2C1 | 显示数据(共享I2C1总线) |
| 按键 | PA0(模式切换)、PA1(确认) | GPIO | 用户交互 |
三、软件设计(C语言+HAL库)
3.1 开发环境
-
IDE:STM32CubeIDE 1.13.0+
-
库:STM32Cube_FW_L0_V1.12.0(HAL库,低功耗优化)
-
工具链:GCC ARM Embedded
3.2 系统架构
3.3 核心代码实现
3.3.1 传感器驱动(I2C通信)
MAX30102心率传感器驱动
#include "max30102.h"
#include "i2c.h"
// 写寄存器
void MAX30102_WriteReg(uint8_t reg, uint8_t data) {
HAL_I2C_Mem_Write(&hi2c1, MAX30102_ADDR, reg, I2C_MEMADD_SIZE_8BIT, &data, 1, 100);
}
// 读寄存器
uint8_t MAX30102_ReadReg(uint8_t reg) {
uint8_t data;
HAL_I2C_Mem_Read(&hi2c1, MAX30102_ADDR, reg, I2C_MEMADD_SIZE_8BIT, &data, 1, 100);
return data;
}
// 初始化(配置采样率、LED电流)
void MAX30102_Init(void) {
MAX30102_WriteReg(REG_INTR_ENABLE_1, 0xC0); // 使能FIFO满/新数据中断
MAX30102_WriteReg(REG_FIFO_CONFIG, 0x4F); // 采样率100Hz,FIFO水位16
MAX30102_WriteReg(REG_MODE_CONFIG, 0x03); // 心率模式(红光+红外)
MAX30102_WriteReg(REG_SPO2_CONFIG, 0x27); // 100Hz采样,100μs脉宽
MAX30102_WriteReg(REG_LED1_PA, 0x24); // 红光LED电流(7.2mA)
MAX30102_WriteReg(REG_LED2_PA, 0x24); // 红外LED电流(7.2mA)
}
ADXL345加速度计驱动(计步用)
#include "adxl345.h"
#include "i2c.h"
// 读取三轴加速度(单位:g,1g=9.8m/s²)
void ADXL345_ReadAccel(float *ax, float *ay, float *az) {
uint8_t data[6];
HAL_I2C_Mem_Read(&hi2c2, ADXL345_ADDR, REG_DATAX0, I2C_MEMADD_SIZE_8BIT, data, 6, 100);
*ax = (int16_t)(data[1]<<8 | data[0]) * 0.004f; // 13位分辨率,±16g→4mg/LSB
*ay = (int16_t)(data[3]<<8 | data[2]) * 0.004f;
*az = (int16_t)(data[5]<<8 | data[4]) * 0.004f;
}
3.3.2 核心算法实现
(1)心率检测算法(PPG信号处理)
步骤:PPG波形采集→带通滤波(0.55Hz,对应30300BPM)→峰值检测→计算心率。
// 带通滤波(IIR滤波器,去除运动噪声)
#define FILTER_ORDER 2
float iir_filter(float x, float *x_history, float *y_history, float *a, float *b) {
float y = 0;
for (int i=0; i<FILTER_ORDER+1; i++) {
y += b[i] * x_history[i];
if (i>0) y -= a[i] * y_history[i-1];
}
// 更新历史数据
for (int i=FILTER_ORDER; i>0; i--) x_history[i] = x_history[i-1];
x_history[0] = x;
for (int i=FILTER_ORDER-1; i>0; i--) y_history[i] = y_history[i-1];
y_history[0] = y;
return y;
}
// 心率计算(峰值检测法)
uint8_t calculate_heart_rate(float *ppg_data, uint16_t len) {
float threshold = 0.3f; // 峰值检测阈值(归一化后)
uint8_t peaks = 0;
for (uint16_t i=1; i<len-1; i++) {
if (ppg_data[i] > ppg_data[i-1] && ppg_data[i] > ppg_data[i+1] && ppg_data[i] > threshold) {
peaks++;
}
}
return (peaks * 60) / (len / 100); // 100Hz采样,len=100→1秒数据,心率=peaks*60
}
(2)计步算法(加速度特征提取)
步骤:三轴加速度合成→低通滤波(去除高频噪声)→检测步态特征(波峰+波谷,步频1~3Hz)→累计步数。
// 计步检测(基于加速度模值变化)
uint16_t step_count = 0;
float last_accel = 0;
uint32_t last_step_time = 0;
void detect_step(float ax, float ay, float az) {
float accel = sqrtf(ax*ax + ay*ay + az*az); // 合成加速度模值
float delta = accel - last_accel;
last_accel = accel;
// 检测波峰(上升沿+阈值)
if (delta > 0.3f && HAL_GetTick() - last_step_time > 300) { // 步频<3Hz(300ms/步)
step_count++;
last_step_time = HAL_GetTick();
}
}
3.3.3 主程序流程(低功耗设计)
int main(void) {
HAL_Init();
SystemClock_Config(); // 32MHz HSI
MX_I2C1_Init(); // OLED+MAX30102+MLX90614
MX_I2C2_Init(); // ADXL345
MX_GPIO_Init(); // 按键+LED
OLED_Init(); // 显示初始化
// 传感器初始化
MAX30102_Init();
MLX90614_Init();
ADXL345_Init();
while (1) {
// 1. 采集数据(每2秒一次,降低功耗)
float heart_rate = read_heart_rate(); // 调用MAX30102+心率算法
float temp = MLX90614_ReadTemp(); // 读取体温
float ax, ay, az;
ADXL345_ReadAccel(&ax, &ay, &az);
detect_step(ax, ay, az); // 计步
// 2. 显示数据
OLED_ShowHeartRate(heart_rate);
OLED_ShowTemp(temp);
OLED_ShowStep(step_count);
// 3. 低功耗休眠(5秒,通过RTC闹钟唤醒)
HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 5, RTC_WAKEUPCLOCK_CK_SPRE_16BITS);
HAL_SuspendTick();
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
SystemClock_Config(); // 唤醒后恢复时钟
HAL_ResumeTick();
}
}
参考代码 心率、体温测量并计步的多功能医疗健康手表 www.youwenfan.com/contentcnt/160724.html
四、关键问题与解决方案
4.1 心率测量抗干扰
-
问题:运动导致PPG波形失真(运动伪影)。
-
解决:
-
硬件:MAX30102增加皮肤接触检测(IR反射强度);
-
软件:采用自适应滤波(如LMS算法),用加速度计数据补偿运动噪声。
4.2 计步精度优化
-
问题:误检(如手臂摆动)或漏检(慢走)。
-
解决:
-
设定步频范围(0.53Hz)和**加速度变化阈值**(0.3g2g);
-
增加状态机(行走/静止/跑步),通过连续3个波峰确认一步。
4.3 低功耗设计
-
问题:传感器和MCU功耗高,续航短。
-
解决:
-
传感器:非采集时进入休眠模式(如MAX30102的
SHUTDOWN位); -
MCU:使用
STOP模式(功耗<1μA),通过RTC或按键中断唤醒; -
显示:OLED采用间歇显示(每5秒刷新一次)。
五、测试与验证
-
心率测试:对比医用指夹式血氧仪,误差<5BPM(静息状态);
-
体温测试:对比水银温度计,误差<0.3℃(额头测量);
-
计步测试:模拟步行1公里(约1300步),误差<5%;
-
功耗测试:待机电流<2mA,续航>7天(200mAh电池)。
六、总结
通过多传感器融合和低功耗嵌入式开发,实现了心率、体温、计步三大核心功能。软件上采用信号滤波+特征提取算法保证数据精度,硬件上通过低功耗器件+休眠模式延长续航,可扩展至血压、血氧等更多健康指标监测。
浙公网安备 33010602011771号