ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

基于STM32的心率计步系统设计:从传感器到算法的嵌入式实践

2026/9/4 18:59:39 拓冰建站 浏览量
基于STM32的心率计步系统设计:从传感器到算法的嵌入式实践 简介本资源是一套完整的毕业设计级嵌入式健康监测系统方案面向电子信息、自动化及物联网方向的本科生与毕设开发者解决心率脉搏实时采集、运动计步与移动端可视化联动的实际工程问题。项目采用STM32F103为主控集成SW-1801P振动传感器实现步数检测MAX30102光学传感器完成心率与脉搏波形采集并通过HC-05蓝牙模块将数据无线传输至自研Android客户端进行图表化展示与历史记录管理。压缩包含535个文件总计84.39MB涵盖83个.h头文件与75个.c源码核心驱动与算法逻辑、66个.o与.d编译中间文件、63个.crf调试符号文件以及15份PDF设计文档、12个XML布局文件和3个可直接安装的APK应用包结构完整、模块清晰便于从硬件驱动、协议解析到APP交互全流程学习与二次开发。目前已有319人下载学习适合需要软硬协同实战经验、毕业设计参考或嵌入式Android跨平台项目复现的学习者。1. 项目缘起从毕业设计到个人健康守护者的思考又到了一年一度的毕业季相信不少电子、自动化、物联网专业的同学正在为毕业设计选题发愁。是做一个炫酷但华而不实的“玩具”还是做一个扎实、有深度、能真正体现四年所学甚至对未来求职有帮助的项目如果你正在这个十字路口徘徊那么今天我想和你分享的这个项目——“基于STM32单片机的心率脉搏监测健康运动计步系统”或许能给你带来一些启发。这个项目听起来很“经典”甚至有些“老套”但它恰恰是经典中的经典。它融合了传感器技术、信号处理、嵌入式系统设计和数据可视化等多个核心知识点是检验一个电子工程师基本功的绝佳试金石。更重要的是它并非一个停留在实验室的“花瓶”其核心功能——心率、脉搏监测与计步正是当前智能穿戴设备如智能手环、手表的基石。通过亲手实现它你不仅能完成一份高质量的毕业设计更能深入理解消费级健康监测设备背后的技术逻辑为将来进入物联网、可穿戴设备领域打下坚实的基础。我当年毕业设计做的就是类似的方向后来在工作中也接触过不少相关的产品研发。回过头看这个项目锻炼的能力非常全面从最底层的单片机选型、外设驱动编写到模拟信号采集与数字滤波算法再到上层的数据融合与简单的人机交互。整个过程就像搭积木但每一块积木都需要你精心打磨。接下来我将结合最新的技术选型和实践中的坑点为你拆解这个系统的完整设计与实现思路希望能帮你少走弯路做出一个既漂亮又扎实的作品。2. 核心架构设计为什么是STM32与这些传感器在动手写代码之前我们必须先想清楚整个系统的骨架。一个好的架构设计能让后续的开发事半功倍也能让你的设计报告逻辑清晰、层次分明。2.1 主控芯片选型STM32F103C8T6的“性价比之选”对于毕业设计而言成本、资源、开发难度是需要平衡的关键。市面上单片机种类繁多从经典的51到高端的ESP32、树莓派Pico。我强烈推荐使用STM32F103C8T6也就是常说的“蓝色药丸”或“最小系统板”。理由如下资源完全够用它基于ARM Cortex-M3内核主频72MHz拥有64KB Flash和20KB RAM。对于处理心率传感器数据、运行计步算法和驱动显示屏来说性能绰绰有余。其丰富的外设多个定时器、ADC、USART、I2C、SPI为连接各类传感器提供了极大便利。生态与社区支持极好STM32拥有最庞大的开发者社区无论是标准外设库SPL还是硬件抽象层库HAL资料和例程都汗牛充栋。你遇到的几乎任何问题都能在论坛或开源平台找到答案。这对于时间紧张的毕业设计至关重要。成本低廉且易获取一块核心板价格仅在十元左右各种外围模块如OLED、传感器也都有成熟的配套能极大降低硬件调试风险。学习价值高STM32是工业界嵌入式开发的事实标准之一掌握它对你求职有直接的加分作用。当然如果你想让项目更“潮”一点也可以考虑使用STM32F4系列性能更强或集成蓝牙的STM32WB系列为无线传输预留空间但这可能会增加一些学习和调试成本。对于首次深入STM32开发的同学F103系列是最稳妥的起点。2.2 传感器选型与原理捕捉生命的“信号”系统的“感官”由三类传感器构成它们分别负责采集心率、脉搏和运动信息。心率/脉搏传感器MAX30102这是当前心率监测方案的主流选择一个模块集成了光电式心率测量的所有关键部件。工作原理它内置两颗LED红光和红外光和一个高灵敏度光电探测器。当LED光照射到皮肤通常是指尖或手腕时血液对光的吸收会随着心脏泵血引起的血容量变化而周期性波动。探测器接收反射光并将其转换为电信号。这个微弱的信号包含了心率HR和血氧饱和度SpO2信息。为什么选它相比上一代分离式的传感器如红外对管运放电路MAX30102集成度高自带环境光抑制、LED驱动和ADC通过I2C接口直接输出数字化的光电容积脉搏波PPG数据极大简化了前端模拟电路设计稳定性也更好。对于毕业设计能让你更专注于算法和逻辑而不是纠结于模拟信号的稳定性。运动传感器MPU6050计步和运动状态识别离不开惯性测量单元IMU。MPU6050是一个6轴传感器集成了3轴加速度计和3轴陀螺仪。工作原理加速度计测量物体在三个方向上的线性加速度可以用来检测步伐走路或跑步时产生的周期性震动和静态角度如设备佩戴姿态。陀螺仪测量角速度可用于识别更复杂的运动模式但基础计步可以不用。为什么选它MPU6050同样是经久不衰的明星型号性价比极高通过I2C接口通信有大量成熟的计步算法如峰值检测、阈值判断开源代码可供参考和学习。环境温湿度传感器DHT11可选但推荐这是一个可选项但我强烈建议加上。健康监测不仅关注身体内部信号环境因素也很重要。DHT11能提供温湿度数据成本仅几元钱通过单总线通信易于集成。在你的系统显示界面上增加一行环境信息会让项目显得更完整、更“物联网”。2.3 系统整体架构框图基于以上选型我们可以勾勒出系统的硬件架构[电源模块] -- [STM32F103C8T6 主控] | |--- I2C --- [MAX30102 心率血氧传感器] |--- I2C --- [MPU6050 运动传感器] |--- GPIO --- [DHT11 温湿度传感器] |--- SPI/I2C --- [OLED显示屏] |--- GPIO --- [按键模块]软件上程序将围绕以下几个核心任务展开传感器数据采集任务定时通过I2C读取MAX30102和MPU6050的原始数据。信号处理与算法任务对PPG信号进行滤波、计算心率对加速度数据进行处理实现计步。人机交互任务在OLED上刷新显示心率、步数、温湿度等信息并响应按键切换显示页面。数据管理任务进阶可以将历史数据如每日步数存储到STM32自带的Flash中实现简单统计。3. 硬件电路设计与连接避开那些“看似简单”的坑有了架构下一步就是动手搭建电路。很多同学觉得按照原理图连上线就行但实际调试中大部分问题都出在硬件连接和电源上。3.1 核心电路连接详解这里给出一个最精简可靠的连接方案以STM32F103C8T6核心板为例MAX30102VIN- 3.3V 注意务必接3.3V接5V可能烧毁GND- GNDSCL- PB6 (I2C1_SCL)SDA- PB7 (I2C1_SDA)INT- 可选连接到一个外部中断引脚如PA0用于在数据就绪时触发读取提高效率。MPU6050VCC- 3.3VGND- GNDSCL- PB6 (与MAX30102共用I2C1总线)SDA- PB7 (与MAX30102共用I2C1总线)AD0- GND (设置I2C地址为0x68如果接3.3V则地址为0x69)OLED (I2C接口SSD1306)VCC- 3.3VGND- GNDSCL- PB10 (可使用I2C2_SCL避免与传感器总线冲突)SDA- PB11 (可使用I2C2_SDA)DHT11VCC- 3.3VGND- GNDDATA- PA1 (配置为开漏输出模式并启用上拉电阻)按键连接至PA2、PA3等GPIO配置为上拉输入模式。3.2 必须警惕的硬件坑点电源问题——噪声的根源所有数字传感器对电源噪声都非常敏感。务必确保3.3V电源干净、稳定。建议在每块传感器的VCC和GND之间就近焊接一个0.1uF104的瓷片电容进行退耦这是消除高频噪声成本最低、效果最显著的方法。如果使用USB供电电脑USB口的噪声可能较大可以尝试用手机充电宝供电对比测试。I2C总线冲突与上拉电阻当多个设备MAX30102、MPU6050共用一条I2C总线时必须确保每条总线上有合适的上拉电阻。STM32的I2C引脚内部弱上拉可能不足以驱动长导线或多设备最好在SCL和SDA线上各外接一个4.7kΩ的上拉电阻到3.3V。很多模块本身已集成但若通信不稳定这是首要排查点。传感器放置与接触MAX30102测量时需要稳定的光学接触。手指不能按压太轻接触不良或太重压迫血管导致信号失真。对于毕业设计演示可以制作一个简单的指套或利用橡皮筋固定这比用手一直捏着可靠得多。MPU6050应牢固地固定在电路板或佩戴模型上避免松动产生额外振动噪声。杜邦线的噩梦面包板杜邦线是快速原型的好工具但也是不稳定的万恶之源。在最终焊接或录制演示视频前尽量将核心电路主控、传感器焊接在万用板或洞洞板上或者使用排针排母紧密连接。我曾因为一根松动的杜邦线花了整整两天调试一个“时好时坏”的心率值。4. 软件驱动与数据采集从寄存器操作到稳定读数硬件搭建完毕我们进入软件部分。首先是为各个传感器编写可靠的驱动确保能读到正确的原始数据。4.1 使用HAL库快速搭建工程我推荐使用STM32CubeMX初始化工具配合HAL库进行开发。对于初学者这能避免繁琐的寄存器配置快速生成工程骨架。时钟配置在CubeMX中将系统时钟SYSCLK设置为72MHz外部晶振HSE。I2C配置启用I2C1模式为I2C速度模式选择标准模式100kHz或快速模式400kHz。注意将PB6、PB7引脚模式自动设置为复用开漏输出Alternate Function Open Drain。GPIO配置配置OLED使用的I2C2引脚PB10 PB11以及DHT11数据线PA1为输出开漏模式、按键引脚PA2 PA3为上拉输入模式。生成代码生成基于MDK-ARM或STM32CubeIDE的工程。4.2 MAX30102驱动开发不仅仅是读数据MAX30102的驱动相对复杂因为它有很多可配置的寄存器。核心步骤包括初始化序列上电后必须按照特定顺序配置寄存器。// 伪代码示例 MAX30102_WriteReg(REG_MODE_CONFIG, 0x40); // 复位 HAL_Delay(100); MAX30102_WriteReg(REG_MODE_CONFIG, 0x03); // 心率血氧模式 MAX30102_WriteReg(REG_SPO2_CONFIG, 0x27); // LED脉冲宽度411us采样率100Hz MAX30102_WriteReg(REG_LED_CONFIG, 0x24); // 红光电流24mA可根据需要调整 MAX30102_WriteReg(REG_FIFO_CONFIG, 0x4F); // 平均采样数滚动覆盖注意LED电流大小直接影响信号强度和功耗。电流太小信号弱易受干扰电流太大发热且耗电。24mA是一个常用起始值需要根据实际佩戴情况皮肤颜色、厚度微调。数据读取MAX30102的数据存储在FIFO中。我们需要周期性地例如每10ms检查FIFO读写指针或利用中断引脚然后通过I2C连续读取6个字节红光ADC值高8位、低8位红外光ADC值高8位、低8位。uint8_t raw_data[6]; MAX30102_ReadFIFO(raw_data); // 自定义函数实现I2C连续读 int32_t red_value (raw_data[0]16) | (raw_data[1]8) | raw_data[2]; int32_t ir_value (raw_data[3]16) | (raw_data[4]8) | raw_data[5]; // 注意数据是18位有符号整数需要根据数据手册进行符号位扩展读到的red_value和ir_value就是原始的PPG波形数据。你会发现它噪声很大夹杂着工频干扰、运动伪影和呼吸波下一步就是滤波。4.3 MPU6050驱动与数据校准MPU6050的驱动重点是初始化和数据读取校准。初始化配置电源管理、陀螺仪和加速度计量程、数字低通滤波器等。MPU6050_WriteReg(MPU6050_RA_PWR_MGMT_1, 0x80); // 复位 HAL_Delay(100); MPU6050_WriteReg(MPU6050_RA_PWR_MGMT_1, 0x00); // 唤醒 MPU6050_WriteReg(MPU6050_RA_CONFIG, 0x03); // 数字低通滤波器带宽 3Hz MPU6050_WriteReg(MPU6050_RA_GYRO_CONFIG, 0x00); // 陀螺仪量程 ±250°/s MPU6050_WriteReg(MPU6050_RA_ACCEL_CONFIG, 0x00); // 加速度计量程 ±2g至关重要的校准MPU6050的原始数据存在零偏Offset即静止时输出不为零。必须进行校准。方法将传感器水平静止放置一段时间如10秒连续读取数百个加速度和陀螺仪样本分别计算三个轴的平均值这些平均值就是零偏。在后续读数中减去这些零偏值。操作可以设计一个校准模式上电后长按某个按键进入OLED提示“正在校准请保持静止”完成后将零偏值保存到Flash中以后每次上电自动加载。// 简易校准示例 for(int i0; i500; i){ MPU6050_ReadAccel(ax, ay, az); offset_ax_sum ax; offset_ay_sum ay; offset_az_sum az; HAL_Delay(10); } accel_offset_x offset_ax_sum / 500; // ... 同理计算y,z轴及陀螺仪零偏未经校准的MPU6050数据几乎无法用于准确的计步。5. 核心算法实现从噪声中提取有效信息这是整个项目的灵魂所在也是最能体现你算法功底和编程能力的地方。5.1 心率计算算法PPG信号的数字滤波与峰值检测直接从MAX30102读到的PPG信号是没法看的。我们需要一套信号处理流程直流分量去除PPG信号包含一个很大的直流分量由组织、骨骼等非搏动部分反射造成和一个较小的交流分量由血液脉动造成。我们需要的是交流分量。最简单的方法是减去一段窗口内的移动平均值。#define WINDOW_SIZE 50 int32_t dc_removed raw_value - moving_average; // 更新移动平均 moving_average moving_average (raw_value - buffer[oldest_index]) / WINDOW_SIZE; buffer[new_index] raw_value;带通滤波心率信号通常在0.5Hz到5Hz之间对应30到300次/分钟。我们需要设计一个数字带通滤波器滤除高频噪声如肌肉抖动和低频漂移如呼吸波。推荐方法使用二阶IIR带通滤波器。虽然设计起来需要一些数字信号处理知识但网上有大量现成的系数计算工具和代码。你可以设定通带为0.7Hz-4Hz用Matlab或在线工具生成滤波器系数然后在C语言中实现差分方程。简化方法先进行低通滤波截止频率5Hz再进行高通滤波截止频率0.5Hz。可以使用一阶IIR滤波器实现计算量小在STM32上跑起来毫无压力。// 一阶IIR低通滤波器示例 float alpha 0.1; // 平滑系数越小越平滑滞后越大 filtered_value alpha * new_sample (1 - alpha) * last_filtered_value;峰值检测滤波后的信号呈现清晰的脉搏波波形。我们需要检测波峰的间隔来计算瞬时心率。动态阈值法这是最常用的方法。维护一个动态的阈值当信号值超过该阈值并且是一个局部最大值比前后几个点都大时判定为一个峰值。实现要点阈值 信号平均值 系数 * 信号标准差。系数需要根据信号质量调整如0.5-1.5。检测到峰值后需要设置一个“不应期”例如对应心率200bpm的间隔在此期间不进行峰值检测避免一个波峰被多次计数。记录相邻峰值的时间间隔T单位秒。瞬时心率HR 60 / T单位次/分钟bpm。心率值平滑输出瞬时心率可能因单次误检而跳动剧烈。通常采用滑动平均或中值滤波来输出一个稳定的心率值。#define HR_BUFFER_SIZE 5 hr_buffer[hr_index] current_hr; if(hr_index HR_BUFFER_SIZE) hr_index 0; // 对hr_buffer排序取中值作为最终输出 output_hr median_filter(hr_buffer, HR_BUFFER_SIZE);5.2 计步算法基于三轴加速度的步数识别计步的本质是检测行走或跑步时产生的周期性加速度冲击。我们主要利用MPU6050的加速度计数据。数据预处理合成向量幅值将三轴加速度数据合成为一个标量消除设备方向的影响。magnitude sqrt(ax*ax ay*ay az*az);去除重力分量在静止状态下magnitude约等于1g9.8m/s²。为了突出运动冲击可以减去这个静态值但更常用的方法是使用高通滤波器直接滤除低频的重力分量。步态检测算法峰值检测法与心率检测类似对预处理后的加速度幅值信号进行峰值检测。行走时脚着地会产生一个明显的加速度峰值。通过设置合适的幅度阈值和时间窗口可以识别出有效步伐。波形分析法分析加速度信号的波形特征如波峰波谷的规律性、周期等可以提高在复杂运动如上下楼梯下的识别准确率。开源算法参考可以借鉴如StepDetector等轻量级开源算法它们通常已经考虑了去噪、阈值自适应等逻辑。实现细节采样率计步不需要太高采样率25-50Hz足够。可以在一个定时器中断里读取MPU6050。防误判连续的步伐之间有时间间隔限制如成人步行频率一般不会超过3Hz。可以加入时间窗约束避免因抖动造成的连续误计数。计步清零通常需要设计一个长按按键清零当日步数的功能。5.3 数据融合与显示逻辑当心率和计步算法都稳定运行后我们需要将它们组织起来通过OLED进行友好地显示。显示界面设计一个128x64的OLED屏可以设计2-3个页面通过按键切换。页面1主页面大字体显示实时心率如“❤ 78”、当前步数如“ 1256”、以及环境温湿度。页面2历史/统计显示今日总步数、估算距离步数*步幅、估算卡路里根据步数和心率粗略估算。页面3波形/调试可以绘制PPG信号或加速度信号的实时波形用于调试和演示非常直观酷炫。程序设计架构建议采用“前台后台”或基于实时操作系统如FreeRTOS的思想。后台在定时器中断或低优先级任务中稳定地执行数据采集、滤波和算法计算更新心率、步数等全局变量。前台在主循环或高优先级任务中负责按键扫描、界面刷新和逻辑控制。刷新界面时直接从全局变量读取最新结果避免在显示函数中进行复杂计算导致界面卡顿。6. 系统调试与优化让作品从“能用”到“好用”代码写完、功能基本实现只是成功了一半。接下来的调试和优化才是区分普通作品和优秀作品的关键。6.1 心率监测的稳定性调试心率不准、跳动巨大是最常见的问题。可以按以下步骤排查信号质量评估在OLED的调试页面上将滤波前的原始PPG信号红外或红光通道绘制出来。观察波形是否清晰。一个健康的PPG信号应该具有明显的、周期性的主波和重搏波。如果波形杂乱、基线漂移严重首先检查硬件接触和电源。滤波器参数调优调整带通滤波器的截止频率。如果心率跳动快可能是高频噪声没滤干净如果响应迟钝可能是通带太窄或滤波器阶数太高引入了相位延迟。可以尝试不同的滤波算法如移动平均、中值滤波组合。动态阈值自适应不同人、不同佩戴部位的信号幅度差异很大。实现一个自适应的阈值算法至关重要。例如可以实时计算最近一段时间信号的平均值和方差动态调整峰值检测的阈值系数。运动伪影抑制这是穿戴式心率监测的最大挑战。走路时传感器与皮肤的接触压力会变化产生巨大的运动噪声运动伪影。单纯的滤波很难解决。一个有效的毕业设计优化点可以利用MPU6050的加速度数据当检测到剧烈运动时通过加速度幅值判断可以临时降低心率更新的频率或者切换到“运动心率”计算模式可能需要更复杂的算法如基于加速度信号对PPG信号进行补偿的算法。即使你只实现“运动时提示信号不可靠”的功能也能在答辩时体现你的思考深度。6.2 计步算法的准确率提升计步不准主要是误检非步伐被计数和漏检步伐没被识别。阈值自适应和心率一样静态的加速度幅度阈值不适用于所有人。可以根据一段时间内加速度数据的统计特征如均值、方差动态调整步数检测的幅度阈值和时间窗口。多特征判断不仅仅看幅度峰值还可以结合峰值之间的时间间隔是否在合理步行/跑步频率范围内以及峰值波形的形状上升沿陡峭程度进行综合判断。姿态识别利用MPU6050的陀螺仪和加速度计可以简单判断设备是放在口袋、拿在手里还是戴在手腕上。不同姿态下的加速度模式不同可以对应采用不同的检测参数提升鲁棒性。这是一个很好的加分项。6.3 功耗优化考虑进阶如果你的设计包含电池供电功耗就是一个必须考虑的问题。传感器休眠MAX30102和MPU6050都支持低功耗模式。当不需要连续监测时比如只显示时间可以将它们设置为休眠状态需要时再唤醒。MCU低功耗模式STM32支持多种低功耗模式Sleep Stop Standby。在系统空闲时如等待按键可以让主控进入Stop模式由外部中断按键或传感器中断唤醒。这需要精心设计你的程序流程。降低采样率与计算量在满足性能要求的前提下尽可能降低传感器数据采样率和算法运行频率。例如静坐时心率采样率可以从100Hz降至25Hz。7. 功能扩展与项目包装让你的设计脱颖而出完成基本功能后如何让你的毕业设计在答辩时更出彩这里有一些锦上添花的扩展思路。7.1 数据存储与简单分析利用STM32内部Flash或外接一个便宜的EEPROM芯片如AT24C02存储每日的步数总和。上电时读取步数更新时写入。这样可以实现“历史步数”查看功能哪怕断电也不会丢失。你甚至可以设计一个简单的7天步数趋势图在OLED上显示虽然像素不高但足以展示你的软件架构能力。7.2 无线数据传输与可视化蓝牙/WIFI这是将项目提升到“物联网”层次的关键一步。蓝牙方案增加一个HC-05或HC-08蓝牙模块通过串口与STM32连接。编写一个简单的手机APP可以用MIT App Inventor、Android Studio或微信小程序接收蓝牙数据实时显示心率和步数曲线。这能极大提升项目的演示效果和实用性。WIFI方案使用ESP8266模块通过AT指令或SDK开发将数据上传到免费的物联网平台如OneNET、阿里云物联网平台然后在平台网页或手机APP上查看数据。这体现了完整的“端-云-端”思路。7.3 设计报告与演示准备一个优秀的毕业设计文档和演示与实物同等重要。设计报告不要只堆砌代码和电路图。重点阐述你的设计思路、方案选型依据、算法原理、调试过程中遇到的问题及解决方案。将前面章节中关于“为什么选这个芯片”、“那个坑是怎么踩的又是怎么填的”等内容系统地写进报告里。图表清晰排版美观。实物包装不要用裸露的杜邦线和面包板去答辩。花几十元定制一个亚克力外壳或者用3D打印一个外壳将电路板、电池、屏幕整合进去做一个腕带或胸扣让它看起来像一个真正的“产品原型”。这体现了你的工程化和产品化思维。演示脚本提前准备好演示流程。比如“大家好这是我的健康监测设备。现在我将它戴在手上大家可以看到OLED屏幕开始显示我的心率当前是XX次/分。我原地踏步几下可以看到步数在增加……我按下这个按键可以切换页面查看历史数据……”。流畅的演示能给答辩老师留下极好的印象。这个项目就像一座宝藏基础部分能确保你顺利毕业而深入的探索和优化则能让你挖掘出更多的价值。从读懂一个传感器数据手册到实现一个稳定的滤波算法再到解决一个棘手的干扰问题每一步都是实实在在的成长。希望这份超详细的拆解能成为你毕业设计路上的得力助手祝你做出一个让自己骄傲的作品如果在实现过程中遇到具体问题不妨回到对应的章节看看或许答案就在其中。本文还有配套的精品资源点击获取