news 2026/9/6 15:45:20

基于单片机的脉搏测量仪设计与实现:从PPG信号调理到心率算法全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于单片机的脉搏测量仪设计与实现:从PPG信号调理到心率算法全解析

简介:这是一份题为《基于单片机的脉搏测量仪》的毕业设计文档,内容完整,共1个doc文件,压缩包大小2.12MB,适合电子、通信及嵌入式方向的毕业生和初学者作为课程设计或毕业设计参考。设计以AT89C51单片机为核心,结合红外发光二极管与光敏三极管构成光电传感器,通过定时器计算时间和脉冲累加得到脉搏次数,并在显示模块上实时输出。文档从选题背景、系统硬件组成、工作原理、软硬件设计,到系统测试与性能分析均有阐述,目录结构清晰,并给出了完整的摘要、关键词和论文框架。已有82人学习下载,对于希望了解51单片机应用、光电检测及脉搏测量实现流程的读者,是一份可用于快速搭建方案、梳理设计思路和撰写论文的有价值参考资料。 又是单片机课设季,后台收到好几个同学在问“基于单片机的脉搏测量仪”这类题目怎么做。这题目在毕业设计和课程设计里确实算常青树了,既能覆盖模拟电路前端处理,又能把ADC采集、数字滤波、算法统计、外设驱动这些单片机核心技能串起来,工作量可观但难度可控,老师也爱看这种“软硬结合”的完整项目。

那这篇就把我当时做这个题目的完整思路、硬件选型、代码框架和踩坑记录整理出来,从原理到实现一次讲透,照着做基本都能跑通。

1. 整体方案设计与核心思路拆解

1.1 脉搏测量的两种主流技术路线

做脉搏测量仪,第一步不是选单片机,而是先定“怎么测脉搏”。目前常见的方案有两种,区别很大。

一种是压电式方案,用的是压电薄膜传感器,贴在手腕桡动脉处,靠脉搏搏动的机械压力产生电荷信号。这种方案的优点是抗环境光干扰强,戴在手腕上更像“手表”,体验好,但缺点也很明显:信号幅度极小(毫伏甚至微伏级),对运放和前级电路要求非常高,而且对传感器贴放位置极其敏感,稍微挪一下位置波形就没了。学生做课设用这个方案,很容易在“信号调理”这个环节耗掉大量时间。

另一种是光电式容积脉搏波方案(PPG),利用的是血液对光的吸收特性。发光管发出特定波长的光照射皮肤,光敏管接收透射或反射后的光。心脏收缩时血管血量增加、吸光量增大,光敏管接收到的光强就变弱;心脏舒张时反之,所以光敏管输出的电信号就呈现与心跳同步的周期性波动。

我做这个题目选的是光电式PPG方案,具体用的是透射式红外对管。原因很直接:电路相对简单、信号幅度大(几十到几百毫伏)、传感器固定方便(夹耳垂或手指),非常适合课程设计和毕业设计的时间节奏。如果非要做腕表式体验,那再考虑压电方案,但那基本是另一个量级的项目了。

1.2 系统整体架构与工作流程

整个系统的工作流程可以从信号流的角度来理解:传感器采集微弱生理信号,经模拟电路放大滤波后,送入单片机进行A/D转换和数字处理,最后计算心率并显示,超限时报警。

整套系统拆成四个功能单元来看:

功能单元核心器件作用
信号采集红外发射管+光敏接收管将脉搏搏动转换为电信号
信号调理前置放大电路+滤波电路+主放大电路将微弱信号放大到ADC可采集范围并滤除噪声
数据处理单片机(STC89C52)内部ADC+算法数字滤波、峰值检测、心率计算
人机交互LCD1602显示+按键+蜂鸣器显示心率数值与报警提示

这里有个关键设计决策需要说明:为什么前级不直接用运放做很高的放大倍数?因为脉搏信号的噪声主要来自50Hz工频干扰、日光灯等环境光干扰以及手指抖动产生的低频干扰。如果前级放大倍数直接拉到1000倍,这些噪声也会被同比例放大,信号直接饱和削顶,什么都测不到。

正确的做法是多级放大加上中间滤波:小倍数前置放大,带通滤波滤除干扰,再二级放大到合适幅度。这个顺序很重要,先滤波再放大,比先放大再滤波的效果好得多。

2. 硬件电路细节与元器件选型要点

2.1 传感器选型与前端电路设计

传感器我选用的是红外对管ST188,这是一颗反射式红外传感器,发射管和接收管封装在一起,靠近手指时红外光经皮肤组织反射后被接收管采集。选它的主要原因是模块化程度高、资料多、价格便宜(两三块钱),而且发射波长在900nm左右,受可见光影响小。

