多路巡检的前置 RC 与串扰辨伪实战:CH4 报 19.7℃、CH5 报 −7.5℃,两颗探头都是好的——不是串扰,是采样点早了两微秒
上一篇《8 路 NTC 巡检的时序预算实战》文末留的预告是:通道间串扰与 MUX 前置滤波的取舍——引脚间 3~5pF 的容性耦合、高阻通道”偷看”邻居、输入端到底该不该加 RC、共模注入怎么用差分消掉。这篇一并答完。
结论先说,因为三条都反直觉:
- “3~5pF 串扰”在这套链路上是假嫌疑人。它的峰值确实吓人——0.633V 的跳变能耦合出 22.9mV,折 0.63 度——但它是亚微秒级瞬态,泄放时间常数只有 537ns。判据不是峰值,是采样时刻的残差:2.08µs 后剩 0.47mV(0.013 度),10µs 后连 12bit 都看不见。
- 加小电容反而会放大串扰:1nF 把峰值压到 1/13,同时把 τ 拉长 13 倍,两者交点算出来是 1.49µs。比它短的间隔加电容有益,比它长的有害。这条标度律(峰值 ∝ 1/N,τ ∝ N,残差对 N 不单调)比”该不该加电容”这个问法本身更值得记住。
- RC 的拐点不由你那颗电阻决定,由探头决定:1k+220nF 在 −40℃ 是 66.5Hz,到 125℃ 变成 493Hz,漂 7.4 倍——因为 R_th 也在回路里,而且它的变化范围是 28 倍。
- 加电容之后,采样点必须跟着挪。本篇现场那台柜子,1k+100nF 把 τ 抬到 759µs,固件还在切换后 2.08µs 采样——只走了 0.003τ,残差 99.73%,每一路读的都是上一路的值。于是 CH4 显示 19.7℃、CH5 显示 −7.5℃,低温告警”搬了个家”,而两颗探头都是好的。
工具照例全离线:drafts/_tools/rc_filter_xtalk_calc.py,17 个模式,53 项自检断言,文中每个数字都能复算。链路口径与《NTC 采样链路故障》、《BMS 温度门限参数表》、《探头贴装质量出厂验收》、《8 路 NTC 巡检的时序预算》严格一致:B3950 / R25=10k / NTC 在下 / 10k 上拉 3.3V / 12bit 满量程 4095 / 1 LSB=0.806mV;C_node=80pF(MUX 输出 30 + 走线 20 + 引脚 10 + 余量 20)、C_sh=6pF、R_on=120Ω(74HC4051@3.3V)、相邻输入脚耦合 C_pp=3pF。
一、现场:低温告警”搬了个家”
去年十一月,一台 16S 200Ah 离网储能柜。8 路 NTC:CH0~CH3 和 CH5~CH6 贴在电芯上,CH4 是柜外环境,CH7 贴在功率电感上。经一片 74HC4051 进 STM32 的 12bit ADC,正序巡检,每路一个 125ms 的 slot。
上一个冬天这台柜子报过干扰:逆变器一上载,好几路温度就开始跳,跳动幅度 2~3 度。当时的处理是给全部 8 路输入端加了 R=1k、C=100nF 的 RC,跳动当场消失,验收通过。
今年十一月,运维发来一张截图:
| 通道 | 位置 | 读数 |
|---|---|---|
| CH3 | 电芯 | 26.3℃ |
| CH4 | 柜外环境 | 19.7℃ |
| CH5 | 电芯 | −7.5℃ |
| CH6 | 电芯 | 21.2℃ |
柜外零下七八度是正常的,但 CH4 报 19.7℃ 就离谱;更离谱的是 CH5——一块正在放电的电芯,显示 −7.5℃,触发了低温禁充。运维已经把 CH5 的探头换过两次、线换过一根、板子换过一块,告警一直挂在 CH5 上。
先看这张表的一个细节:CH4 的读数 19.7 ≈ CH3 的真值(19.8);CH5 的读数 −7.5 ≈ CH4 的真值(−7.6)。读数整体往后挪了一格。
这就是本篇要讲的那种病。它跟上篇那个”CH5 固定偏低 0.3 度”是同一个 τ 的两个不同投影:上篇的 τ 是 527ns,等 2.08µs(4τ),残差 0.32 度,看起来像”偏置”;这次 τ 变成 759µs(差 1440 倍),等待还是 2.08µs(0.003τ),残差 99.73%,看起来像”错位”。同一个公式,两种症状,只看等待时间落在 τ 的哪一侧。
二、先把三个嫌疑人分开:建立、串扰、共模
现场一遇到”多路之间互相影响”,通常三个词一起上来:串扰、干扰、共模。它们的物理机制、判据、治法完全不同,混着查就是一周一周地换板子。
| 现象 | 物理机制 | 量级 | 时间尺度 | 特征指纹 | 治法 |
|---|---|---|---|---|---|
| 前驱记忆(建立不足) | 上一通道留在节点上的电荷没泄放完 | 0~100% 的前驱值 | τ=(R_th+R_s+R_on)(C_node+C_f) | 读数往后挪一格,跟采样顺序绑定 | 把采样点挪到 slot 尾部 |
| 引脚电容串扰 | 相邻输入脚 C_pp 的电荷分配 | 峰值 ΔV·C_pp/C_tot | τ_x=(R_th+R_s)(C_pp+C_node+C_f) | 只在微秒级间隔里可见 | 拉开采样时刻,别指望用小电容救 |
| dv/dt 位移电流 | 开关节点经 pF 级电容注入 mA 级尖峰 | 0.1~2.5V 瞬时 | 尖峰宽度 20ns + τ 衰减 | 只在功率器件动作瞬间出现 | 布局隔离 + 时间隔离 |
| 共模抬升 | 探头地与板地之间的电位差 | 0.1V 起就顶轨 | 直流/工频 | 整柜同向偏,或某一路顶死满量程 | 单端接地、差分、限流 |
| 工频相干干扰 | 50Hz 在采样时刻的相位 | 取决于拾取 | 20ms 周期 | 读数慢摆(拍频) | 整周期多点平均 |
分清这张表,后面每一节只回答一个问题:这个嫌疑人,在本案的证据链上成立吗?
先说串扰,因为它是被冤枉得最久的那个。
三、串扰的判据是”采样时刻的残差”,不是峰值
相邻两个输入脚之间的耦合电容,实测口径 3pF(封装 1~2pF + PCB 并行走线 3cm 约 1pF)。当 CH(n) 的节点从一个值跳到另一个值,CH(n+1) 的节点被电荷分配抬起来:
ΔV_peak = ΔV · C_pp / (C_pp + C_node + C_f) ← 峰值只由电容比决定,与电阻无关
ΔV(t) = ΔV_peak · exp(−t / τ_x) ← 泄放由受扰节点自己的源阻抗决定
τ_x = (R_th + R_s) · (C_pp + C_node + C_f)
拿本案的数:CH3 在 12℃ 附近(2133.7mV),CH4 在 −8℃ 附近(2767.6mV),相邻两路的电压差 633mV。代入:
ΔV_peak = 0.633 × 3 / 83 = 22.9mV
τ_x = 6.47k × 83p = 537ns
22.9mV 在 12℃ 处折 0.63 度。看到这个数,很容易下结论”串扰很大”。但它是 537ns 的瞬态,而你什么时候采样?
| 距上次开关动作 | 残差 | 折温度 |
|---|---|---|
| 100ns | 18.99mV | 0.518℃ |
| 1µs | 3.55mV | 0.097℃ |
| 2.08µs | 0.474mV | 0.013℃ |
| 10µs | <0.001mV | ≈0℃ |
判据是 0.5 LSB = 0.403mV(0.011 度)。残差超过判据的时间窗只有 2.17µs。 也就是说,只要你的通道间隔大于 2.2µs,3pF 串扰就不该出现在嫌疑名单里。
这条结论可以写成一个可抄的判据:
串扰窗口 Δt_w = τ_x · ln(ΔV_peak / 0.5LSB)
要求:通道间隔 ≥ 3·Δt_w(工程余量)
本案 3×2.17µs = 6.5µs,而实际间隔 125ms——差 19000 倍。
那”3~5pF 串扰”这套经验是从哪来的?两个真实场景:
- µs 级通道间隔的高速多路采集。8 路轮流进同一个 ADC,每路 0.5µs,相邻通道的间隔就是 0.5µs——正好落在 2.17µs 的窗口里面,残差 0.1 度的量级;
- 源阻抗极高的节点。热电堆、pH 电极、光电二极管、以及”探头断线后真正悬空”的节点。R_th 上到 10MΩ,τ_x = 10M × 83p = 830µs,窗口变成 3.3ms,那时串扰才开始咬人。NTC 分压的 R_th 最大 9.76k,离这个数差三个数量级。
所以:串扰不是本案的凶手,但它是”高阻节点 + 高速扫描”那条路上的真凶。 判断自己属于哪种,只看两个数:R_th 和通道间隔。
四、加电容是压串扰还是放大串扰:交点 1.49µs
既然串扰是电荷分配,加 C_f 会把分压比压小——这听起来是好事。但它同时把泄放变慢,因为 τ_x 里也有 C_f:
峰值 ∝ 1/N,τ ∝ N(N = C_tot / C_tot_0)
残差(t) ∝ (1/N) · exp(−t·N/τ_0)
对 t 求导就能看出残差对 N 不是单调的:先按 1/N 下降,越过某个 t 之后按 exp(−tN) 更慢地衰减,反而比不加电容大。
| Δt | 无 RC | 100Ω+1nF | 1k+220nF |
|---|---|---|---|
| 100ns | 18.99mV | 1.73mV | 0.0086mV |
| 1µs | 3.55mV | 1.52mV | 0.0086mV |
| 2.08µs | 0.474mV | 1.31mV | 0.0086mV |
| 10µs | ~0 | 0.430mV | 0.0086mV |
| 100µs | ~0 | ~0 | 0.0081mV |
| 1ms | ~0 | ~0 | 0.0047mV |
2.08µs 这一行是最难看的:加了 1nF 之后,残差从 0.474mV 涨到 1.31mV,是原来的 2.8 倍。 交点算出来 Δt = 1.49µs(峰值降到 1/13、τ 拉长 13 倍,对数相消得到 ln13/(1/537ns − 1/7.11µs))。
这张表要读出的不是”加电容不好”,而是三件事:
- 1nF 这个量级最尴尬。它小到压不住峰值(只压 13 倍),又大到把 τ 拉长 13 倍,正好落在”两个坏处都吃到”的区间。要么别加,要么直接上到百 nF 量级;
- 220nF 之后,串扰在整个时间轴上都不存在了。峰值 8.6µV,比 0.5LSB 低 47 倍;2ms 处 0.0026mV,比判据低 155 倍。这时候”串扰”这个词可以从评审表里删掉;
- 残差只在”毫秒级采样点”这个用法下才归零。这直接把下一节的问题顶出来了——你的采样点到底在第几微秒?
顺带说一条本节最容易被忽略的推论:串扰和建立是同一个 τ 的两个投影。你没法”只压串扰不影响建立”,因为它们是同一个 RC 的峰值和尾巴。所以任何”加个电容滤一下”的方案,都必须同时回答”采样点往后挪多少”。
五、RC 的拐点不由你那颗电阻决定,由探头决定
这是本篇最实用的一条,也是最容易被 datasheet 思维带偏的一条。
教科书上的 RC 低通,fc = 1/(2πRC),R 就是那颗电阻。但 NTC 分压的输出阻抗 R_th 是串在回路里的,所以真实的拐点是:
fc = 1 / (2π · (R_th + R_s + R_on) · (C_node + C_f))
R_th 随温度从 0.346k(125℃)变到 9.757k(−40℃),变化 28 倍。于是同样一颗 1k+220nF 的 RC,拐点是这样跑的:
| T℃ | R_th | fc | τ |
|---|---|---|---|
| −40 | 9.757k | 66.5Hz | 2.39ms |
| −20 | 9.133k | 70.5Hz | 2.26ms |
| 0 | 7.708k | 81.9Hz | 1.94ms |
| 12 | 6.466k | 95.3Hz | 1.67ms |
| 25 | 5.000k | 118.2Hz | 1.35ms |
| 45 | 3.030k | 174.2Hz | 913µs |
| 85 | 0.980k | 344.3Hz | 462µs |
| 125 | 0.346k | 493.2Hz | 323µs |
66.5Hz 到 493Hz,7.4 倍。 三件事跟着这个数走:
- 抗干扰能力在高温端最弱。你在 −40℃ 设计的 66Hz 滤波器,到 85℃ 只剩 344Hz。如果干扰源是开关频率(十几 kHz),衰减从 −47dB 掉到 −33dB,差 14dB;
- 建立时间在低温端最长。τ 从 323µs 涨到 2.39ms,7.4 倍。所以”冬天出问题”这句话在这条链路上有两个独立的原因:电压差大(残差大)和 τ 长(衰减慢),两个都往坏的方向走;
- 想稳住拐点,只能让 R_s 远大于 R_th。R_s=10k 时 R_th 的变化只影响 10%,但 10k 串在输入上会带来别的问题(下一节讲漏电流),所以实际取值卡在 1k 这个折中点。
这条也解释了为什么”照着 datasheet 算 fc”会算错:datasheet 给你的电阻是 R_s,而真正决定拐点的是 R_s 加上传感器的源阻抗。传感器源阻抗随被测物理量变化这件事,在 NTC 上放大 28 倍,在 Pt100/Pt1000 上不到 1.5 倍,在热电偶上可以忽略——所以同一条公式,不同传感器的敏感度差一个数量级。
六、建立时间的账:一个 τ 同时管三件事
把上面两节的结论合起来,你会发现”加 RC”这个动作同时改三件事,而且都由同一个 τ 决定:
| 关心的量 | 表达式 | 加 C_f 之后 |
|---|---|---|
| 前驱残差(记忆) | ΔV·exp(−t/τ) | τ 变大,残差变大 |
| 串扰残差 | ΔV·(C_pp/C_tot)·exp(−t/τ_x) | 峰值变小、尾巴变长 |
| 单通道建立到 0.5LSB | (n+1)·ln2·τ | 线性变长 |
| ADC 采样保持跌落 | C_sh/(C_node+C_f) | 变小(这是唯一变好的) |
最后一行值得单独说。上一篇算过,C_node=80pF、C_sh=6pF 时采样开关一闭合,节点电压会跌落 6.98%(230mV,折 6.28 度),因为 C_sh 要从节点抢电荷。加了 220nF 之后:
C_sh/(C_node+C_f) = 6p / 220.08n = 2.7e-5
跌落从 230mV 变成 90µV。 这是大电容送的礼——它把节点变成了一个”硬”源,ADC 那一口电荷只是它的 0.003%。上一篇里”采样窗口要按 5·R_src·(C_node+C_sh) 算到 3.26µs”这个约束,在 220nF 面前直接失效:跌落本身只有 90µV,窗口再短,剩下的残差也在 µV 级,压不到 0.5LSB 以下才怪。这是加 RC 唯一”只赚不亏”的一项。
所以加 RC 不是纯亏。它用时间换了两样东西:抗高频干扰,和采样保持的硬度。要算的是这笔账划不划得来。
七、采样点该放在 slot 的哪里
上一篇的结论是”加 MUX 付出的不是精度是时间”。这一篇要把这句话改得更准:
时间本来就是富余的,前提是你别在切换后立刻采样。
槽是 125ms,最坏情况的建立(−40℃、220nF)也只要 21.5ms——五倍多的余量。真正的约束不是”slot 不够长”,而是”固件把采样点放在了切换后 2µs”:那个位置离要求差了 10000 倍。
把等待时间和允许的电容算成一张表(12℃、R_s=1k、9τ 判据):
| 等待预算 | C_f 上限 | 对应 fc | 对应 τ |
|---|---|---|---|
| 1ms | 14.6nF | 1.43kHz | 111µs |
| 2ms | 29.2nF | 716Hz | 222µs |
| 5ms | 73.2nF | 286Hz | 556µs |
| 10ms | 146.4nF | 143Hz | 1.11ms |
| 20ms | 292.9nF | 71.6Hz | 2.22ms |
| 50ms | 732.3nF | 28.6Hz | 5.56ms |
| 100ms | 1.46µF | 14.3Hz | 11.1ms |
125ms 的 slot 里,你付得起 1.4µF 的滤波电容。“滤波带宽和建立时间不可兼得”这句话,在”切换后 2µs 采样”这个前提之外是不成立的。
本案推荐的采样序列(可直接抄):
slot 开始 t=0 : 切 MUX 到 CH(n)
t=0 → 25ms : 等(覆盖 −40℃ 的 9τ=21.5ms,留 16%)
t=25ms → 43ms : 采 10 点,间隔 2ms
t=43ms : 取中位数 → 打时间戳 → 入队
t=125ms : 切下一路
留给建立 25ms、留给平均 18ms(首末采样时刻跨度),合计 43ms,占 slot 的 34%。剩下的 80ms 是白送的余量,够你把 slot 缩到 60ms、或者把巡检周期压到 0.5s。
这里有个容易看错的地方:10 点、间隔 2ms,首末采样只跨 18ms,但相位跨度是 10×2ms=20ms。整周期抵消的条件是后者(N·Ts 为工频周期的整数倍),不是前者。按 18ms 去算会得出”没有整周期”的错误结论。
两个边界必须说清楚:
- 这套只对慢变量成立。温度时间常数是分钟级,晚 43ms 完全无所谓。电流不行——上一篇说过 4 路电流若靠 MUX 巡检,200A 阶跃落在窗口中间就是”前两路 0A、后两路 200A”,119 篇那条 15% 的均流判据一次投切就误报。电流必须同步采样,不适用本节;
- 同一轮 8 路的采样时刻相差 125ms。做122 篇的 limiting source 时,需要”同一时刻的全套温度”——125ms 的跨度对温度可以接受,但必须每轮打时间戳,别让上层以为这些数是一起采的。
八、数字滤波能救什么,救不了什么
既然 slot 里有 80ms 富余,第二个念头就是”多采几次取平均”。这件事对,但只对一半。
能救的:随机噪声。 10 点平均把 σ 压到 0.316 倍,20 点压到 0.224 倍。2 度的抖动 → 0.63 度 / 0.45 度。
能严格消掉的:整周期的工频。 这一点值得算清楚,因为它是”数学上等于零”,不是”抑制了多少 dB”。N 点等间隔平均对频率 f 的传输比是:
|H(f)| = |sin(π·f·N·Ts)| / (N·|sin(π·f·Ts)|)
只要 f·N·Ts 是整数,分子就是零。取 N=10、Ts=2ms,N·Ts=20ms 正好一个工频周期:
| N | Ts | σ 改善 | 50Hz | 49.5Hz | 50.05Hz | 150Hz |
|---|---|---|---|---|---|---|
| 5 | 4.00ms | 0.447 | 完全抵消 | −39.3dB | −59.4dB | 完全抵消 |
| 10 | 2.00ms | 0.316 | 完全抵消 | −39.8dB | −59.9dB | 完全抵消 |
| 20 | 1.00ms | 0.224 | 完全抵消 | −39.9dB | −60.0dB | 完全抵消 |
三件事要读出来:
- 50Hz 和 150Hz(三次谐波)是真的零,不是 −40dB。这一点在离网储能柜里很有用:逆变器带非线性负载时三次谐波很脏,而它正好落在零点上;
- 49.5Hz 只有 −39.8dB,而且加点数没用(5/10/20 点都是 −39.8dB)。因为抑制深度由窗长决定(20ms 的频率分辨力是 50Hz),点数只改善噪声。想让 49.5Hz 也掉下去,得把窗拉长到 200ms——slot 就没了;
- 50.05Hz 能到 −60dB,因为偏离越小、分子越接近零。所以真正决定效果的是电网频率精度:孤岛运行的逆变器频率可能偏到 49.5~50.5Hz,那这段的抑制就只有 −40dB 量级,2V 的共模拾取还剩 20mV。
还有一条反过来要注意:窗以外的相位漂移会变成慢摆。如果一轮不是整 20ms(例如实测 1.008s),50Hz 的采样相位每轮滑 0.4 个周期,读数就会以 0.4/1.008 ≈ 0.4Hz 的节拍摆动——看起来像”温度自己在晃”,其实是你和电网在打拍子。这种摆动幅度不衰减,只能靠整周期窗消掉。
救不了的:开关纹波。 见下一节,这是个结构性问题。
顺带回答”均值还是中位数”。10 点下均值 0.316σ、中位数 0.396σ,均值更优;但中位数有一个均值没有的性质:一个 10K 的尖峰进来,均值被拉高 1.0K,中位数纹丝不动。而 MUX 切换瞬间的毛刺恰好就是这种单点异常。所以本期推荐中位数——用 25% 的效率换 100% 的鲁棒性,值。
九、开关频率混叠:唯一必须靠模拟 RC 的场合
这一节是整篇里唯一”数字方法彻底失效”的地方,也是输入端那颗电容真正的存在理由。
每通道 1s 一轮、slot 内 2ms 一点的采样率是 500Hz。逆变器的开关频率是 8k / 10k / 16k / 20k / 25k / 40k——全部是 1kHz 的整数倍,而 500Hz 能整除每一个 1kHz 整数倍:
| f_sw | 采样率 | 混叠落点 | 结论 |
|---|---|---|---|
| 8kHz | 500Hz | 0Hz | 落到 DC,平均无效 |
| 10kHz | 500Hz | 0Hz | 落到 DC |
| 16kHz | 500Hz | 0Hz | 落到 DC |
| 20kHz | 500Hz | 0Hz | 落到 DC |
| 25kHz | 500Hz | 0Hz | 落到 DC |
| 40kHz | 500Hz | 0Hz | 落到 DC |
按 8Hz(每 slot 采一次)算也一样:1000/8=125 是整数,所以每一个 1kHz 整数倍都精确落在 DC 上。这不是巧合,是”采样率整除开关频率”的必然结果,而工程上开关频率几乎总是整 kHz。
后果很具体:开关纹波混到 DC 之后,它变成一个固定偏置,你采 10 次、100 次、取平均取中位数,读到的都是同一个偏置。数字域无解。
唯一出路是在混叠发生之前把它压下去。按 50mVpp 的输入纹波、要求残留 ≤ 0.5LSB 算:
| 开关频率 | 输入纹波 | 需要衰减 | 要求 fc |
|---|---|---|---|
| 16kHz | 50mVpp | 41.9dB | ≤128.9Hz |
| 20kHz | 50mVpp | 41.9dB | ≤161.2Hz |
| 16kHz | 200mVpp | 53.9dB | ≤32.2Hz |
对照第四节那张方案表:
| 方案 | fc@12℃ | τ | 9τ | 1MHz 衰减 | 16kHz 衰减 |
|---|---|---|---|---|---|
| 无 RC(只有 C_node) | 302kHz | 527ns | 4.75µs | −10dB | 0.0dB |
| 100Ω+1nF | 22.0kHz | 7.22µs | 65.1µs | −33dB | 0.0dB |
| 1k+100nF | 209.6Hz | 759µs | 6.84ms | −74dB | −37.7dB |
| 1k+220nF | 95.3Hz | 1.67ms | 15.0ms | −80dB | −44.5dB |
1k+100nF 差 4dB,1k+220nF 够了。 这就是为什么本案最终选 220nF 而不是 100nF——不是为了”更大更稳”,是因为 16kHz 那条线卡在 41.9dB 上。
还有一条更”工程”的解法值得提:让采样率与开关频率异步。slot 里加 ±3% 的随机抖动(2ms → 1.94~2.06ms),混叠分量就从 DC 摊到几百 Hz 的带上,配合后面的平均能再压一档。这条不改变硬件,只改固件,代价是工频整周期抵消失效了——两条不能同时用,得按现场主要干扰源选。这一条是量级估算,本脚本没有建模,上线前用实测确认。
十、共模、差分与地电位差
上一篇预告里说”共模注入如何用差分采样消掉”。答案是:能消,但只消得掉共模那一半。
先把两种东西分开:
| 类型 | 来源 | 通道比对里看得见吗 | 差分能消吗 |
|---|---|---|---|
| 共模 | 整束线缆被同一个 dv/dt 抬升;探头地与板地之间的电位差 | 看不见(每路一样) | 能 |
| 差模 | 相邻通道的引脚电容耦合;前驱记忆 | 看得见(只有某几路偏) | 不能 |
“加差分就能抗干扰”这句话半对半错:差分会把共模那部分严格消掉,对差模零帮助。而本案的错位是差模的——它是”上一路的值”,差分放大之后还是”上一路的值”。
共模抑制要多少?按残留 ≤0.5LSB 算:
| 共模幅度 | 需要 CMRR | 80dB 时残留 | 50dB 时残留 |
|---|---|---|---|
| 0.5V | 61.9dB | 0.050mV | 1.58mV |
| 1.0V | 67.9dB | 0.100mV | 3.16mV |
| 2.0V | 73.9dB | 0.200mV | 6.32mV |
| 5.0V | 81.9dB | 0.500mV | 15.8mV |
2V 共模需要 74dB。 这里有个选型坑:STM32 的 ADC 是单端结构,”差分”是伪差分(两个通道相减),CMRR 只有 40~50dB 量级。50dB 对应 2V 共模下残留 6.3mV = 0.17 度——不够,但也不致死;真正致死的是下面这件事。
十一、钳位二极管导通那一下:冷端只剩 80mV 余量
地电位差是这套系统里最阴的一个失效源,因为它的门槛随温度变化,而低温端几乎没有余量。
探头在柜外,线长 3m,探头的地与板的地之间只要有一个电位差 ΔVg(来自 200A 电池回路的 IR 降、来自屏蔽层两端接地的环流、来自不同接地点),整个分压就被整体抬起来。抬多少会出事?
| T℃ | V_out | 顶满量程所需 ΔVg | 钳位二极管导通所需 ΔVg |
|---|---|---|---|
| −40 | 3219.9mV | 0.080V | 0.780V |
| −20 | 3014.0mV | 0.286V | 0.986V |
| 0 | 2543.5mV | 0.757V | 1.457V |
| 12 | 2133.7mV | 1.166V | 1.866V |
| 25 | 1650.0mV | 1.650V | 2.350V |
| 85 | 323.5mV | 2.977V | 3.677V |
| 125 | 114.3mV | 3.186V | 3.886V |
−40℃ 时,80mV 的地电位差就能把这一路顶到满量程。 冷热不对称 40 倍,因为 NTC 冷端的 V_out 已经在 3.22V,离 3.3V 只剩 80mV。
后果分两级:
- 第一级(顶满量程,raw=4095):ADC 饱和。123 篇的断线判据是 raw>4050,于是这一路被判成”探头断线”。运维按断线去换探头,换三次都不好——因为病在接地;
- 第二级(真正导通):节点电位超过 VDD+0.7=4.0V 之后,ESD 二极管导通,电流灌进 VDD 轨。−8℃ 时 2.0V 的地电位差对应 0.092mA、3.0V 对应 0.211mA。单路不大,但 8 路一起灌就是 1.7mA 往 3.3V 轨里打,而这个轨通常只有 LDO 供、没有任何泄放路径;更麻烦的是导通瞬间的电荷注入进衬底,会把相邻通道一起带偏——这时候你才真的看到了”串扰”,而且它的强度跟你查的 C_pp 一点关系都没有。
这就是为什么第十节那张表里,”整柜同向偏”和”某一路顶死”要分开查:顶死是地电位差,同向偏是共模,两者都不该去查探头。
一个 30 秒的判别实验:用万用表直流档量探头的地(柜外的屏蔽层/探头负端)与板子的 GND 之间的电压。 大于 50mV 就已经在吃余量了,大于 300mV 冬天必炸。这个数在夏天量往往只有几毫伏,因为电池回路电流小——所以”夏天正常”不能当作没问题。
屏蔽层的接法直接决定 ΔVg 有多大:单端接地,接在采样板这一端。 两端接地会形成一个环路,柜内 200A 母排的漏磁通穿过这个环路,50Hz 感应电压按 V=2πfBA 算:1.5m²、10µT 时是 4.7mV(0.13 度),3m² 时 9.4mV。这个量级本身不致命,但它会把 ΔVg 从几毫伏推到几十毫伏——在 −40℃ 只剩 80mV 余量的前提下,这就是压死骆驼的那根稻草。
十二、元件选型与布局:五条会踩的
到这一节,方案已经定了:R_s=1k、C_f=220nF、采样点在切换后 25ms、10 点中位数、窗 20ms。落地时还有五个坑:
1. R_s 的上限由 ADC 漏电流定,不是由建立时间定。 ADC 输入漏电流按 1µA 上限算:
| R_s | 漏电流 10nA 时 | 漏电流 1µA 时 |
|---|---|---|
| 100Ω | 0.00 LSB | 0.12 LSB |
| 1kΩ | 0.01 LSB | 1.24 LSB |
| 10kΩ | 0.12 LSB | 12.41 LSB |
10k 串在输入上,1µA 漏电流就是 12.41 LSB = 10mV = 0.27 度。所以 R_s 卡在 1k:既能跟 R_th 形成可用的滤波拐点,漏电流误差又压在 1.2 LSB 以内。这就是为什么选 1k 而不是 10k。
2. C_f 的介质。 X7R 在 3.3V 直流偏压下容值掉 10~30%,拐点会往上跑,正好抵消你想压的余量。同样 220nF,50V 耐压那颗在 3.3V 偏压下的容值损失明显小于 16V 那颗(这就是为什么选耐压高的);要么选 50V 耐压,要么直接上 C0G(220nF 的 C0G 体积大、贵,一般不划算)。温度系数 ±15% 是第二重漂移,叠在第五节那 7.4 倍上。
3. 共用 RC 还是每路一套。 把 RC 放在 MUX 后面共用一套,看起来省 7 套元件,实际上把 C_f 直接并进了 C_node:8 路的记忆效应全部共享,而且这个电容会在切换瞬间被前一路充到 V(n-1),再通过 R_on 往新节点上灌——串扰从”相邻 3pF”变成”全局 220nF”。这条绝对不能省。
4. 电容的充电电流会在地线上打台阶。 220nF 在 633mV 跳变下搬运 139nC,如果 10µs 内完成就是 13.9mA 的脉冲电流。走 30mΩ 的公共地线段,压降 0.42mV = 0.52 LSB。加电容反而新增了一条串扰路径——所以每路的 C_f 必须就近接到模拟地,且模拟地单点回星形点,不要跟 MUX 的数字地共用一段。
5. 大电容让”故障注入”变慢,但不影响判据。 断线时 C_f 由 10k 上拉充电,τ=10k×220n=2.2ms,比原来慢但仍是毫秒级;123 篇那套 raw 层判据的确认次数(连续 5 次、1Hz)完全不受影响。这一点要提前跟测试说清楚,否则会被当成”响应变慢”的缺陷。
十三、排障十步(按命中率排)
遇到”多路之间互相影响”,照这个顺序做,前三条能解决八成:
- 扰动上游通道,看下游读数是否跟着动。把上游的探头换成一个 10k 电阻(等效 25℃),看它下游那一路是否也跟着变成 25℃。跟着动 → 记忆效应,直接跳到第 3 条。这个实验 30 秒,判定性最强;
- 把采样点从切换后 2µs 挪到 10ms(同一个 slot 内,别的都不改),看是否全部恢复。恢复 → 确诊建立不足,收工;
- 算一遍 τ = (R_th+R_s+R_on)(C_node+C_f),再算 9.01τ。这两个数跟你的等待时间比一下,比值小于 1 就是病;
- 看是不是只在”相邻通道温差大”的季节/工况出现。夏天所有通道挤在 25~35℃ 时,错位后的值仍然”看起来合理”,所以只有冬天才暴露——这不是偶发故障,是季节性显影;
- 整柜同时同向偏 → 量地电位差,别查探头。探头地到板地 >50mV 就已经在吃余量;
- 某一路顶死满量程且换探头无效 → 也量地电位差。−40℃ 时门槛只有 80mV,夏天量不出来不代表冬天没有;
- 读数以 0.4~2Hz 慢摆 → 采样周期与 50Hz 的拍频。量一下实际轮询周期是不是整 20ms 的整数倍;不是就用第 8 节的整周期平均;
- 开关频率整倍数混叠 → 加模拟 RC,平均法无效。先确认 f_sw/采样率是不是整数,是的话数字域怎么做都没用;
- 想靠”加个 1nF”压串扰 → 先算交点。间隔小于 1.5µs 才有益,大于就是负优化;
- 怀疑共模 → 先看是不是每路一起偏。一起偏是共模(差分能救),某几路偏是差模(差分救不了)。
第 1 条为什么排第一:它是唯一能把”记忆”从”串扰/探头/板子”里一刀切开的实验。探头、MUX、走线的问题不会因为你扰动上游而改变下游;记忆效应一定会。
十四、设计评审表(可直接抄)
| 项目 | 判据 | 本例取值 | 备注 |
|---|---|---|---|
| 采样点位置 | ≥ 9.01τ(按最坏 R_th) | 切换后 25ms | −40℃ 需 21.5ms |
| C_f 上限 | 由 slot 预算反算 | 220nF | 125ms slot 可到 1.4µF |
| 滤波拐点 | fc ≤ f_sw/需要的衰减 | 95.3Hz@12℃ | 16kHz 衰减 −44.5dB |
| 拐点漂移 | 冷热比 ≤ 8 倍 | 66.5→493Hz(7.4 倍) | R_s 越大越稳 |
| R_s 上限 | I_leak·R_s ≤ 1.5 LSB | 1kΩ | 1µA 时 1.24 LSB |
| 串扰窗口 | Δt ≥ 3·τ_x·ln(峰值/0.5LSB) | 6.5µs | 实际 125ms,余量 19000 倍 |
| 采样保持跌落 | C_sh/(C_node+C_f) ≤ 1e-4 | 2.7e-5 | 大电容的赠礼 |
| 工频抑制 | 采样窗 = 整数个 20ms | 10 点 × 2ms | 50Hz/150Hz 严格为 0 |
| 估计器 | 抗单点异常 | 中位数 | 均值会被毛刺拉偏 1K |
| 共模抑制 | ≥ 74dB(2V 共模) | 单端不够,需差分 | 伪差分仅 40~50dB |
| 地电位差 | 冷端余量 ≥ 10 倍 | ≤8mV@−40℃ | 顶轨门槛仅 80mV |
| 屏蔽接地 | 单端,接采样板端 | 是 | 两端接地引入环流 |
| RC 位置 | 每通道一套,MUX 之前 | 是 | 共用会把串扰放大到全局 |
最后把本篇收成三句话:
第一,”串扰”在这套拓扑里几乎永远是假嫌疑人。 它是亚微秒瞬态,而你的采样间隔是毫秒到百毫秒;判据要算采样时刻的残差,不是峰值。别再去换 MUX、换低 R_on、加屏蔽罩。
第二,”滤波与建立不可兼得”是个假两难。 它只在”切换后立刻采样”这个前提下成立。把采样点挪到 slot 尾部,你就能同时要 95Hz 的抗扰和 12bit 的精度——代价只是把采样时刻推迟 25ms,而温度这个量根本不在乎 25ms。
第三,真正会咬人的是接地。 冷端 80mV 的余量、8 路共用一个模拟地、屏蔽层两端接地——这三个任何一个都能把”探头断线”和”串扰”同时伪造出来,而且都在冬天显影。先量地,再查探头。
工具:drafts/_tools/rc_filter_xtalk_calc.py(17 个模式,53 项自检断言,纯标准库、全离线)。文中数据口径:B3950/R25 10k/NTC 在下/10k 上拉 3.3V/12bit 满量程 4095/1LSB=0.806mV;C_node=80pF、C_sh=6pF、R_on=120Ω、C_pp=3pF;MUX 按 74HC4051 计。X7R 容值随直流偏压与温度的漂移按典型值 10~30% / ±15% 取,具体请按自己器件的 datasheet 替换。文中现场案例是按脚本口径的复算,不是原始录波。
另:9 月 26 日那篇《ESD 与浪涌防护实战》里”12.5kV 应为 12.5V”的笔误还没改,等排期。站内至今仍缺《Flash 存储与参数管理》和《固件安全与逆向防护》两个主题,都在待写清单上。
下一篇写探头断线、地电位差、共模超范围:三种”顶满轨”的区分与现场取证——本篇第十一节只给了门槛(冷端 80mV)和一句”先量地”,没给取证流程:三种成因在 raw 曲线上的形状、在巡检顺序上的指纹、以及一个不用示波器的现场三步法。这是123 篇那套断线判据的直接下游,也是这台柜子明年的第一件事。