ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

基于51单片机的脉搏血压体温测量仿真:信号调理与系统设计

基于51单片机的脉搏血压体温测量仿真:信号调理与系统设计 简介这套基于51单片机的脉搏心率测量仿真设计面向单片机初学者与电子设计竞赛备赛者可用于课程设计或综合实训。资料包含完整C程序、Proteus仿真文件、原理图及HEX烧录文件共23个文件打包为7z格式压缩包仅62KB轻量易获取。硬件链路涵盖红外光电传感器脉冲采集、放大整形、单片机处理、按键上下限设置、蜂鸣器报警以及LCD1602显示能直观呈现每分钟脉搏次数的测量与超限提示。目前已有超过1300人学习下载说明该方案具备较高的参考价值。通过对照仿真与原理解读读者可快速掌握模拟信号处理、定时/计数测频、显示驱动和报警逻辑便于移植扩展到血压、体温等多参数检测设计中。1. 基于51单片机的脉搏血压体温测量仿真从需求拆解到文件交付“基于51单片机的脉搏心率心跳血压体温测量检测仿真文件包含程序、仿真、原理图”这个标题在大学课程设计里出现频率极高下载来的压缩包里通常有Keil工程、Proteus仿真和一张原理图但三者的引脚分配经常对不上LCD不显示ADC乱跳。这类项目的本质不是算法多复杂而是三条采集链路——红外对管脉搏检测、压力传感器血压检测、DS18B20体温检测——要把模拟信号调理、51单片机资源分配和仿真环境特性对齐。这篇文章按信号链顺序拆开讲硬件参数怎么整定、C51程序怎么组织、Proteus仿真里传感器模型怎么搭最后落到原理图设计和实物排错给出一套能完整跑通的最小实现。2. 脉搏心率、血压、体温三条采集链路的硬件设计与参数整定2.1 脉搏心率检测的PPG原理与比较器整形电路光电容积脉搏波PPG的基本原理是红外LED通常选940nm或850nm透射或反射手指组织光电二极管接收透射光指尖血管随心跳搏动改变血液容积引起透射光强度变化光电二极管输出的电流信号随之变化。这个信号有两个特征一是直流分量很大典型值在几伏级别反映组织静态吸收二是交流分量很小只有直流分量的1%到5%频率范围在0.5Hz到5Hz对应30到300次/分钟的心率范围。所以信号调理的第一件事不是放大而是隔直和滤波。常见做法是一级隔直放大加一级比较器整形。前级运放接成同相交流放大输入端串联1µF电解电容隔离直流分量反相端接地电阻取10kΩ反馈电阻取510kΩ放大倍数约51倍。运放输出再接一个LM393比较器比较门槛取放大后信号峰峰值的中间值工程上直接把正输入端用两个10kΩ电阻分压到Vcc/22.5V因为交流信号经过隔直后是围绕2.5V上下波动的。比较器输出接51单片机的INT0外部中断引脚每一拍心跳产生一个下降沿中断程序里计数即可。这里有一个内置参数值得注意正常成年人静息心率60到100bpm对应信号周期600ms到1000ms而PPG信号上升沿时间只有100ms左右。比较器如果设置成过零触发抖动会非常大一定要加滞回。LM393在正反馈环路里加一个1MΩ电阻门槛从2.5V变成约2.4V和2.6V的滞回区间抗噪效果明显好于无滞回。链路传感器原始信号特征调理目标51单片机接口脉搏心率红外对管光电二极管mV级交流叠加几V直流隔直、放大51倍、滞回整形INT0外部中断血压MPX5050GP或电位器模拟0.2~4.7V直流压力叠加mV级振荡分压入ADC、RC滤波去脉动ADC0809的IN0通道体温DS18B20单总线数字信号4.7kΩ上拉、电平匹配P1.0普通IO口2.2 血压测量的示波法与压力传感器信号链血压测量在51单片机上做全自动示波法并不现实因为气泵放气速率控制、脉动包络搜索和收缩压/舒张压判定都需要一定运算量。课程设计里最常用的替代方案是压力传感器用MPX5050GP0~50kPa对应0.2V到4.7V输出气泵用继电器控制放气过程简化为定时器均匀放气ADC以每秒50次的速率采集压力值。仿真阶段则用两个电位器分别模拟袖带直流压力和交流振荡幅度一个按键切换显示收缩压还是舒张压程序按简化示波法做包络峰值搜索。示波法的处理逻辑可以简化成这样的链路袖带放气过程中每个心动周期产生一个动脉振荡波这些波的幅度先增后减形成类似钟形的包络。峰值位置对应平均压峰值前包络上升到最大幅度的70%处对应收缩压峰值后包络衰减到最大幅度的55%处对应舒张压。51单片机内存有限常见做法是采样128个点存入数组放气结束后离线搜索包络峰值这样比实时判断可靠得多。压力信号进ADC之前要加一级RC低通滤波截止频率设在10Hz既能保留脉搏振荡波和压力变化趋势又能滤掉继电器切换时的毛刺。R取10kΩC取1.5µF算下来约10.6Hz仿真里直接用MULTIMETER观察滤波后的电压是否平稳。2.3 DS18B20单总线体温测量与上拉电阻配置DS18B20测温范围-55°C到125°C12位分辨率下精度0.0625°C完全覆盖人体测温需求。单总线通信最重要的一条规则数据线必须接上拉电阻典型值4.7kΩ允许范围2.2kΩ到10kΩ。上拉太小总线高电平驱动能力变弱上拉太大时序边沿变缓高速模式容易出错。52单片机端口本身有内部上拉但驱动DS18B20这种开漏总线器件外部4.7kΩ更稳。供电方式上寄生供电和外部供电选后者。寄生供电需要数据线在高电平期间给内部电容充电测量转换期间MCU必须把总线拉高以提供能量如果代码时序处理不当转换结果会读到85°C这个错误值。外部供电则把VDD接3.3V或5V数据线只负责通信转换期间无需额外维持电流。Proteus仿真里DS18B20元件默认支持外部供电模型直接接VCC即可。51单片机访问DS18B20没有硬件单总线控制器时序全靠延时函数。12MHz晶振下执行一条普通指令约1µs复位脉冲要求480µs以上用两层嵌套循环实现读时序要求总线拉低6µs后采样写0时序要求总线拉低后继续保持60µs。这个时序窗口比较宽松用_nop_()和简单的空循环就能满足。/* 引脚分配与系统参数STC89C52RC12MHz晶振 */ sbit Pulse_In P3^2; /* 脉搏整形输出接INT0外部中断 */ sbit DQ P1^0; /* DS18B20数据线 */ #define VREF 5.0f /* ADC参考电压 */ #define ADC_CH_PRESS 0 /* 血压压力模拟通道接ADC0809 IN0 */ #define SAMPLE_N 128 /* 血压包络采样点数 */这段代码把三条链路的引脚资源一次性锁死P3.2是INT0外部中断专门等脉搏跳变沿P1.0给DS18B20ADC0809数据总线占用P0口P3.6和P3.7分别控制气泵继电器和显示切换按键。引脚分配到这一步就不要再改否则后面Proteus仿真图和原理图全部要跟着动。血压通道之所以接ADC0809的IN0是因为ADC0809的地址译码A、B、C全接地时默认选中IN0少两根地址线少两处出错的可能。3. C51程序实现定时器中断、ADC采样与心率算法落地3.1 定时器0做10ms时基定时器1数脉搏脉冲心率测量有两种思路一种是把脉搏整形信号送定时器1外部计数引脚定时器0做秒时基1秒后读计数值再乘以60另一种是测量两次脉搏跳变的时间间隔再换算。第一种适合信号质量一般、偶发漏检的情况时间窗口内计数天然有平均效果。第二种读数快但受单次抖动影响大剧烈运动时误差会到±10bpm。课程设计里建议用第一种代码简单且抗抖动。定时器1工作在计数模式外部脉冲从P3.5引脚进入定时器0工作在16位定时模式每10ms溢出一次。定时器0中断里累加100次就是1秒每秒读取定时器1的计数值差值心率等于差值乘以60。TMOD设置成0x51高四位是定时器1的计数模式低四位是定时器0的定时模式都是方式1的16位计数。/* 定时器0中断函数每10ms进一次累计1秒读取脉搏计数 */ void Timer0_Isr() interrupt 1 { static unsigned int ms10 0; static unsigned int last_cnt 0; unsigned int cur_cnt; TH0 0xD8; /* 65536-1000055536 (0xD8F0) */ TL0 0xF0; if (ms10 100) /* 满100次1秒 */ { ms10 0; TR1 0; /* 停T1避免读取时计数跳变 */ cur_cnt (TH1 8) | TL1; // 心率 (本次计数值-上次计数值) * 60 heart_rate (unsigned int)(cur_cnt - last_cnt) * 60; last_cnt cur_cnt; TH1 0; /* T1清0重新开始下一秒计数 */ TL1 0; TR1 1; } }这段逻辑的关键在于读取计数前先停掉定时器1否则TH1和TL1可能处于进位过程中高低字节组合出错。心率的计算结果是次/分钟正常范围60到100小于30或大于220基本可以判定为信号异常显示“----”而不是一个错误数字。需要说明的是脉搏信号每次心跳只有一个下降沿所以计数差值本身等于心跳次数乘以60就是bpm。如果后续想提高刷新率可以把时间窗口缩到5秒再乘12代价是显示跳动更频繁两种做法对应不同场景取舍。3.2 DS18B20温度读取的时序实现DS18B20的读写完全依赖主机控制总线时序三个核心动作分别是复位脉冲、写一个字节、读一个字节。复位时主机拉低总线480µs到960µs然后释放并读取从机应答脉冲写1时序是拉低总线1µs到15µs后释放写0时序是拉低总线60µs到120µs读时序是拉低总线1µs后释放在第15µs内完成采样。/* 读取DS18B20温度单位0.0625°C */ unsigned int ds18b20_read_temp_raw(void) { unsigned char low_byte, high_byte; unsigned int temp_raw; ds18b20_reset(); /* 复位总线 */ DQ 1; _nop_(); DQ 0; /* 写跳过ROM命令 0xCC */ write_byte(0xCC); write_byte(0x44); /* 启动温度转换 */ while (!DQ); /* 等待转换完成DQ拉高表示完成 */ ds18b20_reset(); write_byte(0xCC); write_byte(0xBE); /* 读暂存器 */ low_byte read_byte(); high_byte read_byte(); temp_raw (unsigned int)((high_byte 8) | low_byte); return temp_raw; }转换等待这段最好加超时保护DS18B20在12位分辨率下转换时间最长750ms如果单总线没接好while(!DQ)会死循环。常见的做法是加一个计数器超过20000次循环就返回0xFFFF表示读取失败。返回值是高8位和低8位的组合低4位是小数部分符号位在高字节的第5位体温场景基本都是正数直接乘以0.0625得到实际温度值即可。3.3 血压包络提取的简化算法仿真里血压信号的来源是两个电位器一个调节直流偏置模拟袖带压力一个调节交流幅值模拟脉动振荡。ADC0809以每秒50次的采样率连续采集128个点存入数组放气过程结束后统一处理。实际算法分三步走第一步计算基线取数组前10个点的平均值作为基准第二步计算每个点相对基线的偏差绝对值得到振荡幅值序列第三步搜索幅值序列的峰值和峰位按收缩压70%、舒张压55%的比例映射到压力值。/* 简化示波法包络搜索env[]为振荡幅值数组press[]为同步压力值 */ unsigned char i, peak_index 0; unsigned int max_env 0; for (i 0; i SAMPLE_N; i) { if (env[i] max_env) { max_env env[i]; peak_index i; } } /* 收缩压峰前第一个幅值超过70% max_env的点对应压力 */ /* 舒张压峰后第一个幅值衰减到55% max_env的点对应压力 */这段代码的工程性改良点是加平滑直接对env数组求差分会把单点毛刺放大算峰值前先做三邻域平均再搜索时用滞回比较小于阈值连续5个点才确认越过阈值。仿真阶段就算不做平滑也能出数但移植到真实传感器上会频繁误判所以保留平均这一步更稳妥。另外128个采样点对应放气持续时间约2.56秒这个时长在仿真里没问题真实袖带放气通常要8到15秒采样周期要改成每点50ms才能覆盖完整放气过程。4. Proteus仿真文件搭建元件清单、传感器模型与联合调试4.1 仿真整体结构与元件清单Proteus仿真要把51单片机、模拟前端和显示外设放在同一张图里元件清单按功能划分成四块MCU及最小系统、模拟信号链、显示交互、电源和调试辅助。元件型号数量作用单片机AT89C511主控程序中替换为STC89C52RC同管脚运放LM3581脉搏信号一级交流放大比较器LM3931脉搏信号整形输出方波数据采集ADC08091血压压力模拟量转数字量温度传感器DS18B201单总线测温液晶屏LM016L12行16列显示心率、体温电位器POT-HG2模拟血压直流压力和振荡幅度脉冲源PULSE1模拟PPG脉搏信号去耦电容10µF0.1µF若干每芯片电源引脚各配单片机晶振放12MHz电容22pF复位电路用10µF电解电容加10kΩ电阻上电自动复位。LCD的V0引脚串一个5kΩ电位器到GND调对比度仿真里不调会白屏这是最多人遇到的问题。ADC0809的CLK引脚务必接一个时钟源可以直接用单片机的ALE引脚也可以加一个PULSE信号源设成500kHz不接时钟ADC永远输出0xFF或不变。4.2 用PULSE信号源模拟PPG脉搏波形真实PPG信号是带直流偏置的不规则脉动波Proteus里最接近的模拟方式是PULSE信号源叠加直流偏置。设置方法初始低电平0V高电平1V脉冲宽度0.1秒周期0.8秒对应75bpm相位延迟0。输出端接一个1µF电容隔直再送入LM358放大效果和无信号源时的直流偏置完全区分开。仿真时务必在脉搏信号源和放大器之间留一个测试点用虚拟示波器分别观察传感器源点、运放输出和比较器输出三个位置。源点应该是0V到1V的脉冲方波运放输出是被放大后的双向波形隔直后负半周朝下比较器输出是规则的0V/5V方波方波频率就是心率。如果比较器输出一直高电平或者一直低电平说明门槛电压没落在信号幅度范围内调一下分压电阻比例就行。这个三步观察法对模拟信号链路的排错价值最大它能直接定位问题出在前级放大、比较器门槛还是后级计数逻辑。4.3 Keil5生成HEX文件与工程参数对齐Keil5里新建工程时选芯片型号要严格对应Proteus里的型号AT89C51和STC89C52RC管教兼容但RAM和Flash大小不同编译出来的HEX可能包含Proteus仿真的AT89C51不支持的地址段。稳妥的做法是Keil里选Atmel AT89C51仿真用AT89C51原理图用STC89C52RC实机烧录时重新选择STC型号编译一次因为这两者的头文件寄存器定义是一样的代码层面完全兼容。编译设置里打开Output选项卡勾选Create HEX File然后在Proteus里双击单片机Program File路径指向生成的HEX文件。调试顺序是先调LCD能显示字符后再调DS18B20温度固定温度正确后再加脉搏仿真信号源最后再接ADC0809和电位器做血压模拟。把每一步分开验证的好处是出问题能缩小范围一体化调试一旦不显示就先乱成一锅粥。5. 原理图模块化设计与仿真到实物的排错技巧5.1 原理图模块化布局与去耦参数原理图在AD或立创EDA里绘制时按供电入口、51单片机最小系统、脉搏信号调理、血压采集、DS18B20、显示和外设六个模块分块摆放。每一块用一个矩形边框圈起来并标注功能评审老师和后期调试都容易进入状态。电源去耦按“每芯片一组”的规则每个芯片的VCC引脚放一个0.1µF陶瓷电容就近接地板级电源入口放一个10µF到100µF电解电容。三个设计习惯直接影响实物稳定性。第一ADC0809和运放的模拟地与数字地分开走线在电源入口处单点连接第二脉搏放大器输入端走线远离继电器驱动线和气泵电机线避免50Hz工频干扰从寄生电容耦合进来第三DS18B20的数据线不要铺地铜皮单总线器件的寄生电容过大会拉慢上升沿导致时序不稳。5.2 仿真正常但实物不工作的四步排查法实物和仿真最大的差异是电源质量、传感器偏置和参考电压按顺序排查能把问题压缩到最小范围。排查步骤检查点操作方法1电源纹波示波器AC档测5V观察有无高频毛刺2运放偏置点万用表测LM358输出静态应在1.5V到3.5V3单总线波形示波器测DQ引脚复位和应答脉冲是否完整4ADC时钟确认ADC0809的CLK引脚有脉冲输入第四步最容易被忽略但影响最严重ADC0809的CLK引脚内部没有时钟源必须外部提供10kHz到1MHz的方波否则ADC转换结果直接不可用。仿真里如果忘了接CLK结果还能勉强看到几个数在跳实物的表现是ADC值固定不变或者全部为0。合规的接法是从ALE引脚引信号经过分频后接CLK或者直接用一个定时器中断翻转IO引脚产生方波。如果实物测量时心率值比正常高出一倍多半是LM393比较器输出沿抖动导致外部中断重复触发给P3.2引脚加一个10kΩ下拉电阻并开启INT0的中断标志位清空逻辑能缓解大半。这些都确认无误后再把放气过程加长到10秒以上用串口把压力数组打出来画成折线图核对包络形态是否符合预期。仿真文件、程序和原理图三者的引脚关系保持一致整套流程才算闭环。本文还有配套的精品资源点击获取
返回列表