也有同学用透射式的方案,让手指夹在发射管和接收管之间,好处是信号更强,但需要一个固定的手指夹结构,做起来麻烦一些。反射式最大的坑是安装距离:传感器表面到皮肤的距离要控制在5mm以内,太远了反射信号急剧衰减,太近了容易压死血管造成局部缺血,反而没信号。

前端电路的核心是一个跨阻放大或简单的电阻分压加射极跟随结构。我用的方案是:接收管集电极接上拉电阻到VCC,发射极接地,脉搏引起的光变化导致光敏管等效电阻变化,从而在集电极产生变化的电压信号。这个信号只有几十毫伏级别,需要进入调理电路处理。

2.2 信号调理电路的核心参数计算

信号调理部分是整个硬件电路中技术含量最高、也是很多同学最容易做砸的地方。原理上就三件事:放大有用信号、滤掉噪声、把信号幅度调到ADC合适范围。

运放选型上,课程设计用LM358就足够,虽然它带宽窄、噪声偏大,但脉搏信号本身就是低频信号,LM358完全够用且不容易自激振荡。想做得更好可以用NE5532或OP07,但要注意供电电压和单电源工作的共模输入范围。

具体电路采用两级结构:

第一级是同相比例放大,放大倍数设为10倍左右,把几十毫伏的信号放大到几百毫伏。R1取10k,反馈电阻R2取100k,放大倍数=1+R2/R1≈11倍。这一级输出接入一个有源低通滤波器,截至频率设计在5Hz左右。为什么是5Hz?人的正常心率范围是60~100次/分,剧烈运动时可达180次/分左右,对应频率是1~3Hz。把截至频率放在5Hz可以完整保留脉搏信号,同时把50Hz工频干扰和更高频的噪声一刀切掉。低通滤波的电容电阻取值按照RC截至频率公式计算:f=1/(2πRC),取R=33k、C=1uF,算下来约4.8Hz。

第二级放大倍数设计得更大一些,用可调电位器实现增益调节,范围为20~100倍。这样总放大倍数在200~1000倍之间可调,适应不同人的皮肤厚度、手指粗细差异。这里必须用可调增益,因为不同人的手指透光性差异非常大,固定增益要么信号太弱测不到,要么信号太大削顶失真。

2.3 单片机最小系统与显示模块连接

主控我用的是STC89C52RC,价格便宜、资料多、51基础知识通用,做课设完全够用。要是想上STM32也完全可以,但要注意STM32的ADC是12位,采样的分辨率和精度会更好,对应的代码逻辑也更复杂一些,需要根据自己掌握的程度选择。

最小系统的搭建有几个容易踩的坑:复位电路用10uF电解电容加10k电阻,晶振用11.0592MHz(主要是为了串口波特率准确),电源端一定要加100nF和10uF两个去耦电容。尤其是ADC采集时,电源纹波会直接耦合进采样结果里,在示波器上看波形毛刺很多,排查半天发现是电源没处理好,非常常见。

显示模块我用LCD1602,因为它显示字符方便、代码库多、接线简单,8个数据引脚加3个控制引脚,标准接法连到P0和P2口。要注意P0口内部没有上拉电阻,接LCD时必须在外部加上拉电阻,否则显示乱码。用4位模式接法可以省4个IO口,但代码上要稍微处理一下字节拆分。

3. 软件核心算法与代码实现

3.1 ADC采样与数字滤波处理

STC89C52内部集成8路10位ADC,对我们来说够用了。配置ADC寄存器开启P1.0通道采样,采样率设为100Hz(每秒100个点),这样2Hz的脉搏信号一个周期能采到50个点,波形还原度很好。

采样率也不是越高越好,太高了数据量大,MCU处理不过来;太低了波形细节丢失,峰值检测不准。100Hz是我测试下来比较合适的折中值。

采到的原始数据直接算心率是不行的,因为信号里还有高频毛刺和基线漂移。我在软件里做了两级处理:

第一级是滑动平均滤波,每采5个点取一次平均值。这个滤波会带来一定的波形延迟,但100Hz采样率下5个点才延迟50ms,对心率计算来说可以忽略。

第二级是去基线漂移。手指按压力度变化、呼吸等都会造成信号整体上下漂移,表现为波形在零点附近缓慢游走。处理方法是计算最近100个采样点的平均值,然后让当前值减去这个平均值,相当于一个数字高通滤波器,能把低频漂移去掉,让波形稳定在零轴附近。

3.2 心率计算逻辑:从波形到数字

这是整个软件的核心,我的方法分三步:

