
简介面向单片机课程设计的一款电子血压计设计方案以单片机为控制核心集成压力传感器采集血压信号、温度传感器采集体温数据通过按键切换显示完整覆盖处理、测量、信号处理、显示与电源五大模块。包内共22个文件整体约865KB包含Keil工程源码、编译生成的HEX可烧录文件、Proteus仿真图和任务书/设计报告文档适合需要快速理解系统框架并动手实践的本科生。这份资料不仅提供可直接运行的源码和仿真环境还附有设计报告能帮助读者梳理传感器选型、信号调理到模块联调的关键思路。已有589人学习下载对正在准备课设或复习单片机应用的同学极具参考价值。1. 单片机电子血压计的设计示波法原理与系统框架把基于单片机的电子血压计设计当作课程设计或毕业设计来做时最容易踩空的点不在代码而在示波法Oscillometric Method这条信号链袖带放气过程中压力传感器同时采集缓慢下降的静压和叠加其上的脉搏波振荡后者振幅从小到大再减小峰值对应平均动脉压 MAP上升段与下降段的特征比例点对应收缩压与舒张压。整套设计包含压力传感器选型、信号调理、单片机 ADC 采样、包络提取与特征点判读、标定五个环节。下面按一套在 51 单片机上可复现的最小系统展开逻辑同样适用于 STM32。2. 电子血压计的硬件信号链压力传感器、放大电路与气路驱动先搭硬件再谈算法因为示波法对信号完整性的要求远高于一般传感器采集。放气过程中静压变化只有 23 mmHg/s叠加其上的脉搏波幅度是静压的几十分之一传感器、放大器和 ADC 任何一级引入的噪声都会直接进入后面的包络计算最终表现为血压读数整体偏移或逐次跳动。2.1 压力传感器与单片机最小系统的接口血压测量的量程一般取 0300 mmHg约等于 040 kPa为充气超压留出余量。常见选型如下表传感器型号量程输出方式接口/供电适用场景MPX5050GP0375 mmHg模拟 0.24.7 V5 V内置放大与温补血压计最常见选型MPX5100DP0750 mmHg模拟5 V量程偏大分辨率差XGZP6847040 kPa模拟 / I2C3.3 V / 5 VI2C 版免调理电路MS5611060 kPaI2C3.3 V精度高但需二次封装多数人选 MPX5050GP应变桥、温度补偿与放大电路封装在一起输出近似 Vout 0.2 V 0.09 V/kPa × P。按 300 mmHg40 kPa折算输出约 3.8 V正好落进 STC89C52 的 5 V ADC 量程。若选 XGZP6847 的 I2C 版固件可以直接读数字压力省掉调理电路但 I2C 连续读取速率会限制采样率示波法需要至少 100 Hz 的脉动跟踪数字接口版更适合对体积敏感、不追求采样密度的设计。2.2 信号调理电路增益计算与低通滤波如果只买到裸压力芯体放大电路必须自己搭。以灵敏度 0.25 mV/mmHg、量程 0300 mmHg 的芯体为例把满量程输出抬到 04 V需要约 53 倍增益。常见做法是双运放仪表放大器结构增益公式 Av 1 2Rf/Rg。取 Rf 100 kΩ、Rg 3.9 kΩAv ≈ 52满量程输出约 3.9 V配合 10 位 ADC5 V/1024 ≈ 4.88 mV理论分辨率约 0.4 mmHg满足示波法要求。放大后需要一级无源低通。脉搏波能量集中在 0.55 Hz充气泵和电磁阀的噪声多落在 50 Hz 以上R 16 kΩ、C 0.1 µF 组成约 100 Hz 截止频率的 RC 低通放在 ADC 引脚附近并用独立地平面与数字部分隔离。提示MPX5050GP 这类集成放大器件输出阻抗较高ADC 采样瞬间的保持电容会拉低电压建议在 ADC 引脚对地并联 100 nF 电容并适当延长采样保持时间。2.3 充气泵与放气阀的驱动逻辑气路部分决定放气速率。充气泵用 6 V 微型隔膜泵峰值电流 23 A必须经三极管S8050或达林顿管ULN2003驱动GPIO 只提供控制信号。放气有两种结构固定针阀靠机械限流孔实现 23 mmHg/s 的自然泄放电磁阀则用于测量结束后的快速放气。需要可控慢放气的设计可对电磁阀做 PWM 占空比控制。充气阶段逻辑如下// 51 单片机气路控制P2.1 接泵P2.2 接电磁阀低电平有效 #define PUMP_PIN P2_1 #define VALVE_PIN P2_2 void pump_on(void) { PUMP_PIN 0; } // 打开充气泵 void pump_off(void) { PUMP_PIN 1; } // 停止充气 void valve_open(void) { VALVE_PIN 0; } // 打开快速放气阀 void valve_close(void) { VALVE_PIN 1; } // 关闭放气阀 void inflate_to(uint16_t target_mmhg) { pump_on(); valve_close(); while (get_pressure() target_mmhg) { delay_ms(5); // 5 ms 轮询压力一次 } pump_off(); }说明target_mmhg 通常取预估收缩压 30 mmHg下限 170、上限 250防止超压充气速度约 2030 mmHg/s5 ms 轮询不会漏过压力变化。泵停止瞬间会产生反电动势续流二极管放在电机两端气路接口处加一小段硅胶管减振能明显减少泵振动对传感器输出端的机械耦合并降低包络毛刺。3. 单片机 ADC 数据采集与滤波从原始压力到脉搏波压力 ADC 值里同时包含静压基线和幅值很小的脉搏振荡两条信息要分别提取静压曲线用于定位特征点对应的压力值振荡曲线用于得到包络线。这一章的滤波质量直接决定第四章判读是否正确也是跑通压力显示但测不出脉搏波这类问题的高发位置。3.1 采样率、放气速率与 ADC 配置的匹配示波法对采样率的要求来自两个约束脉搏波最高频率约 5 Hz以及放气速率不能太快导致特征点丢失。推荐放气速率 23 mmHg/s采样率取 100 Hz。下表给出不同采样率下的实际表现采样率每搏采样点数60 bpm 时适用场景50 Hz50 点只测静压不适合示波法100 Hz100 点示波法脉搏波提取常用200 Hz200 点额外分析脉搏波形细节STC89C52 的 10 位 ADC 单次转换约 10 µs100 Hz 采样几乎不占 CPU。需要注意 ADC 参考电压把传感器供电和 ADC 参考接到同一路低噪声 LDO用比例方式计算压力可以抵消电源波动带来的读数漂移。换用 STM32 时建议开 ADC 的 DMA 循环采样把 CPU 留给包络计算。3.2 基线分离与滑动平均滤波原始 ADC 值 静压基线 脉搏振荡。静压变化缓慢用长窗口滑动平均取基线振荡分量用原始值减基线再做短窗口平滑。经验参数基线窗口 1 秒100 个点振荡平滑窗口 5 个点等效截止频率约 10 Hz。窗口太短会吃掉低频脉搏成分太长则基线滞后特征点对应压力会系统性偏移。3.3 采样子程序与主循环下面代码可在 Keil 5 的 51 单片机工程里直接运行换到 STM32 只需替换 adc_read 的实现#define SAMPLE_RATE 100 // 100 Hz 采样 #define BASE_WIN 100 // 基线窗口 1 s #define AC_WIN 5 // 振荡平滑 5 点 uint16_t base_ring[BASE_WIN]; uint8_t base_idx 0; uint32_t base_sum 0; int16_t ac_ring[AC_WIN]; uint8_t ac_idx 0; // 采一个压力点返回滤波后的振荡分量 int16_t sample_pressure_ac(void) { uint16_t raw adc_read(0); // 读压力通道 ADC base_sum - base_ring[base_idx]; // 基线环形缓冲更新 base_ring[base_idx] raw; base_sum raw; base_idx (base_idx 1) % BASE_WIN; uint16_t base base_sum / BASE_WIN; int16_t ac (int16_t)raw - (int16_t)base; ac_ring[ac_idx] ac; // 5 点滑动平均 ac_idx (ac_idx 1) % AC_WIN; int32_t sum 0; for (uint8_t i 0; i AC_WIN; i) sum ac_ring[i]; return (int16_t)(sum / AC_WIN); }逻辑说明先用 100 点环形缓冲平均得到基线再用原始值减基线做差分最后做 5 点平均。差分操作会把 ADC 量化噪声放大所以最后一级平滑不能省。若发现包络毛刺多优先检查 AC_WIN 是否被人为调大——平滑点数过多会压低峰高导致后续 SBP/DBP 阈值错判。主循环由定时器产生 10 ms 节拍驱动bit tick_10ms 0; void timer0_isr(void) interrupt 1 { tick_10ms 1; // 10 ms 置一次标志 } void main_loop(void) { while (1) { if (tick_10ms) { tick_10ms 0; int16_t ac sample_pressure_ac(); envelope_update((uint16_t)get_pressure_mmhg(), ac); } } }4. 电子血压计判读算法包络提取与收缩压/舒张压定位包络线是判读环节的核心产物横轴为袖带压力纵轴为脉搏振荡幅度。放气过程中把每个采样点的振荡幅度按当前压力落入 1 mmHg 档位累加平均后得到完整包络曲线峰值点对应 MAP峰值两侧的比例点对应 SBP 与 DBP。4.1 包络提取的两种方式一是逐跳峰值检测在每个心动周期内找振荡波形的局部极大、极小值差值作为该周期振幅。心率不齐时容易漏检需要自适应周期窗口。二是滑动窗口 RMS 法对 0.3 秒窗口内的振荡信号求均方根作为该时刻的振荡能量。第二种对单点噪声更稳健推荐优先实现。RMS 值按当前压力取整到 1 mmHg 档位更新对应数组元素放气结束即得到完整包络。4.2 SBP 与 DBP 特征点判定比例包络是单峰曲线。SBP 与 DBP 由幅度比例确定这是示波法唯一需要仔细调参与验证的环节参数比例范围初始建议值读数不准时的调整方向SBP 阈值0.450.55 × Amax0.50读数偏高时调向 0.55MAP1.00 × Amax峰值点受放气速率影响最大DBP 阈值0.650.80 × Amax0.72读数偏低时调向 0.65判定规则在包络上升段找第一个振幅大于 SBP 阈值的点该点袖带压力为收缩压在下降段找第一个振幅小于 DBP 阈值的点对应舒张压。DBP 从峰值向低压侧扫描方向不要弄反。4.3 判读函数实现放气结束后pressure[] 和 envelope[] 两个数组存放了整条包络typedef struct { uint16_t sbp; uint16_t map; uint16_t dbp; uint8_t valid; } bp_result_t; bp_result_t bp_calc(const uint16_t *pres, const uint16_t *env, uint16_t n) { bp_result_t r {0, 0, 0, 0}; uint16_t amax 0, idx_max 0; for (uint16_t i 0; i n; i) { if (env[i] amax) { amax env[i]; idx_max i; } } if (amax 20) return r; // 振荡太弱判为无效 r.map pres[idx_max]; for (uint16_t i idx_max; i 0; i--) { if (env[i] (uint16_t)(amax * 0.50f)) { r.sbp pres[i]; break; } } for (uint16_t i idx_max; i n; i) { if (env[i] (uint16_t)(amax * 0.72f)) { r.dbp pres[i]; break; } } r.valid (r.sbp 0 r.dbp r.sbp) ? 1 : 0; return r; }说明amax 20 的阈值是 ADC 计数单位实际值要按自己的增益调原则是低于正常脉搏振荡幅度的三分之一。若分辨率要求到 1 mmHg 以内可在阈值点两侧做线性插值P P1 (P2 - P1) × (Amax×ratio - E1)/(E2 - E1)。valid 里额外检查 dbp sbp防止包络出现多峰时下降段的毛刺被误判成 SBP 特征点。5. 电子血压计压力标定与整机调试校准步骤与常见坑放大器和 ADC 都存在零点偏置与增益误差直接换算会导致读数整体偏移。标定就是给每台硬件单独求解ADC 数值 → mmHg的线性系数且系数必须存在非易失存储里不能写死在程序里。5.1 两点标定流程与系数计算用三通把气路同时接到被测设备和一块经过校准的压力表或水银血压计系统上电、袖带完全泄压记录 ADC 值 adc_zero充气至压力表稳定显示 200 mmHg记录 adc_200计算斜率 k 200.0 / (adc_200 - adc_zero)任意压力 P (adc - adc_zero) × k。两点标定对 MPX5050GP 这类温度补偿器件足够。对未补偿的裸传感器还要在每次测量前做一次零位刷新袖带泄压状态下自动采若干点取平均更新零点避免温漂累积。5.2 标定系数的存储标定系数写进 AT24C02I2C 接口比较通用换单片机型号调试时不用改代码/* 写两个 16 位标定值到 AT24C02地址 0x00 起高字节在前 */ void cal_save(uint16_t adc_zero, uint16_t adc_200) { i2c_start(); i2c_send_byte(0xA0); // AT24C02 器件地址 写 i2c_send_byte(0x00); // 起始地址 i2c_send_byte(adc_zero 8); i2c_send_byte(adc_zero 0xFF); i2c_send_byte(adc_200 8); i2c_send_byte(adc_200 0xFF); i2c_stop(); delay_ms(5); // 等待器件内部写周期 }说明读取时按同样顺序拼回两个数。STC 片内 EEPROM 也可以承担这个任务但按扇区擦写的限制比较多调试阶段不如外部 EEPROM 直观。5.3 整机调试常见问题排查现象可能原因处理压力读数整体偏高或偏低标定系数过期或参考电压漂移重新两点标定检查 LDO 输出读数跳动超过 5 mmHg气路漏气或袖带未绑紧检查硅胶管接口重新绑袖带包络毛刺明显泵振动耦合进传感器停泵 200 ms 后再采样加缓冲管SBP 与 DBP 差值过近放气速率快于 5 mmHg/s调整针阀孔径控制到 23 mmHg/s调试时先把 pressure[] 与 envelope[] 通过串口发到上位机用 VOFA 绘制包络曲线确认峰值位置与比例点无误后再固化算法。多数第一次实现的包络不是多峰就是平台属于正常现象先看曲线再调参数比盲目改采样率更有效。6. 电子血压计测量结果可靠性验证异常判定与多测次均值算法能出数不等于数可信。示波法本身的包络特征点判定在噪声、移动伪迹和袖带异常情况下可能输出一个看起来正常的错误血压值因此设备端必须保留一层质量判定。下面给出可直接落地的丢弃规则和多次测量均值策略前者保证不显示错误数据后者让读数在统计上更接近真实血压。6.1 无效测量的判定标准三条硬规则直接丢弃当次结果一是 SBP 或 DBP 落在 60260 mmHg 之外二是 SBP 与 DBP 的差值小于 20 mmHg这通常意味着袖带尺寸不符或包络特征点定位错误三是充气阶段压力超过 250 mmHg立即打开放气阀并提示重新绑带。另外放气过程中连续 3 秒检测不到有效脉搏波也应判为无效而不是硬给一个值。6.2 三次测量的均值策略临床常用的流程是间隔 12 分钟测量三次取平均值。单片机端实现为连续测量三次间隔 60 秒SBP 取三次算术平均作为显示值第一次数值往往因紧张偏高可以只作参考。若任意两次 SBP 差值超过 10 mmHg说明测量环境不稳定手臂移动、袖带松动自动提示重测。均值计算用三个变量即可#define MAX_TRIALS 3 uint16_t sbp_buf[MAX_TRIALS], dbp_buf[MAX_TRIALS]; uint16_t tri_avg(uint16_t *buf) { uint32_t sum 0; for (uint8_t i 0; i MAX_TRIALS; i) sum buf[i]; return (uint16_t)(sum / MAX_TRIALS); }把三次单次结果连同均值写入 AT24C02 历史区按日期保存最近 10 组。下次测量后与上次均值比较差值超过 15 mmHg 时在显示屏提示波动较大建议复测。验证阶段可以在 Proteus 里用信号源模拟一组带噪声的放气过程把同一套判读函数跑一遍比对 SBP/DBP 输出与输入设定值的偏差确认阈值与均值逻辑在仿真层面成立后再上实物袖带联调。本文还有配套的精品资源点击获取