4、感知电路设计:心内信号特征、感知放大器设计、自动增益控制
说到起搏器的感知电路,我脑子里第一个蹦出来的词就是「难搞」。你想想看,要在心脏那个不停跳动的环境里,从一堆噪声和干扰中准确抓出几毫伏的心内信号,这活儿真不是随便搭个运放就能干的。
我入行那会儿,带我的老工程师跟我说过一句话,我一直记着:「感知电路做不好,起搏器就是个瞎子。」嗯,这话一点不夸张。今天咱们就把这块硬骨头啃下来。
4.1 心内信号特征:你得知道你要感知什么
先聊聊心内信号长什么样。说白了,起搏器电极直接贴在心肌上,它捕捉到的信号和体表心电图完全是两码事。
心内信号的核心参数:
| 参数 | 典型范围 | 备注 |
|---|---|---|
| P波幅度 | 1 ~ 8 mV | 心房感知,幅度偏小 |
| R波幅度 | 5 ~ 25 mV | 心室感知,幅度较大 |
| 信号上升时间 | 10 ~ 50 μs | 斜率很陡,这是关键特征 |
| 频率范围 | 0.5 ~ 100 Hz | 主要能量集中在10~30 Hz |
| T波幅度 | 1 ~ 3 mV | 这是干扰源,需要抑制 |
这里有个坑,我踩过。心内信号的幅度不是固定的。病人体位一变、呼吸一深,信号幅度能差好几倍。你按静态参数设计放大器,到临床上一准出问题。
核心要点:心内信号的特点是「幅度小、斜率陡、动态范围大」。感知电路的设计目标就是:在噪声中准确识别P波和R波,同时抑制T波和肌电干扰。
4.2 感知放大器设计:从电极到数字信号
感知放大器,我习惯把它分成三级来看:前置放大、带通滤波、比较整形。每一级都有讲究。
4.2.1 前置放大级
电极过来的信号,也就几毫伏。第一级放大器必须做到两件事:低噪声、高输入阻抗。
为什么高输入阻抗?因为电极和心肌的接触阻抗不是固定的,有时候能到几百千欧。输入阻抗低了,信号就被分压了,你放大个啥?
我一般用仪表放大器,比如INA333这类。共模抑制比(CMRR)至少要100 dB以上。为什么?因为心内信号是差模信号,但人体会耦合进来50 Hz的工频干扰,那是共模信号。CMRR不够,工频干扰直接淹掉心内信号。
// 典型前置放大级设计参数
// 增益设置:50倍(约34 dB)
// 输入阻抗:> 10 MΩ
// CMRR:> 100 dB
// 噪声:< 1 μVrms(0.5-100 Hz)
// 增益电阻计算
// G = 1 + (49.4 kΩ / Rg)
// 目标G = 50
// Rg = 49.4 kΩ / (50 - 1) ≈ 1.01 kΩ
我的经验:前置放大级的PCB布局要特别注意。输入走线越短越好,周围用地线包围。我曾经有一版设计,噪声指标死活下不来,最后发现是输入走线太长,耦合了数字部分的开关噪声。重新布局后,噪声直接降了一半。
4.2.2 带通滤波级
前置放大完了,信号还是混着各种乱七八糟的东西。这时候需要带通滤波器,把有用的频段挑出来。
心内信号的主要能量在10~30 Hz。低于0.5 Hz的是基线漂移,高于100 Hz的是肌电干扰和开关噪声。所以滤波器的通带我一般设在1 Hz到80 Hz之间。
具体实现上,我推荐用二阶巴特沃斯滤波器。为什么?因为它在通带内最平坦,不会把心内信号的幅度给压歪了。
// 二阶带通滤波器设计(Sallen-Key结构)
// 中心频率:20 Hz
// 品质因数Q:0.707(巴特沃斯响应)
// 低频截止:1 Hz(一阶高通)
// 高频截止:80 Hz(二阶低通)
// 元件值计算(示例)
// 高通部分:C1 = C2 = 1 μF, R1 = R2 ≈ 159 kΩ
// 低通部分:C3 = C4 = 0.1 μF, R3 = R4 ≈ 19.9 kΩ
注意:滤波器的阶数不是越高越好。阶数高了,相位延迟会变大。起搏器对时序要求很严,相位延迟大了会影响感知窗口的准确性。我一般控制在二阶到四阶之间。
4.2.3 比较整形级
滤波后的信号还是模拟的,得转成数字信号给微控制器处理。这一步用比较器完成。
比较器的阈值怎么设?固定阈值肯定不行。信号幅度会变,固定阈值要么漏检,要么误检。所以需要动态阈值,这就是后面要讲的自动增益控制。
比较器本身也有讲究。要选带迟滞的,不然信号在阈值附近抖动时,输出会来回跳,产生所谓的「震颤」现象。
// 比较器迟滞设计
// 迟滞电压:典型值取信号幅度的5%
// 假设信号幅度为10 mV,迟滞设为0.5 mV
// 上阈值:Vth + Vhyst/2
// 下阈值:Vth - Vhyst/2
// 迟滞电阻计算(以LMV331为例)
// Vhyst = Vcc * (R1 / (R1 + R2))
// 设Vcc = 3.3V, Vhyst = 0.5 mV
// R1 / (R1 + R2) = 0.5 mV / 3.3V ≈ 1.5e-4
// 取R1 = 1 kΩ, 则R2 ≈ 6.6 MΩ
4.3 自动增益控制:让放大器自己适应
自动增益控制(AGC),这是感知电路里最体现功力的地方。说白了,就是让放大器根据输入信号的强弱,自动调整增益,保证输出幅度基本稳定。
为什么需要AGC?我举个例子。病人刚植入起搏器时,电极和心肌接触好,R波可能有20 mV。过几个月,电极周围长了纤维组织,信号可能掉到5 mV。没有AGC,你让比较器阈值设多少?
4.3.1 AGC的实现方式
我见过几种方案,各有优劣:
- 模拟AGC:用压控增益放大器(VGA),通过反馈环路控制增益。响应快,但电路复杂,功耗高。
- 数字AGC:用可编程增益放大器(PGA),微控制器根据检测到的信号幅度,调整增益档位。灵活,功耗低,但响应慢。
- 混合AGC:前级用固定增益,后级用数字控制衰减器。我比较喜欢这种,兼顾了响应速度和灵活性。
我的推荐:起搏器里我倾向于用数字AGC。虽然响应慢一点,但功耗低、设计简单。而且起搏器的感知窗口是周期性的,有足够的时间让MCU去调整增益。
4.3.2 AGC的控制策略
AGC不是简单的「信号小了就加增益」。这里有几个关键点:
- 增益调整步长:每次调整3 dB左右,太大会引起输出抖动。
- 调整间隔:至少隔一个心动周期再调整,避免在同一个心跳内反复调整。
- 增益上下限:我一般设20 dB到60 dB的范围。低于20 dB,噪声太大;高于60 dB,电路容易自激。
- 保持时间:增益调整后,要维持一段时间(比如10个心动周期),确认信号稳定了再继续调整。
// 数字AGC控制伪代码
// 目标输出幅度:500 mV(峰峰值)
// 增益范围:20 dB ~ 60 dB,步长3 dB
void agc_control(float measured_amplitude) {
static uint8_t current_gain_index = 10; // 初始增益30 dB
static uint16_t stable_count = 0;
float target = 0.5; // 目标幅度500 mV
float error = target - measured_amplitude;
// 误差超过10%才调整
if (fabs(error) / target > 0.1) {
stable_count = 0;
if (error > 0) {
// 信号太小,增加增益
if (current_gain_index < 13) { // 最大60 dB
current_gain_index++;
}
} else {
// 信号太大,减小增益
if (current_gain_index > 3) { // 最小20 dB
current_gain_index--;
}
}
} else {
stable_count++;
// 连续10次稳定,锁定增益
if (stable_count >= 10) {
// 锁定当前增益,进入低功耗模式
agc_lock();
}
}
set_gain(current_gain_index * 3 + 20); // 实际增益值
}
避坑指南:我曾经遇到过一个情况,病人有室性早搏,信号幅度忽大忽小。AGC一直在调整,导致正常心跳反而被漏检了。后来我加了一个「信号稳定性检测」模块,只有连续3个心跳的幅度变化在20%以内,才允许AGC调整。这个问题就解决了。
4.4 感知电路的整体架构
把上面这些串起来,一个完整的感知通路是这样的:
电极 → 前置放大(50倍) → 高通滤波(1 Hz) → 低通滤波(80 Hz) → 可编程增益放大(20~60 dB) → 比较器(带迟滞) → 数字信号 → MCU
这里面每一步都有坑,但最关键的还是两个字:匹配。放大器的噪声要和信号匹配,滤波器的带宽要和心内信号匹配,AGC的响应速度要和心率变化匹配。匹配做好了,感知电路就稳了。
嗯,今天就聊到这儿。下一章咱们讲起搏时序,那可是决定起搏器「什么时候该干活」的核心逻辑,到时候见。