第一步是峰值检测。对滤波后的数据做一阶差分,即计算当前点与前一个点的差值。当差分值从正变负,且当前值大于设定阈值时,判定为一次脉搏峰值。阈值不能设成固定值,因为不同人的信号强度可能差一倍以上。我采用自适应阈值:阈值为当前时间段内信号最大值的60%。这样手指放上去信号强就自动适应高阈值,信号弱就自动降低标准,实测下来适应不同人很稳定。

第二步是不应期锁定。人的心率最快也就240次/分左右,对应峰间隔至少250ms。如果检测到两次峰值间隔小于250ms,后一个峰值直接判定为干扰,不计数。这能有效防止波形抖动造成的误触发。

第三步是心率计算。记录最近4次脉搏峰值的间隔时间,取平均值后换算成每分钟心跳次数。之所以用4次间隔的平均值而不是单次间隔,是为了平滑心率显示,让数字跳动不至于太突兀,更接近医用脉搏血氧仪的效果。

核心代码框架如下:

// 峰值检测与心率计算 #define PEAK_THRESHOLD_RATIO 0.6f // 自适应阈值比例 #define REFRACTORY_PERIOD_MS 250 // 不应期,毫秒 uint16_t peak_value = 0; // 当前周期内的峰值 uint16_t peak_count = 0; // 峰值计数 void process_pulse_data(uint16_t adc_value) { // 更新当前周期最大值(用于自适应阈值) if (adc_value > peak_value) { peak_value = adc_value; } // 差分判断:当前点比前一个点小,且前一个点是局部最大值 if (adc_value < previous_value && previous_value > threshold) { uint16_t interval = get_current_interval(); // 与上次峰值的间隔 if (interval > REFRACTORY_PERIOD_MS) { peak_count++; update_heart_rate(interval); // 更新心率 } } previous_value = adc_value; }

3.3 显示驱动与按键交互

LCD1602的驱动代码网上很多,关键在于时序的把握。我建议直接使用4位数据线模式,初始化时序严格按照手册要求来,不然容易出现“刚开始显示正常、过一会儿乱码”的情况——这多半是初始化时序不够规范。

显示内容分两行:第一行显示“Heart Rate:”,第二行显示数值和单位“XX BPM”。每次心率更新后,只在原来的位置重写数字部分,不要整屏刷新,否则LCD会有闪烁感。

按键功能我做了两个:一个切换工作模式(实时显示模式/历史记录模式),一个设置报警阈值。报警逻辑很简单,心率高于设定值或低于设定值时,蜂鸣器以不同频率鸣叫,高报警用高频,低报警用低频,方便区分。

4. 常见问题与排查技巧实录

4.1 示波器看得到波形,心率却显示乱跳

这个问题十有八九出在阈值设置不合理滤波强度不够上。

我调试时遇到过一种典型情况:手指放上去,LCD上的心率显示在120到220之间剧烈跳动,但示波器上明明看到规律波形。排查后发现是波形上有一些小毛刺,幅度虽然不大,但经过差分检测后也会被误判为峰值。解决方法是提高阈值比例(从60%提到75%),以及引入“连续两个点满足条件才算峰值”的确认机制。这种方法本质上是增加了检测的“去抖动”逻辑,比单纯调阈值更有效。

另外要检查手指位置是否稳定。PPG信号的波形形态与传感器和血管的相对位置有很大关系,手指微动一下,波形幅度和形状都会变化,心率自然就不稳定。让被测者手放平稳、不要用力握紧,是最简单但最有效的改善手段。

4.2 有信号但幅度太小,调大增益后波形反而消失

这个现象比较反直觉,原因在于电路饱和。信号在前级就被放大到接近电源电压,后级再放大时波形已经削顶变形,表现出来的就是“波形消失”。

判断方法是逐级测量:用示波器分别量第一级输出和第二级输出,看哪一级开始饱和。比如第一级输出已经到4V了,那问题就出在第一级,而不是盲目调第二级电位器。

实际中还有个容易被忽视的点:LM358运放在单电源供电下,输出不能真正到0V,最低只能到几十毫伏。如果信号接近地电位,就会被“卡”住,表现为波形底部被削平。解决方法是把前级偏置到VCC/2(比如2.5V)作为虚地,让信号在2.5V上下摆动,这样正负半周都有充足的空间。

4.3 程序烧录后简单上电无反应

烧录不进去或者上电没反应,不要先怀疑程序,按顺序排查以下环节的效率最高:

第一看电源。用万用表量单片机VCC和GND之间是否有5V电压,注意部分USB转串口模块输出的电压可能不稳,最好用万用表实际测量确认。

第二看晶振。示波器探针放在晶振引脚上,看是否有振荡波形。没有波形的话,检查两个22pF负载电容是否漏焊,或者晶振本身焊接时受热过高坏了。

