资讯详情

基于STM32的电子血压计设计:示波法脉搏波提取与系统实现

📅 2026/10/27 7:46:51 | 华诺云谱 👁 阅读
基于STM32的电子血压计设计:示波法脉搏波提取与系统实现
简介基于STM32的电子血压计设计是一份完整的嵌入式项目资料包面向电子、自动化、嵌入式专业学生及开发者适合毕业设计、课程设计、实训竞赛和项目开发内含可直接运行的源码工程与说明涵盖压力传感器数据采集、信号调理、LCD显示和报警模块等核心环节。包内共195个文件以C源文件35个c和头文件34个h为主同时含Keil工程文件uvproj、编译输出hex、axf及备份配置压缩包仅3.39MB便于下载和离线使用。目前已有38人学习下载适合有一定STM32基础、想动手完成完整外设应用的读者通过本项目可综合掌握ADC采样、定时器、串口通信等常用模块的协作并借鉴设计思路扩展蓝牙上报、云端存储或更精准的血压算法。1. 基于STM32的电子血压计设计难点不在读压力而在读准脉搏波“基于STM32的电子血压计设计”这类项目在毕业设计和物联网产品开发里一直很常见。第一眼看上去它就是一个STM32加压力传感器加气泵的采集系统实际上真正决定能不能出成果的是放气过程中那几毫米汞柱量级的脉搏波能不能被稳定提取出来。示波法血压计的精髓在于一边按固定速度放气一边从袖带压力里分离出脉动信号再用包络特征反推收缩压和舒张压。只要气路、电源、滤波一个环节做得草率前端的程序写得再花哨最后读数也跟听诊器对不上。这套设计适合两类人一类是要快速完成课设和毕设的学生另一类是做家用健康设备预研的工程师。下面从选型开始把一条能落地的路径拆开来讲。2. 硬件选型与主控资源盘点压力传感器、气泵和电磁阀怎么搭配STM32电子血压计本质上是“气压控制加微弱信号检测”的组合。先把硬件链路想清楚后面调试才不用反复拆板。硬件选型不是越贵越好而是要让传感器量程、执行器驱动能力和主控外设数量互相匹配。2.1 压力传感器的选型量程、输出类型与接口怎么定血压计袖带上的绝对压力范围一般在0到300mmHg之内正常测量时最高也就200mmHg左右。所以传感器的量程选0到40kPa约300mmHg这一档最合适。分辨率方面12位ADC在0到3.3V满量程下即使传感器满量程对应4V折算到压力上也有大约0.1mmHg的量化台阶理论上够用实际上干扰往往比量化误差大得多所以传感器本身的输出幅度反而更重要。市面上的压力传感器按接口形式可分为两类。第一类是集成放大输出的气压传感器典型输出0.5到4.5V或0.5到3.0V可以直接接入STM32的ADC引脚无需额外放大。优点是电路简单适合原理验证缺点是输出静态偏置接近VCC一半后续要判断零点漂移时没有那么直观。第二类是带mV级差分输出的压力传感器还需要接一颗仪表放大器或运放才能被ADC使用。优点是信号带宽内噪声小线性度好产品级血压计更多选这条路缺点是调零电路、共模抑制和布线要求更高。我一般建议第一版样机先用集成输出型跑通气路和算法后再换差分型做信号链打磨。两边都需要注意传感器靠近袖带一端不要再接太长的软管否则管容残气腔会衰减脉搏波这个坑在第五章专门讲。提示无论是哪类传感器量程选择都以200mmHg以上为底线留20%余量避免充气超限时传感器输出饱和造成压力值失真。2.2 气泵与放气阀的驱动用STM32定时器输出PWM控制充放气自动血压计的气动部分一般由两个执行器组成一个是充气气泵一个是放气电磁阀。气泵是微型隔膜泵工作电压常见3.3V或5V启动电流300到500mA电磁阀是常闭型通电才放气工作电流也在100mA以上。STM32的GPIO推挽输出只能提供几毫安到二十毫安能力不能直接驱动因此中间必须加功率开关。常见的驱动电路是三极管或MOSFET加续流二极管。用N沟道MOSFET驱动时PWM信号从定时器输出引脚直连栅极经过一个10kΩ下拉电阻防止上电瞬间误开通漏极接负载线圈线圈两端反向并联续流二极管。连接示意TIM2_CH1接气泵MOSFETTIM2_CH2接放气阀MOSFET。PWM频率方面气泵用10kHz左右电磁阀用1kHz到5kHz频率太低会听到明显的“哒哒”声频率太高阀芯来不及动作反而放气不稳定。实际测量中放气速度是决定波形质量的关键。放气电磁阀的PWM占空比与放气流量不是线性关系要先测占空比曲线固定袖带压力为180mmHg把占空比从10%扫到90%记录每档压力下降速度。这样做的好处是后面写MEASURE状态时能直接查到目标放气速度对应的占空比。选阀时还有一个容易踩的点电磁阀分两位两通常闭型和比例阀。比例阀价格贵但可以精确控制放气量。低成本方案用两位两通常闭阀配合PWM开关也能实现近似线性放气。缺点是同一批次阀的机械一致性不如比例阀标定时要多测几只取中间值。2.3 主控选型与外设资源分配F103为什么够用G0/L0省电做样机和毕业设计STM32F103C8T6是最大众的选择原因很简单网上资料、例程、CubeMX配置教程都最全遇到问题搜到的概率最大。如果目标是量产的低功耗健康设备再往下看STM32G0系列或L0系列它们在睡眠电流上比F103低一个数量级适合电池供电。对电子血压计来说外设需求其实很少一个ADC输入采集压力两个定时器通道输出PWM驱动气泵和放气阀一个按键检测开始测量一个OLED或段码LCD显示结果最多加一个蜂鸣器提示测量完成。F103C8T6的3个ADC、4个通用定时器完全够用。下面这张表是我做样机时常用的管脚分配可以直接套到自己板上功能建议引脚说明压力传感器ADCPA0ADC1_IN0采集袖带压力气泵PWMPA6TIM3_CH110kHz放气阀PWMPA7TIM3_CH21k到5kHz按键开始测量PB1内部上拉OLED I2CPB8/PB9只作显示过压报警或快放阀PB0备用注意PA13和PA14是SWD调试口默认状态下不要配置成普通GPIO否则第一次固件下载后调试器就连不上了只能按复位键擦除。选完引脚后建议在CubeMX里把时钟树配好ADC的采样时钟不要直接用最高频率多数情况14MHz到36MHz之间比较稳噪声更大的时候把ADC采样时间档位调长效果比盲目提采样率更好。2.4 传感器供电与参考电压这块设计不好后面滤波全是白干压力传感器对供电电压的波动很敏感。如果传感器和STM32共用一个3.3V LDO气泵启动瞬间整条3.3V都会跌落几十毫伏ADC测量到的压力值就会跳变。正确做法是把传感器供电与泵电源分开泵直接接电池或5V传感器和ADC参考电压由一颗独立的低噪声LDO供电模拟地采用单点接地汇到总地。ADC参考电压这一条容易被忽略。STM32很多型号的VREF引脚直接接VDDA如果VDDA上有纹波血压值就会跟着漂。规范一点的做法是在VREF引脚接外部基准芯片比如REF3025这类固定2.5V基准没有外部基准时至少要在VREF引脚并联一个100nF加10uF的电容组并把ADC采样通道设置在压力通道之后、电池电压通道之前也就是做“stm32 adc切换通道”时把噪声最大的测量放在最后。3. 示波法测量原理与气压回路参数先从原理上把“测谁”说清楚把硬件确定下来后接下来要在代码里还原示波法算法。想让算法工作第一步不是写公式而是把整个测量过程拆成可观测的物理量。3.1 示波法与柯氏音法的差别为什么自动血压计普遍用示波法手动血压计用的是柯氏音法先把袖带充到高于收缩压再用听诊器听肱动脉的Korotkoff声第一声出现时对应的压力就是收缩压声音消失时对应舒张压。这个方法准确但依赖人听无法自动化。自动血压计普遍改用示波法振荡法原理是袖带压力只要介于收缩压与舒张压之间血管就会周期性搏动这个搏动会叠加到袖带气压上。放气过程中袖带里既有缓慢下降的静态气压P_cuff又有一个几mmHg幅度的脉动信号P_pulse(t)。把脉动信号从总压力信号里分离出来取每个心跳周期的振幅就能得到一条“脉搏波振幅对袖带压”的包络曲线。包络曲线的形态接近钟形袖带压力很高时血管被彻底压瘪脉动幅度很小随压力下降到平均压附近脉动最大再继续下降血流完全恢复脉动又变小。曲线峰顶对应的袖带压就是平均动脉压MAP。收缩压对应的位置在峰顶之前、曲线上升段某个高度比例上舒张压在峰顶之后、下降段某个比例上。比例系数不是理论推导出来的而是厂商在不同人群里做听诊对照标定出来的经验值不同产品可能不一样。3.2 充气与放气的动作参数压力目标、放气速度与测量窗口一次完整的测量过程可以分成三段。第一段是充气阶段充气压力至少要比预测收缩压高30mmHg。如果没有病史信息默认充到170到180mmHg。设定太高手臂被勒得过紧设定太低遇到高血压患者就测不出来。我一般把目标压力做成按键选择常规170高压模式200。第二段是放气测量阶段放气速度控制在3到5mmHg每秒。太快了每个心跳在包络上只有一个点找不到准确的峰值位置太慢了袖带持续压迫动脉被测者手部发麻。以一个每分钟70次心跳的人为例5mmHg每秒放气时每次心跳间压力只下降约4mmHg包络点数量够了。第三段是余压释放阶段测量完成需要把电磁阀全开快速放气。从气路角度看袖带、软管和压力传感器共同构成一个气容系统。软管越细越长内部残气越多脉搏波传到传感器时衰减越厉害所以传感器的气嘴尽量直接接到袖带接头软管长度控制在30cm以内。放气阀的放气流量也会影响测量精度放气量取决于阀口孔径和两侧压差固定占空比下高压段放气比低压段快这是后期判定算法要配合处理的。下面这张参数表是首版样机可以直接用的初始值参数初始值调整方向充气目标压力170mmHg高压模式200放气速度4mmHg每秒左右过快时加放气阀PWM死区修正ADC采样率1kHz不要低于500Hz压力低通截止20到50Hz滤泵振纹脉搏波基线窗口0.4秒滑动平均窗口大于1个心动周期3.3 从压力信号里提脉搏波的信号链模拟滤波与ADC参数设置示波法算法对ADC的要求并不是“刷新率越高越好”而是采样间隔均匀、噪声足够低。均匀采样这一点直接用TIM触发ADC比较可靠在循环里调用HAL_ADC_Start每次都存在微秒级抖动对脉搏波提取时波形会被拉毛。模拟域先做一级RC低通把气泵的机械振纹滤掉。RC时间常数取几十Hz到一两百Hz都可以血压脉搏波的主要能量集中在1到20Hz之间所以把-3dB点设在20到50Hz不会丢失有用成分。ADC每个通道的采样时间建议取较大档位比如STM32F103的ADC采样时间分成1.5到239.5个周期传感器输出阻抗较高时选13.5或更大采样电容才能充到稳定值。注意压力信号从传感器到ADC中间不要串有源滤波器。低压差放大后的信号直接单端到ADC多一级有源滤波就多一个零点漂移源。模拟滤波只做无源RC剩下的交给数字滤波。数字域再对1kHz采样做两件事一是滑动平均得到P_cuff慢变基线二是原始信号减基线得到P_pulse脉动。这一步在第四章的状态机里实现。4. 软件状态机与血压判定算法核心代码和参数怎么落到STM32上血压计软件跟普通传感器程序有个明显差别它不能一直显示瞬时压力而是要按顺序执行“充气、保持、测量、放气”几个阶段中途还可能有按键取消和过压保护。用状态机来组织最清晰。无论用HAL库还是标准库这套状态机的写法都一样不同点只在底层外设接口F103资料里两种写法都能找到对应例程。4.1 状态机设计充气、保持、慢放气、完成的切换我把状态定义为IDLE空闲INFLATE充气HOLD保持MEASURE放气测量COMPLETE完成ERROR错误。IDLE状态下等按键ADC低频采集或干脆不采INFLATE状态下气泵全速输出压力达到目标后切到HOLDHOLD状态关闭气泵等待压力稳定1秒左右MEASURE状态放气阀PWM输出同步采集压力和脉搏波COMPLETE状态全开放气并记录结果ERROR状态用于过压或超时处理。状态切换用switch实现每个状态只干一件事最后用一个全局状态变量驱动整个循环。状态机参数里有一个容易忽略的细节充气压力判断要做迟滞达到目标压力的正负2mmHg内持续10ms再切状态防止单次采样毛刺误触发。放气测量阶段每次采样后判断压力是否低于20mmHg低于则认为袖带已完全松开进入COMPLETE。4.2 ADC多通道采集代码用定时器触发数据进环形缓冲测量阶段要求采样间隔均匀。常见做法是用TIM2更新事件触发ADC转换单通道采样用中断搬运。下面这段代码用HAL库实现ADC定时触发依赖CubeMX生成的hadc1句柄// TIM2自动重载值 系统时钟 / (分频 * 采样率)这里按1kHz采样设置 // 假设APB1时钟72MHzTIM2分频72-1ARR1000-1则触发频率1kHz TIM_HandleTypeDef htim2 {0}; htim2.Instance TIM2; htim2.Init.Prescaler 72 - 1; htim2.Init.Period 1000 - 1; HAL_TIM_Base_Init(htim2); // ADC1_IN0接压力传感器采样时间用较大档位降低源阻抗影响 ADC_ChannelConfTypeDef sConfig {0}; sConfig.Channel ADC_CHANNEL_0; sConfig.SamplingTime ADC_SAMPLETIME_13CYCLES_5; HAL_ADC_ConfigChannel(hadc1, sConfig); // 启动定时器和ADC中断 HAL_TIM_Base_Start(htim2); HAL_ADC_Start_IT(hadc1);这段代码的采样率等于72MHz除以分频再除以ARR得到1kHz。实际做板时不要照抄这个数字先看自己工程里的时钟树是72MHz还是64MHz分频和ARR是两段式先分频到1MHz再用ARR除到目标频率。ADC用中断方式后每次转换完成会进入回调函数把结果放进环形缓冲static volatile uint16_t adc_buf[512]; static volatile uint16_t wr_idx 0; void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) { if (hadc-Instance ADC1) { adc_buf[wr_idx] HAL_ADC_GetValue(hadc); wr_idx (wr_idx 1) % 512; } }环形缓冲大小512对应0.512秒足够后续脉搏波提取时往前回看一个完整的滑动窗口。回调里只做拷贝不要做滤波和判断否则其他中断会一直进不来。需要做多通道扫描时把ADC配置为扫描模式注意做“stm32 adc切换通道”时压力传感器要排在第一个通道电池电压放在最后一个通道因为每切换一次ADC通道采集到的第一个样本可能受前一通道残留电荷影响软件里把首个样本丢弃。4.3 脉搏波提取从压力信号里分出袖带压与脉动压力信号等于慢变的袖带压加上叠加其上的脉搏波。在数字域里我一般用两种办法分离。第一种是滑动平均作为基线原始信号减基线即为脉动。窗口宽度取0.4秒左右对1kHz采样就是400个点。原因是脉搏周期约0.6到1秒窗口小于一个周期才能让基线跟上压力下降的慢趋势又不会把脉动本身吃掉。要注意窗口不能取整好一个心动周期否则脉动会被平均掉包络幅度就小了。第二种是对压力做差分后再低通得到的“脉动”幅度与心跳相关。这个方法做包络更快但容易把压力下降的斜坡也混进来。对首版实现滑动平均减基线最直观、最好调试。脉动信号提取后要对每个脉搏周期找峰谷计算峰谷差值作为该次心搏的振幅。峰谷判断用“斜率变号加幅度阈值”组合先设置一个最小阈值比如10bit防止把噪声当脉动再要求连续上升N个点后转折才认定一个峰值。判断逻辑放在1kHz采集循环里做不要在中断里算。4.4 收缩压与舒张压判定比例系数卡位与标定把所有心搏振幅按“对应时刻的袖带压”组织起来就得到包络曲线。第一步找振幅最大值对应的袖带压就是MAP。第二步在最大值之前从最大值的压力位置往前找到第一个“振幅首次降到最大振幅的50%以下”的采样点该点对应的袖带压记为收缩压再在最大值的压力位置往后找到第一个“振幅首次降到最大振幅的75%以下”的点对应舒张压。中间如果正好落在两个离散点之间用线性插值。为什么不是固定的50%和75%因为不同袖带尺寸、不同人群、不同阀的放气曲线导致包络形状偏移比例只能在听诊法对照标定后确定。一般初始系数可以先按50%和75%起调再根据与标准血压计的偏差修正。还有两个细节影响判定稳定性一是包络曲线前后各会有一个大毛刺通常是充气切换和快放时产生的需要把压力高于160mmHg和低于30mmHg的包络段裁掉二是如果某段数据点数少于3个就不要直接判定进入错误处理重新测量。测完记得把MAP、SBP、DBP三个值一起显示方便调试。5. 调试避坑清单气压回路、传感器噪声和标定偏移最容易翻车的5处每次做血压计样机最后验收被退回来的问题十有八九都集中在这几个环节。这里按实际踩坑频率排序先说气路再说电路最后是标定。5.1 漏气导致压力升不上去先查接头再查阀现象充气20秒压力还不到120mmHg阀已经关了但压力保持不住一会就掉下来。原因袖带快速接头没有完全插到底或者气管与接头之间有裂缝也可能是放气阀在断电时密封不严。袖带接头这类快插结构最容易漏因为插拔几次后里面的O圈会变形。解决先把气路断开直接给气泵单独充到一个密闭容器看压力能不能稳定再用肥皂水刷每个接头冒泡位置就是漏气点。参数上我习惯这样做把袖带压力充到180mmHg后关泵观察60秒如果压力下降超过5mmHg说明气路有漏保持住才能继续做算法。注意别一上来就怀疑传感器传感器气嘴漏气的概率比接头低很多。5.2 泵一启动ADC数据就乱跳电源地线绕成回路了现象只要气泵一开压力ADC原始值在屏幕上以几十甚至上百个LSB幅度抖软件滤波压不下去。原因气泵启动电流瞬间几百毫安公共地线上产生压降。传感器参考地和泵地走的是同一条细线压降直接串到ADC测量回路。解决把负载地和模拟地分开星型单点接地传感器供电单独一颗LDOLDO输出端再加RC低通ADC采样时间调长一些。验证方法很简单断开气泵电源用手动气筒加压看ADC读数是否平稳。如果手压时纹波很小、一开泵就跳基本就是地线问题。这里不用追求高阶手段先把“泵、阀、传感器”三条地线理成从同一个铜点引出毛刺能消掉一大半。5.3 放气阀PWM占空比有死区比例控制提前失效现象占空比从10%调到50%放气速度没明显变化到60%以上突然很快放气压力曲线直接掉到底。原因电磁阀阀芯有机械惯性PWM脉冲宽度低于一定时间阈值时阀芯还没完全打开就该关了所以大部分小占空比脉冲都在无效区间浪费掉。不同阀的死区不同同一型号不同个体也有差异。解决先做占空比扫描。把袖带固定压力设到180mmHg占空比从5%开始每次加5%记录每秒钟压力降把数据画成曲线找到有效区间例如某阀有效区间是30%到85%占空比那算法里就不要输出低于30%的占空比。对应地放气速度3到5mmHg每秒在70mmHg到180mmHg压力段往往对应占空比40%到70%把它做成查找表比在线PID更容易调稳。扫描时血压计外壳要合上因为阀的安装角度会影响落座压力。5.4 测出的血压比听诊法整体偏高先查袖带和比例系数现象波形看起来正常包络形状也对但收缩压整体比听诊法高8到15mmHg舒张压也偏高。原因袖带尺寸不对成人袖带套在瘦弱手臂上压力偏大或者SBP和DBP判定系数与这一套气路不匹配。示波法的比例系数不是普适常数与充气压力、放气速度、阀特性都有关系。解决先换一条尺寸匹配的袖带再测如果仍然偏高把SBP系数从50%往下调到45%到47%DBP系数从75%往上调到77%到80%。标定方法是一次同时连接听诊法测量记录30组左右用最小二乘拟合出本机的系数。每个人手臂粗细不同固定系数不可能完全精确但平均值控制在可接受范围内是产品级要求。5.5 电池供电时数值漂移参考电压根本不是“参考”现象同一人静坐后连测两次收缩压差6mmHg而且电池电量越低差值越大。原因电池电压下降3.3V LDO输出跟着跌ADC参考电压也跌同一压力对应的ADC读数就不一致。如果软件里只按固定3.3V换算压力必然漂。解决第一选择是给VREF引脚接外部基准比如REF3025这类固定电压芯片第二选择是软件补偿每次测量前单独采一次内部VREFINT通道用它推算实际VDDA再按实际电压换算压力。这个方法在做“stm32 adc切换通道”时很常用把VREFINT作为最后一个虚拟通道读一次成本几乎为零。补偿公式不复杂实际VDDA等于内部基准标称值除以VREFINT的ADC读数再乘以满量程换算压力时用这个实际值代替固定3.3V。6. 这台血压计准不准怎么验证听诊法对比、重复性测试和进阶改动样机焊出来后先别急着上算法。第一步做静态压力验证把血压计气嘴接到标准压力表上手动加压到50、100、150、200mmHg看STM32读出的压力值与标准表误差。这一步能快速暴露传感器零点和换算系数问题。做法是在程序里加一个“压力校准模式”按键进入后显示当前压力值读数稳定后再记录不经过气路控制逻辑。第二步做听诊法对照让有经验的人用听诊器同时听血压计把结果存下来一个人完成所有测试减少判别差异。连续测30组后统计血压计与听诊法差值的均值和标准差。我自己的经验是标准差比均值更敏感均值差一两毫米汞柱可以通过系数补偿拉回来标准差大说明算法稳定性有问题要回头查放气速度和包络提取。第三步做重复性测试同一被测者静坐5分钟连续测3次收缩压相互之差不超过4mmHg左右算合格。如果合格说明系统本身的随机误差在可接受范围内如果3次结果差得大按第五章的顺序排查气路和电源别先改算法。进阶方向有两个比较值得做。一是给测量过程加一个放气速度闭环用ADC实时压力控制PWM占空比让放气速度恒定在4mmHg每秒这样包络曲线更均匀比例系数标定结果也会更稳定。二是加蓝牙或WiFi模块把测量结果上报做成物联网网关的节点或者用“stm32 dwt”的周期计数器做一套不带SysTick的精确延时避免操作系统节拍对采样时序的干扰。这两项都不改核心算法但对产品档次提升很大。我最后一次做这个项目时就是因为放气速度没有闭环电池电压下降到一定程度后放气变慢包络点变密但比例系数没变结果同一人两次测量差出6mmHg。后来加了一个最简单的比例调节占空比按实时压力查表修正问题才压下去。这一类细节正是血压计和普通传感器项目最不一样的地方希望帮到你。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