4. 模拟前端(AFE)配置与增益调试:LED驱动电流设置,跨阻放大器增益调节,环境光抑制策略
好,咱们进入血氧仪最核心的硬件环节——模拟前端AFE的调试。说实话,这部分搞不定,后面算法再牛也白搭。我见过太多团队,算法工程师天天抱怨信号太差,结果一查,AFE配置压根没调对。
AFE调试说白了就三件事:把光发出去(LED驱动)、把光收回来转成电压(跨阻放大器)、把干扰滤掉(环境光抑制)。咱们一个一个来拆。
4.1 LED驱动电流设置——不是越亮越好
很多人上来就把LED电流开到最大,觉得信号强就好。嗯,这是个坑。我早期做的一款指夹式血氧仪,红光LED开到20mA,结果手指一放上去,ADC直接饱和,波形平得像一条直线。
LED驱动电流的选择,其实是个平衡艺术:
- 电流太小:光信号弱,穿透手指后光电二极管几乎没反应,信噪比极差
- 电流太大:一是发热,LED温度漂移会影响波长;二是容易让接收端饱和
- 还有个隐藏问题:大电流会缩短电池寿命,尤其是可穿戴设备
我个人习惯的调试方法是:
- 先把电流设到典型值(红光一般5-10mA,红外8-15mA)
- 用示波器看跨阻放大器输出端的波形
- 调整电流,让PPG波形的峰峰值在ADC满量程的30%-70%之间
- 如果波形太小,优先调增益,而不是无脑加电流
关键经验:红光和红外光的驱动电流通常不一样。因为不同波长在组织中的吸收特性不同,红外穿透性更好,所以红外LED的电流可以比红光小一些。我一般先让两者在接收端的信号幅度接近,这样后续算法处理起来更公平。
实际项目中,LED驱动常用的是恒流源方式。以AFE4404为例,它的LED驱动寄存器是这样配置的:
// AFE4404 LED驱动电流配置示例
// LED电流 = (LED_CODE / 256) * 50mA
// 红光LED设到8mA
AFE4404_REG_LED1_DRV = (uint8_t)(8.0 / 50.0 * 256); // 约41
// 红外LED设到10mA
AFE4404_REG_LED2_DRV = (uint8_t)(10.0 / 50.0 * 256); // 约51
小技巧:调试时别只盯着静态值。把手指拿开再放回去,观察波形恢复速度。如果恢复很慢,说明LED电流可能偏大,组织被加热了,血流量在变化。
4.2 跨阻放大器增益调节——信号放大的艺术
跨阻放大器(TIA)是AFE的咽喉。光电二极管产生的电流只有微安级,必须通过TIA转成电压才能被ADC采集。增益怎么选?我见过有人直接套用参考设计,结果换了手指厚度就不行了。
TIA的增益由反馈电阻Rf决定:Vout = Ipd × Rf。Rf越大,增益越高,但噪声也越大。这是个典型的信噪比取舍问题。
我在项目中总结了一套增益调节的步骤:
- 第一步:估算信号范围。正常手指透射光产生的光电流大约在10nA到1μA之间,具体取决于皮肤厚度和血氧饱和度
- 第二步:确定目标电压。ADC的满量程是参考电压Vref,一般留20%裕量,目标峰值电压设为0.8×Vref
- 第三步:计算Rf。Rf = Vtarget / Ipd_max。比如Vref=3V,目标2.4V,最大光电流1μA,那Rf=2.4MΩ
注意:Rf不是越大越好。反馈电阻大了,带宽会下降。我踩过这个坑——为了追求高增益用了10MΩ电阻,结果PPG波形的高频细节全没了,脉率计算偏差很大。一般血氧仪的TIA带宽至少要能通过10Hz的信号,算下来Rf最好不要超过5MΩ。
实际芯片里,增益通常是可编程的。比如MAX30102的TIA增益有7个档位:
// MAX30102 TIA增益配置
// 0x0E: 7.81pF, 增益50kΩ
// 0x0F: 7.81pF, 增益100kΩ
// 0x10: 7.81pF, 增益200kΩ
// 0x11: 7.81pF, 增益400kΩ
// 0x12: 7.81pF, 增益800kΩ
// 0x13: 7.81pF, 增益1600kΩ
// 0x14: 7.81pF, 增益3200kΩ
// 我一般从200kΩ开始试
max30102_write_reg(0x0E, 0x10); // 设置增益200kΩ
调试建议:先用手边最厚的测试者(比如大拇指)来调增益。如果最厚的手指都能得到不错的信号,那薄手指可以通过降低LED电流来适配,而不是反过来。
4.3 环境光抑制策略——白天黑夜都要准
环境光干扰是血氧仪最头疼的问题之一。你想想看,用户在户外阳光下测血氧,和在被窝里测,环境光强度差了几百倍。如果不做抑制,ADC早饱和了。
环境光干扰主要有两种:
- 直流分量:太阳光、室内照明等持续光源,会让光电二极管产生较大的直流偏置
- 交流分量:50Hz/60Hz的荧光灯频闪,会叠加到PPG信号上
常用的抑制策略有三种,我按效果排序:
| 策略 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| 采样时序法 | LED亮时采一次,灭时采一次,相减 | 实现简单,无额外硬件 | 对运动伪影敏感 |
| 模拟低通滤波 | 在TIA后加低通滤波器 | 抑制高频噪声效果好 | 会滤掉部分PPG信号 |
| 环境光消除环路 | 用DAC产生反向电流抵消环境光 | 效果最好,动态范围大 | 需要额外DAC,成本高 |
我最常用的是采样时序法,因为大多数AFE芯片都内置了这个功能。以AFE4404为例,它的时序是这样的:
// AFE4404 环境光抑制时序配置
// 一个完整的采样周期包含4个阶段:
// Stage 1: 红光LED亮,采样红光+环境光
// Stage 2: 所有LED灭,只采样环境光
// Stage 3: 红外LED亮,采样红外+环境光
// Stage 4: 所有LED灭,只采样环境光
// 实际信号 = (LED亮时采样值) - (LED灭时采样值)
// 这样就把环境光的直流分量去掉了
我曾经遇到过一个案例:某款手环在户外阳光下血氧值乱跳。查了半天,发现是环境光变化太快,采样时序跟不上。后来把采样率从100Hz提到200Hz,问题解决了。所以环境光抑制不只是硬件的事,时序配合也很关键。
对于50Hz/60Hz的工频干扰,我建议在软件层面再加一道陷波滤波器。硬件滤波虽然也能做,但电容电感会占体积,而且中心频率不好调。软件陷波就灵活多了:
// 50Hz IIR陷波滤波器示例(采样率200Hz)
// 二阶陷波,Q值30
float b0 = 0.9900f;
float b1 = -1.9601f;
float b2 = 0.9900f;
float a1 = -1.9601f;
float a2 = 0.9801f;
float notch_filter(float input) {
static float x1 = 0, x2 = 0, y1 = 0, y2 = 0;
float output = b0*input + b1*x1 + b2*x2 - a1*y1 - a2*y2;
x2 = x1; x1 = input;
y2 = y1; y1 = output;
return output;
}
实战经验:环境光抑制的调试,我建议在三个场景下验证:强光直射(户外正午)、弱光(暗室)、频闪光(荧光灯下)。每个场景跑5分钟,看波形稳定性。如果某个场景下波形出现周期性毛刺,那大概率是环境光抑制没做好。
4.4 三个参数的协同调试
LED电流、TIA增益、环境光抑制,这三个参数不是孤立的。它们互相影响:
- LED电流大了,环境光的影响相对变小,但容易饱和
- TIA增益高了,信号放大倍数大,但噪声和环境光也被放大了
- 环境光抑制做得好,就可以用更小的LED电流和更高的增益
我个人的调试顺序是:先定环境光抑制策略 → 再调TIA增益 → 最后微调LED电流。这个顺序能让你少走很多弯路。
最后提醒一句:所有参数调好后,一定要做温度测试。LED的发光效率随温度变化,TIA的增益也有温漂。我有一款产品在常温下测得好好的,拿到东北零下20度,血氧值直接偏了3%。后来加了温度补偿才搞定。
好了,AFE配置这块就讲到这里。下一章咱们聊ADC采样与数字滤波,到时候会用到今天调好的这些参数。记住一句话:AFE调好了,血氧仪就成功了一半。