1. 项目背景与核心需求
心率监测设备在现代健康管理中扮演着越来越重要的角色。无论是日常健康监测还是运动时的实时追踪,一个便携、精准的心率监测系统都能为用户提供有价值的数据支持。基于STC89C52单片机和红外传感器的方案,以其低成本、低功耗和易用性,成为DIY爱好者和电子工程师的热门选择。
这个项目的核心目标是开发一个能够实时检测并显示心率的便携设备。与专业医疗设备相比,我们的系统更注重实用性和可操作性,适合家庭使用和运动场景。STC89C52作为经典的51系列单片机,具有丰富的外设接口和成熟的开发环境,非常适合这类嵌入式应用。而红外传感器(如ST188)则通过非接触方式检测血流变化,避免了传统电极式传感器的不便。
在实际开发中,我发现这个项目有几个关键优势:首先是成本控制,整套硬件成本可以控制在百元以内;其次是可定制性,用户可以根据需要调整报警阈值和显示方式;最后是便携性,成品可以做到比手表稍大的体积,方便随身携带。
2. 硬件系统设计详解
2.1 核心控制器选型
STC89C52RC是宏晶科技推出的增强型51单片机,相比基础型号具有更多RAM(512字节)和Flash(8KB),支持最高35MHz主频。我选择它的主要原因有三点:首先是有丰富的IO口(32个)可以连接各种外设;其次是内置看门狗和EEPROM,提高了系统可靠性;最后是广泛的技术支持和成熟的烧录工具。
在实际使用中,STC89C52的P0口需要外接上拉电阻(通常用10kΩ排阻),而P1-P3口内部已有上拉。特别注意,如果使用内部RC振荡器,虽然节省了外部晶振,但精度较差(±1%),对于需要精确计时的应用建议外接11.0592MHz晶振。
2.2 红外传感器电路
ST188是一款常用的反射式红外传感器,包含红外发射管和接收三极管。工作时,发射管发出红外光,当血液流经指尖时,反射光强度会随脉搏波动。接收管将这些变化转换为微弱的电流信号(通常在μA级)。
为了提高信噪比,我设计了三级信号处理电路:
- 前置放大:使用LM358搭建同相放大器,增益约100倍
- 带通滤波:中心频率1Hz-5Hz,滤除直流偏移和高频噪声
- 电压抬升:将双极性信号抬升到0-5V范围,适配单片机ADC
// 典型ADC初始化代码(STC89C52需外接ADC芯片如PCF8591) void ADC_Init() { PCF_Init(); // 初始化I2C接口 PCF_Write(0x40); // 配置ADC通道0 }2.3 电源管理设计
考虑到便携性,系统采用3.7V锂电池供电,通过HT7333稳压到3.3V。实测整机工作电流约15mA,2000mAh电池可连续工作5天以上。为了节省功耗,我加入了运动检测功能:当3分钟内无脉搏信号时,系统自动进入休眠模式(电流降至50μA)。
3. 软件算法实现
3.1 信号采集与预处理
原始脉搏信号含有大量噪声,需要通过软件进一步处理。我采用移动平均滤波结合中值滤波的方法:
#define SAMPLE_SIZE 10 int filter(int new_sample) { static int buffer[SAMPLE_SIZE]; static int index = 0; buffer[index] = new_sample; index = (index + 1) % SAMPLE_SIZE; // 中值滤波 int temp[SAMPLE_SIZE]; memcpy(temp, buffer, sizeof(buffer)); bubbleSort(temp); // 实现略 return temp[SAMPLE_SIZE/2]; // 返回中值 }3.2 心率计算算法
准确检测R波峰值是计算心率的关键。我实现了基于斜率阈值的方法:
- 计算信号差分:diff[n] = signal[n] - signal[n-1]
- 当差分值超过阈值且后续出现过零点时,判定为有效峰值
- 记录连续两个峰值的时间差Δt,心率=60/Δt (bpm)
int detect_peak(int sample) { static int last = 0; int diff = sample - last; last = sample; if(diff > THRESHOLD && !peak_detected) { peak_detected = 1; return 1; } return 0; }3.3 用户界面设计
系统使用12864 LCD显示实时波形和心率值。通过三个按键实现功能切换:
- KEY1:切换显示模式(波形/数值)
- KEY2:增加报警阈值
- KEY3:减少报警阈值
界面刷新采用局部刷新策略,避免全屏刷新导致的闪烁。心率值每5秒更新一次,波形每100ms采样一点。
4. 系统优化与实测数据
4.1 硬件优化技巧
在原型测试阶段,我发现几个常见问题及解决方案:
- 信号基线漂移:在传感器输出端加入1μF隔直电容
- 环境光干扰:用黑色热缩管包裹传感器,只留出检测窗口
- 电源噪声:每个IC的VCC引脚添加0.1μF去耦电容
4.2 实测性能对比
在不同运动状态下测试10名志愿者,与专业心率带对比结果:
| 状态 | 本系统误差(bpm) | 响应时间(s) |
|---|---|---|
| 静坐 | ±2 | 3 |
| 步行 | ±3 | 4 |
| 跑步 | ±5 | 5 |
4.3 扩展功能实现
通过添加蓝牙模块(如HC-05),可以将数据无线传输到手机APP。我修改了串口协议,每秒钟发送一次心率数据:
void Bluetooth_Send(int heart_rate) { printf("HR:%03d\n", heart_rate); // 格式如"HR:075" }对于需要存储历史数据的场景,可以外接AT24C02 EEPROM芯片,按小时存储平均心率。