第三看复位电路。STC单片机在冷启动时要求RST引脚经历一个由高到低的变化过程,如果复位电路不对或者一直处于复位状态,程序永远不会执行。测一下RST引脚电压,正常工作时应该是低电平。

第四看下载电路。STC单片机下载时需要先断电再上电触发下载动作,很多新手卡在这一步。正确顺序是:点下载按钮 -> 给板子上电(如果有独立电源开关) -> 等待提示下载成功。

4.4 常见问题速查表

现象可能原因排查顺序
LCD无显示/乱码P0口未加上拉电阻、初始化时序不对、对比度电位器没调好先测VL引脚电压,再查上拉,最后核对初始化时序
波形毛刺多电源纹波、手抖动、环境光干扰电源端增大电容、手放稳、给传感器做遮光处理
心率值翻倍阈值太低导致误检测、不应期太短提高阈值比例、增加不应期时间
心率值减半阈值太高漏检、波形峰值不明显降低阈值、重新调节传感器位置
蜂鸣器误报警干扰引起心率突变在心率更新时增加平滑处理,突变超过20%不更新

5. 实测效果与优化扩展

整套系统搭完后实际测试,在安静环境下,手指放入传感器夹子的透射式结构(如果你选用),或者在传感器上轻按手指(反射式),LCD显示的心率数值与手机上的PPG测心率软件对比,误差基本能控制在±3次/分以内,完全满足课程设计或毕业设计的指标要求。

从功耗角度看,STC89C52全速运行加LCD背光大概在50mA左右,如果用USB供电完全没问题,想做成便携设备的话换用电池供电就需要考虑休眠模式了。STC89C52有掉电模式,可以在两次采样间隔进入休眠,但考虑到课设场景通常是USB供电,这个优化做不做看个人精力。

想做得更深入的话,有几个扩展方向:一是换成OLED显示屏,UI界面能做得更漂亮;二是加入蓝牙模块HC-05,心率数据实时传到手机App,这个在答辩时特别加分;三是从51平台升级到STM32,用内部定时器做更精确的峰值间隔计时,同时可以加FFT算法做频域分析。如果追求更低功耗,可以考虑GD32等国产ARM芯片,在低功耗模式下整个系统可以做到5mA以内。

我对这个项目的一个核心体会是:**脉搏测量仪在硬件原理上没有太深奥的东西,真正的技术难点全在信号质量的处理上。**模拟前端滤波调好了,数字算法写起来就事半功倍;前级电路毛刺一堆,后面软件再怎么处理都像“烂地基上盖楼”。所以如果你正在做这个题目,多花点时间在示波器上观察各个节点的波形变化,把每级电路的输出都量一遍,这套基本功练下来,收获远不止一个课设高分。

本文还有配套的精品资源,点击获取

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

基于SpringBoot+Vue喀纳斯旅游网站的设计与实现

1. 项目背景与意义喀纳斯景区位于新疆阿勒泰地区&#xff0c;以其壮丽的自然风光和独特的图瓦人文化闻名于世。然而&#xff0c;传统旅游信息获取渠道分散&#xff0c;游客往往需要辗转多个平台才能完成景点查询、路线规划、住宿预订等操作&#xff0c;体验割裂且效率低下。与此…

作者头像 李华
网站建设 2026/9/6 15:40:37

STM32+EC200S+MQTT:4G Cat 1物联网终端开发实战

简介&#xff1a;面向具备嵌入式C开发基础、熟悉STM32与UART通信的物联网开发者&#xff0c;该资源围绕移远EC200S 4G Cat.1模块直连MQTT服务器&#xff0c;提供一套完整的物联网终端解决方案。内容涵盖系统架构设计、硬件引脚连接、AT指令驱动开发、MQTT协议封装、主程序集成、…

作者头像 李华
网站建设 2026/9/6 15:39:18

程序员简历模板.docx:从模块设计到Word实操避坑全指南

简介&#xff1a;面向程序员求职者的岗位简历模板&#xff0c;覆盖Java、C、PHP、SQL与Web开发等常见技术方向&#xff0c;适合正准备技术岗位面试、希望系统梳理项目与技能亮点的候选人参考。整包为1份Word文档&#xff08;.docx&#xff09;&#xff0c;大小约79KB&#xff0…

作者头像 李华
网站建设 2026/9/6 15:35:23

Novu 邮件捕获最佳实践:邮箱校验、双重确认与表单合规设计

Novu 邮件捕获最佳实践&#xff1a;邮箱校验、双重确认与表单合规设计 【免费下载链接】novu The open-source communication infrastructure for agents and products 项目地址: https://gitcode.com/GitHub_Trending/no/novu 本文围绕 Novu 仓库中 邮件捕获最佳实践指…

作者头像 李华