8 路 NTC 巡检的时序预算实战:第 5 通道总偏低 0.3 度,换探头换板子都没用——把采样顺序倒过来,偏低的那一路跟着换了个位置

2026年10月23日 0 By admin

上一篇《导热硅脂的老化与泵出实战》文末我留了个预告:多通道 NTC 巡采的 MUX 时序与同步采样——电荷注入、采样保持窗口、通道间 skew、巡检 vs 同步采样的判据表,以及”第 5 通道总是偏低 0.3 度”这类现场病怎么定位。这篇全部答上。

先说结论,因为它反直觉:这个 0.3 度跟探头、跟 MUX、跟板子都没有关系,是固件里那个”切换通道后延时一下”的延时不够长。而”不够长”这件事,只能在它和前一个通道的电压差里看见——所以它表现成”某一个通道固定偏”,而不是噪声。

事情起于去年十二月的一台柜子。16S 200Ah 离网储能柜,6 个电芯测点 + 1 路柜内环境 + 1 路功率电感温度,共 8 路 NTC,经一片 74HC4051 进 STM32 的 12bit ADC。巡检正序 0→7,每通道一个 125ms 的 slot,切换后固件延时 2.08µs(500 次空循环,240MHz)再启动 ADC。

运维报的现象很干净:CH5 比其他电芯通道稳定低 0.3 度左右,白天负载高的时候更明显,夜里空载时基本看不出来。换过探头(换了三支)、换过板子(换了两块)、换过 NTC 的批次,0.3 度一动不动。

三条常规排查全部指向”没问题”:探头在恒温槽里 ±0.05K 内;把 CH5 的探头插到 CH3 的座子上,CH5 还是低;把 CH3 的探头插到 CH5 的座子上,CH5 还是低。偏差跟着通道走,不跟着探头走——这时候就该怀疑通道本身,而不是传感器。

但”通道本身”这四个字会把人带偏:MUX 的通道导通电阻、走线、焊点、分压电阻,一个个查下去能耗掉一周。真正的答案在时序上,而且有一个十秒钟就能做完的判决性实验——把扫描顺序倒过来。

结论先行,五条:

  • 多路 MUX 不进精度预算,只进时间预算:10k 分压下加一片 8:1 MUX,整条链的误差从 0.366K 变成 0.367K(+0.2%);它唯一会亏的是”建立没做完”的残差,而残差大小 = 前一通道电压差 × exp(−t/τ);
  • 这个残差是差模的,所以表现成”某一路固定偏”:电荷注入是共模的(每一路一样大),在通道比对里看不见;前驱残差只打在某一路身上,这才是”第 5 通道总偏”的元凶;
  • “等 3~5 个时间常数”这条经验只够 9~10bit:12bit 要 9.01τ,16bit 要 11.78τ(τ 数 = (位数+1)×ln2)。本例 4τ 恰好对应 0.32K,和现场那个 0.3 度严丝合缝;
  • 换更贵的 MUX 没用:R_on 从 470Ω 换到 4.5Ω,τ 只从 818ns 降到 781ns(5%),因为 R_th 主导。R_on 在直流上严格为 0(ADC 输入阻抗 MΩ 级,稳态电流 nA 级,I×R_on 是 µV 级)——钱花在 R_on 上,病在时间上;
  • 巡检对温度够用,对电流致命:温度一轮 1s 的 skew 只值 1.7mK,随便巡;但 4 路电流若也靠 MUX 巡检(一轮 4ms),200A 阶跃落在窗口中间就是”前两路 0A、后两路 200A”,119 篇那条 15%(30A)的均流判据一次投切就误报。

工具照例全离线:drafts/_tools/mux_scan_calc.py,13 个模式,37 项自检断言,文中每个数字都能复算。链路口径与《NTC 采样链路故障》、《BMS 温度门限参数表》、《探头贴装质量出厂验收》严格一致:B3950/R25 10k/NTC 在下/10k 上拉 3.3V/12bit 满量程 4095/1 LSB=0.806mV。


一、先把链路拆成两级 RC,别混着算

多路巡检的模拟链路,教科书上画成一根线,实际是两个独立的 RC,中间夹着一次开关动作:

NTC 分压 --[R_th]--+--[R_on]--+--[C_sh]-- ADC
                   |          |
                 C_node     采样开关
  • 第一级(MUX 节点):从探头分压点到 MUX 输出脚,源阻抗是戴维南电阻 R_th,负载电容是 MUX 的输出电容 + PCB 走线 + ADC 引脚,统称 C_node。时间常数 τ1 = (R_th + R_on) × C_node。
  • 第二级(ADC 采样保持):采样开关闭合后,采样电容 C_sh 从节点取电荷。这一级的源阻抗是 R_th + R_on + R_adc,负载是 C_sh(以及被它拖着的 C_node)。

这两级的判据不一样,必须分别算,然后取慢的那个。 现场最常见的错就是只算了第二级——翻 ADC 手册,查”12bit、C_sh=6pF、t_samp=1.5µs,最大源阻抗 27.7kΩ”,一看自己的 R_th 才 9.8k,判定”没问题”。而第一级要 4.75µs,他给了 2.08µs。

先看 NTC 这一侧的物理量,这是全篇的地基:

T℃ R_ntc R_th(//10k) V_out raw dV/dT τ1@80pF/120Ω
−40 401.9k 9.76k 3220.0mV 3996 −5.68mV/K 790ns
−20 105.4k 9.13k 3014.0mV 3740 −16.10mV/K 740ns
0 33.62k 7.71k 2543.5mV 3156 −30.87mV/K 626ns
12 18.29k 6.47k 2133.7mV 2648 −36.63mV/K 527ns
25 10.00k 5.00k 1650.0mV 2048 −36.66mV/K 410ns
45 4.35k 3.03k 1000.0mV 1241 −27.20mV/K 252ns
55 2.98k 2.29k 757.3mV 940 −21.40mV/K 193ns
72 1.65k 1.41k 466.5mV 579 −13.28mV/K 123ns
85 1.09k 0.98k 323.5mV 401 −8.98mV/K 88ns
125 0.36k 0.35k 114.3mV 142 −2.75mV/K 37ns

这张表里有三件事,后面反复用:

第一,R_th 的最大值趋向”上拉电阻本身”,不是”两个电阻的并联最大值”。 NTC 越冷阻值越大,并联结果趋近上拉电阻 10k。所以 −40℃ 时 R_th=9.76k,几乎是 10k 封顶。习惯上想”并联总比两个都小,最大也就 5k”是错的——5k 只出现在 R_ntc=R_pull 的 25℃ 那一点。

第二,冷端建立最慢。 τ 从 125℃ 的 37ns 到 −40℃ 的 790ns,差 21 倍。所以”冬天出问题、夏天正常”这类现象,第一嫌疑永远是时序,不是温漂。

第三,灵敏度在两端都钝。 12~25℃ 处 −36.6mV/K 最好,−40℃ 只有 −5.68mV/K,125℃ 只有 −2.75mV/K。这意味着一件事,后面会算:同样的残差电压,在热端换来的温度误差更大。所以高温通道既是最该准的,又是最不容易准的。

二、第一级:残差 = 前一通道的电压差 × exp(−t/τ)

通道切换那一刻,MUX 输出脚上的电压还停在上一个通道的值。开关合上之后,它按指数曲线上电到新通道的值:

V(t) = V_ch + (V_pred − V_ch) · exp(−t / τ1)
残差  = (V_pred − V_ch) · exp(−t / τ1)
温度误差 = 残差 / (dV/dT)

三个变量,一个比一个重要:

  • V_pred − V_ch:前一个通道和本通道的电压差。这决定了误差跟”谁”有关。相邻两个电芯温度差 0.5℃,电压差 18mV,残差再大也就 0.5K 的十分之一;但如果前一个通道是柜外环境(−8℃),电压差 0.63V,就是 35 倍;
  • exp(−t/τ1):等待时间的指数衰减。这是唯一你能改的量;
  • 1/(dV/dT):把电压误差翻译成温度误差。

把”要等多久”算出来:

T℃ τ1 等 4τ 的残差(跳变 0.633V) 到 0.5LSB 的时间(满幅 3.3V)
−40 790ns 2.04K 7.12µs
−20 740ns 0.72K 6.67µs
0 626ns 0.38K 5.64µs
12 527ns 0.32K 4.75µs
25 410ns 0.32K 3.69µs
55 193ns 0.54K 1.74µs
85 88ns 1.29K 0.79µs
125 37ns 4.22K 0.34µs

注意最后两列的走势是反的:冷端要等更久,但等不够时的温度误差反而更小;热端等得快,但等不够时温度误差更大。原因就是灵敏度——125℃ 处 1mV 值 0.36K,−40℃ 处 1mV 值 0.18K。

这一栏”4τ 残差”是全篇最关键的一列。它在 12℃ 那里写着 0.32K,和现场那个 0.3 度完全对上。

三、建立深度阶梯:4τ 正好 0.3K,而 4τ 是”看起来很保险”的数

把 exp(−t/τ) 摊成一张阶梯表,用本例的实际参数(跳变 0.633V,12℃ 通道,τ=527ns,灵敏度 −36.63mV/K):

t/τ 残差比 残差电压 温度误差 现象
0.5 60.65% 383.9mV 10.48K 整条曲线像前一通道
1.0 36.79% 232.9mV 6.36K 整条曲线像前一通道
2.0 13.53% 85.7mV 2.34K 秒级可见偏置
3.0 4.98% 31.5mV 0.86K 通道比对里露头
4.0 1.83% 11.6mV 0.32K 就是现场这个 0.3 度
5.0 0.67% 4.3mV 0.12K 勉强合格
6.0 0.25% 1.6mV 0.04K 合格
9.0 0.012% 0.08mV 0.002K 12bit 判据线

4τ 是这一行里最危险的一行,因为它长得太像一个”已经够保守”的经验值。工程口头禅”等 3~5 个时间常数”就是从 8bit 时代传下来的——那会儿 1 LSB = 12.9mV,等 5τ 就足够。现在的 12bit 是 0.806mV,差了 16 倍,需要的 τ 数也跟着涨。

精确的算法很简单:

所需 τ 数 = ln(ΔV / 0.5LSB)

满幅 3.3V、0.5LSB=0.403mV 时,ln(8188)=9.01。一般化成位数:

ADC 位数 所需 τ 数
8 bit 6.24
10 bit 7.62
12 bit 9.01
14 bit 10.40
16 bit 11.78

规律是 (n+1)×ln2,每多一位加 0.69τ。“等 5 个时间常数”这条经验,对应的其实是 9~10bit——放在 12bit 上,正好落在 0.32K 那一格。

现场那个 2.08µs 是怎么来的?500 次空循环。240MHz 下 for(i=0;i<500;i++) __NOP(); 连循环开销一起算就是这个数——一个没有任何物理依据的数字,恰好落在 4τ 上。这类”凑出来的延时”在固件里非常普遍,它的问题不是短,是短得刚好能被判据容忍:0.32K 不会触发任何告警,也不会让保护误动,只是让 6 个电芯测点中的一个永远低 0.3 度。等到有人拿它做一致性判断(比如122 篇的兄弟温差、124 篇的跟随比),它才开始咬人。

四、第二级:ADC 采样窗口有两个判据,取大的那个

第一级等够了,第二级还有一个坑,而且这个坑在手册里查不到。

(a) C_sh 充电:标准公式,源阻抗上限 R_s ≤ t_samp / ((n+1)·ln2·C_sh)。

C_sh t_samp=0.5µs 1.5µs 3µs 10µs
3pF 18.5kΩ 55.5kΩ 111kΩ 370kΩ
6pF 9.2kΩ 27.7kΩ 55.5kΩ 185kΩ
10pF 5.5kΩ 16.6kΩ 33.3kΩ 111kΩ

按这一条,12bit/6pF/1.5µs 允许 27.7kΩ,现场 R_th 最大 9.8k,看起来绰绰有余。这就是”查完手册觉得没问题”的来源。

(b) 节点跌落恢复:采样开关闭合的瞬间,C_sh 要把自己充到节点电压,这份电荷只能从 C_node 拿。如果 C_node 不够”硬”,节点会被拉下来一个台阶:

跌落 = C_sh / (C_node + C_sh)

本例 C_node=80pF、C_sh=6pF,比例 13.3,跌落 6.98%,满幅时 230mV——按 12℃ 灵敏度算是 6.28K。这个台阶要靠源阻抗重新充回去,时间常数是 R_src × (C_node + C_sh) = 652ns,比 (a) 的 65ns 大 10 倍。

采样窗口 跌落残留 折算温度
0.5µs 46.5% 2.92K
1.0µs 21.6% 1.36K
1.5µs 10.0% 0.63K
3.0µs 1.0% 0.06K
5.0µs 0.05% 0.003K

按 (a) 只要 0.41µs,(b) 要 3.26µs,差 6 倍。取大的,t_samp 定 5µs。

判断什么时候 (b) 会咬人,看一个比值:C_node / C_sh。

  • 大于 50(输入端带 1nF 以上):节点很”硬”,(b) 自动满足,按 (a) 算就行;
  • 10~50(本例 13.3):必须两个都算,取大的;
  • 小于 10(16bit ADC 的 C_sh 常有 10~20pF,而 C_node 因为要快所以压得很小):跌落超过 10%,这一级就是主要误差源,只能加缓冲器。

这条判据在现场为什么重要:它是”加了抗干扰电容反而更不准”的另一种解释。加 1nF 会让 C_node/C_sh 变成 167,(b) 消失了——但同时 τ1 涨了 12 倍变成 6.3µs。两个判据是一根跷跷板,你不能只改一头。

五、R_on 不买精度,只买时间

这是本篇最省钱的结论。

MUX 的导通电阻 R_on 常被当成精度指标:CD4051B 在 5V 下 470Ω,74HC4051 在 3.3V 下 120Ω,ADG708 只要 4.5Ω,价格差 20 倍。直觉是”贵的准”。算一下就散了:

τ1 = (R_th + R_on) × C_node
   = (9756 + 470) × 80pF = 818ns      (CD4051B)
   = (9756 + 4.5) × 80pF = 781ns      (ADG708)

差 5%。 因为 R_th 是 9.76k,R_on 在它面前就是个零头。

而精度上,R_on 的贡献严格为零。理由是:ADC 输入阻抗是 MΩ 级,稳态时流过分压网络的只有 ADC 的输入漏电流(nA 级),I×R_on 落在 µV 量级,不到 0.5LSB 的百分之一。R_on 只在充电的那一瞬间有电流通过,等建立完成它就不存在了。

所以选型判断变成两条:

  • 等待时间给够了,1 块钱的 CD4051 和 20 块的 ADG708 读数一样准;
  • 等待时间不够,换 ADG708 也没用——τ 只从 818 降到 781ns,你需要的是 9τ 而不是 9.5τ。

真正有效的提速只有两条路,而且都有代价:

手段 效果 代价
降 R_th(分压电阻 10k→1k) τ 降 10 倍 功耗涨 10 倍(8 路 13mW)
降 C_node(缩短走线、低容 MUX、去掉并联电容) τ 线性降 抗干扰能力下降
换低 R_on 的 MUX τ 降 5% 贵 20 倍

80pF 这个数值得说一句:MUX 输出电容 30pF + PCB 走线 20pF + ADC 引脚 10pF + 余量 20pF。把 MUX 到 MCU 的走线从 5cm 缩到 1cm,能省 10~15pF,τ 降 15%——比换 MUX 划算得多。

六、巡检顺序就是误差的指纹(本篇最有用的一条)

到这里可以把现场那个 0.3 度还原了。8 个通道的实际温度:

CH 位置 实际温度 V_out τ1
0 电芯 11.8℃ 2141.0mV 529ns
1 电芯 12.1℃ 2130.0mV 526ns
2 电芯 12.4℃ 2119.0mV 523ns
3 电芯 12.0℃ 2133.7mV 527ns
4 柜外环境 −8.0℃ 2767.8mV 681ns
5 电芯 12.2℃ 2126.3mV 525ns
6 电芯 12.3℃ 2122.7mV 524ns
7 电芯 11.9℃ 2137.3mV 528ns

CH4 是柜外环境探头,冬天夜里 −8℃,NTC 阻值 402k,分压点被顶到 2768mV。它比相邻的电芯通道高 634mV——这是全表唯一的大跳变。

按正序 0→7 扫描,每个通道的前驱就是它的前一号,算出来的误差:

CH 实际℃ 前驱(温度) 残差 ΔT
0 11.8 7 (11.9℃) +0.07mV +0.002K
1 12.1 0 (11.8℃) +0.21mV −0.006K
2 12.4 1 (12.1℃) +0.21mV −0.006K
3 12.0 2 (12.4℃) −0.28mV +0.008K
4 −8.0 3 (12.0℃) −29.85mV +1.190K
5 12.2 4 (−8.0℃) +12.21mV −0.333K
6 12.3 5 (12.2℃) +0.07mV −0.002K
7 11.9 6 (12.3℃) −0.28mV +0.008K

只有 CH4 和 CH5 两位是错的,其余 6 位的误差在 0.01K 以内(不到 0.02 LSB)。这和现场”只有 CH5 偏低”完全对上——CH4 是环境温度,运维根本没人看它。

现在做那个十秒钟的实验:把扫描顺序倒过来,7→0。

CH 正序 ΔT 倒序 ΔT 倒序时的前驱
3 +0.008K −0.334K 4 (−8.0℃)
4 +1.190K +1.204K 5 (12.2℃)
5 −0.333K +0.002K 6 (12.3℃)

偏低的那一路从 5 号跳到了 3 号,而 5 号自己恢复正常。 跳过去的位置正好是”柜外环境通道的下一个”。

这就是判决性的证据:偏差不是通道的物理属性(否则换顺序不会动),也不是探头的属性(否则换探头会动),而是“谁紧跟在那个大电压差的通道后面采样”这个关系的属性。

顺带解释两个细节,都很容易被误读:

为什么 CH4 自己偏高 1.19K,而 CH5 只偏低 0.33K? 因为 CH4 在 −8℃,灵敏度只有 −25mV/K(冷端钝),同样的 30mV 残差换到 1.19K;CH5 在 12℃,灵敏度 −36.6mV/K,12mV 残差换到 0.33K。冷端是最容易被”同样的电压误差”放大成温度误差的地方——这也是118 篇那张 0℃ 限流表最怕的事:温度读数错了 1 度,限流档位就错一档。

为什么 CH4 的偏差只在冬天夜里出现? 因为 ΔV 就是它和电芯的温差。夏天柜外 30℃、柜内 25℃,差 5℃ → 电压差不到 20mV → 残差 0.4mV → 温度误差 0.01K,淹没在噪声里。冬天 −8℃ vs 12℃,差 20℃ → 电压差 634mV,才浮出来。“季节性出现的通道偏差”这个描述,本身就指向时序——真正的器件问题是常年存在的,只有前驱电压差是季节性的。

七、电荷注入是共模的,前驱残差是差模的

MUX 切换时,开关管的栅极电荷会注入到输出节点。74HC4051 类大约 10pC,ADG708 类 1pC。用同一个 C_node 折算:

ΔV_inj = Q_inj / C_node = 10pC / 80pF = 125mV

125mV 在 12℃ 是 3.41K,在 0℃ 是 4.05K。看起来比前驱残差严重得多,但它有一个关键性质:每一路都一样大。

效应 大小 性质 在通道比对里
电荷注入 125mV(10pC/80pF) 共模,每路相同 看不见
前驱残差 25mV(ΔV=0.63V,4τ) 差模,只打某几路 全暴露

所以这两件事的处置完全不同:

  • 注入只买时间:它和信号一起衰减,等够了就没了。它唯一的作用是把”所需的等待时间”往上抬一点——把 ΔV + Q/C 当成一个更大的等效跳变去算 9τ 就行。本例 125mV 相对 634mV 是 20%,等待时间要多 2%。
  • 前驱残差要买结构:换顺序、加缓冲器、或按最坏 ΔV 设计等待时间。改不了就认,但必须在判据里扣掉。

这条区分解释了一个常见困惑:“我把所有通道都短接到同一个基准,读数都很准,为什么现场还是偏?” 因为短接之后 ΔV=0,注入也被同一电压对齐,两个效应同时归零。这个测试测的是”器件好不好”,测不出”时序够不够”。

八、漏电:低功耗大电阻的真实代价

关断通道的漏电流会通过 R_th 变成一个直流偏移。这个偏移不像残差那样会衰减——它一直在。

10k/10k 分压(NTC 在下):

器件 / 口径 I_off −8℃ 12℃ 25℃ 55℃ 85℃
HC4051 类 25℃ 典型 0.10nA 0.0mK 0.0mK 0.0mK 0.0mK 0.0mK
HC4051 类 85℃ 外推 6.40nA 2.1mK 1.1mK 0.9mK 0.7mK 0.7mK
HC4051 类 85℃ 手册上限 100nA 33.4mK 17.6mK 13.6mK 10.7mK 10.9mK
ADG708 类 85℃ 上限 0.10nA 0.0mK 0.0mK 0.0mK 0.0mK 0.0mK

最坏一格 33.4mK,占整条链 0.366K 预算的 9%,可以接受。

100k/100k 分压(把功耗降 10 倍,从 1.32mW 降到 0.13mW):

器件 / 口径 I_off −8℃ 12℃ 25℃ 55℃ 85℃
HC4051 类 85℃ 外推 6.40nA 21.4mK 11.3mK 8.7mK 6.9mK 7.0mK
HC4051 类 85℃ 手册上限 100nA 334.5mK 176.5mK 136.4mK 107.2mK 109.1mK
ADG708 类 85℃ 上限 0.10nA 0.3mK 0.2mK 0.1mK 0.1mK 0.1mK

最坏一格 334mK,比整条链的器件误差(0.366K)还大。 而且注意它是单向的、常驻的、不随采样时序变化的——它不会像残差那样被”换个顺序”暴露,会安安静静待在那里。

所以低功耗大电阻的结论不是”能”或”不能”,是必须成套换:

方案 静态功耗 R_th τ1 漏电(85℃ 上限) 结论
10k + HC4051 1.32mW 9.9k 790ns 33mK 可以,建立时间 7.1µs
10k + ADG708 1.32mW 9.9k 781ns 0.03mK 过设计,钱花在没用的地方
100k + HC4051 0.13mW 99k 7.9µs 334mK 不合格
100k + ADG708 0.13mW 99k 7.9µs 0.3mK 可行,等待时间 71µs

100k + ADG708 是省电的正确解法:省 1.2mW,付 71µs 的等待时间(slot 125ms 完全付得起),精度不掉。而 100k + HC4051 是”省了电,精度没了”,还查不出来——因为它的指纹是”所有通道一起慢慢偏”,在一致性判据里看不见。

顺带一个量级校验,防止把这件事想得太严重:100k 方案下 R_th 最大 99k,正常工作时这个电阻上的热噪声是 √(4kTRB),B=1kHz 时 1.3µV,折 0.04K。噪声不是问题,漏电才是。

九、缓冲器很容易加错位置

“加个运放做跟随,把源阻抗降下来”——这句话对,但位置决定生死。三种方案,同一个 MUX:

方案 一级 τ 二级 τ 代价 解决问题?
A 每通道一个跟随器(探头端) 4.0ns 90.3ns 8 颗运放 + 8×0.5mA 彻底解决
B MUX 后一个共享缓冲器 410ns 90.3ns 1 颗运放 一点没解
C 输入端串 1k + 100nF 647µs 747µs 0 元 反向恶化 1500 倍

方案 B 是现场最常犯的错。 运放加在 MUX 后面,它只把”ADC 的负载”和”MUX 的输出”隔开——但 MUX 输出脚上那 80pF 还是得由探头自己充,τ1 一点没变(410ns)。而 ADC 那一级的 τ 本来就只有 90ns,不需要救。钱花了,病没治。

方案 A 才是真正的解:跟随器放在探头端,MUX 节点由运放的 50Ω 输出阻抗驱动,τ 从 410ns 掉到 4ns,快了 100 倍。代价是 8 颗运放(4 颗双运放),BOM 加 8~15 块,静态电流加 4mA。8 路以上、且需要 10µs 以内的建立时间时,这个钱值得花。

方案 C 是”为了抗干扰加电容”的典型翻车:100nF 配 6.47k 的 R_th,τ=647µs。等 2.08µs 时衰减 exp(−0.0032)=0.9968,等于每个通道读到的都是前一个通道的电压。

这个失效模式的指纹和”0.3 度”完全不同,很好认:

  • 偏 0.3K 那种(时间不够一点点):某一路固定偏,曲线形状不变,只是整体平移;
  • 100nF 那种(时间差 300 倍):曲线整体右移一位——把 8 条温度曲线画在一张图上,会发现 CH5 的形状像 CH4、CH6 像 CH5。

第二种情况别去查探头,一查一个准是白查。反推一下:要让 100nF 方案的残差降到 0.3K,等待时间得给到 3ms。slot 是 125ms,付得起——所以 100nF 不是不能用,是必须和 slot 一起重算,不能沿用 2µs。这就是本篇反复出现的主题:时序预算是一个整体,改一头必须回头改另一头。

十、巡检 vs 同步采样:温度够用,电流致命

这是”多路巡检”这个方案该不该用的分水岭。判据只有一个:被测量的时间常数。

先算温度这边的 skew 值多少。8 路 × 125ms = 一轮 1s,第 8 路和第 1 路在时间上差 875ms:

工况 温升速率 一轮 1s 内的变化
1C 充电 6.10K/h 1.69mK
0.5C 充电 1.53K/h 0.43mK
加热膜启动瞬间 2.10K/h 0.58mK

对照124 篇的判据——兄弟温差 3K、斜率缺口 30%(0.5C 下 460mK/h)——skew 贡献 1.7mK,差两个数量级。温度巡检一轮 1s 完全够用,甚至 10s 也够(探头自身 τ 是 6~8s,比巡检周期还长,采样点之间本来就是相关的)。

电流就完全不是这回事:

  • 4 路电流若也靠 MUX 巡检、每路 1ms,一轮 4ms;
  • 负载投切、充电机启停是 100ms 级事件,但 MOSFET 关断只要 100µs;
  • 200A 的阶跃如果正好落在 4ms 窗口中间,前两路读 0A、后两路读 200A;
  • 119 篇的均流判据是”支路电流差 15%(=30A)持续 60s”——一次投切就误报,而且误报会持续 60s。

所以这一条不是”精度问题”,是判据的时间基准问题:任何”多路之间的差”的判据,都要求各路在同一时刻取值。电流类判据必须用:

  • MCU 的双 ADC 同步规则组(同时启动转换);
  • 或多路采样保持同时进入 hold,再逐个读出;
  • 或每路一个独立的 ΣΔ/霍尔传感器(本来就是并行的)。

顺便把这一条推广成一个通用规则,写进设计评审清单:

被测量 时间常数 采样方式 一轮 skew 允许值
电芯温度 6~8s(探头)到 5h(包体) MUX 巡检 ≤ 1s
母线电压 ms~s 巡检或同步 ≤ 10ms
支路电流 µs~ms 必须同步 ≤ 100µs
绝缘阻抗 s 巡检 ≤ 1s

十一、slot 不该平均分

8 路 × 125ms 是最省事的写法,也是最浪费的写法。实际每路只需要 25~30µs:

单通道:等待 10µs + 采样 5µs + 转换 4µs + 开销 6µs = 25µs
占空比:25µs / 125ms = 0.02%

CPU 有 99.98% 的时间可以睡。 如果为了省电把巡检周期拉到 10s,占空比降到 0.00025%,一年省下的电还不够一次误动作的代价。

但平均分的真正问题是它把”快”和”慢”混在一个节奏里。合理的做法是按时间常数分档:

档位 周期 通道 实现
快 1ms 支路电流、母线电压 独立 ADC 通道 + DMA 连续
中 100ms 功率器件温度、电感温度 MUX 前 4 路
慢 1s 电芯温度、环境温度 MUX 后 4 路
极慢 60s 绝缘、SOH 辅助量 单独任务

这样做的额外好处:慢档的等待时间可以给足。电芯温度那 4 路,每路可以给 5ms 的建立时间(本来只要 4.75µs),留 1000 倍余量,什么探头、什么线长都不用怕。而快档不需要 MUX,也就没有 MUX 的时序问题。

一个反过来的坑要提一句:别把”一轮”当成”一个决策窗口”。122 篇的四张门(禁充、限流、加热、降额)需要”同一时刻的全套温度”来做 limiting source 判断。如果 8 路分在 4 个不同的 MUX 上、由 4 个任务分别扫描,就会出现”这一路的温度是 800ms 前的、那一路是 100ms 前的”,在温度快速变化时(比如刚启动加热)判断会抖。做法是每轮结束时打一个时间戳,同一轮的 8 个值算同一次决策,而不是各算各的。

十二、产线自检:交替基准法,两根线就能测出时序够不够

前面所有分析都是”算”,这一节是”测”。而且这个测法不花一分钱。

做法:把 8 路输入交替接到 0.5V / 2.5V 两个基准(偶数路 0.5V,奇数路 2.5V),按真实的扫描顺序和真实的 slot 跑一遍,读 raw 值。

  • 每次切换的跳变是 2.0V = 2482 LSB,把建立残差放到最大;
  • 理论值:相邻通道 raw 差恰好 2482;
  • 判据:偏离超过 12 LSB(约 0.12K)即不合格。
等待时间 残差 LSB 折算温度 判定
2.08µs 12.46mV 15.5 0.340K 不合格
4.00µs 0.11mV 0.1 0.003K 合格
6.00µs 0.00mV 0.0 0.000K 合格

三行就把现场那个 2.08µs 判死了,和前面算出来的 0.333K 互相印证。

为什么不能”全部短接到同一个点”? 因为那样跳变等于 0,残差恒等于 0,什么也测不出来。这个测试的全部信息量都在”跳变”里,所以基准必须交替。

还有两个细节,都是坑:

第一,测试用的基准源内阻要低。 两个基准若来自同一颗 DAC 的两个通道,输出阻抗几百欧,会串进来。用 TL431 分压 + 运放跟随,或者干脆用两个低阻分压(1k/1k 从 3.3V 和 5V 分出来)。基准的内阻直接加在 R_th 上,会把你测的东西改掉。

第二,产线 25℃ 通过,不代表 −40℃ 合格。 这一条最容易被忽略:

温度 τ1 等 4µs = 多少 τ 残差
25℃ 410ns 9.77τ 0.006%
−8℃ 681ns 5.88τ 0.280%
−40℃ 790ns 5.06τ 0.633%

同样 4µs,−40℃ 的残差是 25℃ 的 100 倍以上。 产线在 25℃ 测出的”合格”,对冷端毫无预测力——这正是”出厂全过、冬天出问题”的机理。

解法很轻:产线测试时在每个输入端串 4.7kΩ。直流下没有电流流过它,读数不变;但它把 R_th 从 6.5k 抬到 11k,覆盖了 −40℃ 的 9.8k。这时候 12 LSB 的判据就真正代表了最坏情况。

/* 产线自检序列(伪代码,交替基准法) */
for (ch = 0; ch < 8; ch++) {
    mux_select(ch);
    delay_us(T_SETTLE);          /* >= 9 * tau_worst */
    raw[ch] = adc_read_12bit();  /* t_samp >= 5us */
}
int32_t d = 0;
for (ch = 0; ch < 7; ch++)
    d = MAX(d, abs((raw[ch+1] - raw[ch]) - 2482));
FAIL_IF(d > 12);                 /* 12 LSB = 0.12K = 0.5% 建立深度 */

十三、排障十步(按命中率排)

下次遇到”某个通道固定偏”,照这个顺序做,前三条能解决八成:

  1. 把扫描顺序倒过来(7→0),看偏差是否跟着跳到”离群通道的下一个”。是 → 建立时间不足,收工。这条十秒钟,永远第一个做。
  2. 交换两个通道的探头接线:偏差跟着线走,还是跟着通道走?跟通道 → MUX/时序;跟线 → 探头/接线/分压电阻。
  3. 示波器看 MUX 输出脚,在 ADC 采样窗口末尾量纹波。大于 0.5 LSB(0.4mV)就是等待时间不够,直接加。
  4. 把等待时间从 2µs 加到 20µs 再读一遍。偏差消失 → 确诊;不消失 → 看第 5 条。
  5. 全通道接同一基准,读数极差是否大于 0.1K。是 → ADC 通道差或 MUX 的 R_on 不平坦(直流上本不该有差)。
  6. 某通道输入并 100nF 后,曲线是否”像前一个通道”。是 → RC 太大,采样窗口被记忆效应吃掉。
  7. 高温工况(>60℃)偏差是否变大。是 → 关断漏电,换低漏 MUX 或降分压电阻。
  8. 偏差是否只在负载高/某器件发热时出现。是 → 前驱通道是功率器件温度,跳变大。
  9. ADC 采样窗口是否按手册最小值配的。是 → 只满足了第二级,第一级没算。
  10. 固件延时是不是空循环或未校准的 NOP。是 → 编译优化、主频变化都会改它,改用定时器或 ADC 触发。

第 1 条为什么排第一:它是唯一能把”时序”从”器件”里一刀切开的实验。器件问题不会因为顺序改变而改变,时序问题一定会。

十四、时序预算表(可直接抄进设计评审)

项目 判据 本例取值 备注
MUX 切换→启动 ADC 的等待 ≥ 9τ1(按最坏 R_th) 10µs −40℃ 需 7.1µs,留 40%
ADC 采样窗口 t_samp ≥ max(9.01·R_src·C_sh, 5·R_src·(C_node+C_sh)) 5µs 两个判据取大
ADC 转换 器件固定 4µs @1Msps
单通道总占用 等待+采样+转换+开销 25µs 占 slot 的 0.02%
温度巡检周期 ≤ 最快保护环 τ 的 1/5 1s 8 路 × 125ms
电流采样 必须同步 双 ADC 同步规则组 巡检会误报均流
交替基准自检 raw 偏差 ≤ 12 LSB 产线 100% 输入端串 4.7k 覆盖冷端
漏电上限 I_off × R_th ≤ 0.5 LSB ≤ 0.4mV 85℃ 上限口径
R_on 指标 只影响 τ,不影响精度 470Ω 可接受 别为它多花钱

最后把本篇的主线收成一句话:加一个 MUX,你付出的不是精度,是时间。精度账上它几乎是白送的(0.366K → 0.367K,+0.2%);时间账上它要求你从”我延时了 2µs”变成”我按最坏 R_th 算了 9τ”。而时间账一旦算错,它不会报错、不会越界、不会触发任何告警——它只会让某一路温度悄悄偏 0.3 度,然后在你拿它做一致性判据的那天,咬你一口。


工具:drafts/_tools/mux_scan_calc.py(13 个模式,37 项自检断言,纯标准库、全离线)。文中数据口径:B3950/R25 10k/NTC 在下/10k 上拉 3.3V/12bit 满量程 4095/1LSB=0.806mV;C_node=80pF(MUX 输出 30 + 走线 20 + ADC 引脚 10 + 余量 20);C_sh=6pF;R_adc=1kΩ;R_on=120Ω(74HC4051@3.3V);Q_inj=10pC;漏电按 HC4051 类 25℃ 典型 0.1nA、85℃ 按 10℃ 翻倍外推 6.4nA、手册上限 100nA 三档给出,具体数值请按自己器件的 datasheet 替换。

另:9 月 26 日那篇《ESD 与浪涌防护实战》里”12.5kV 应为 12.5V”的笔误还没改,等排期。站内至今仍缺《Flash 存储与参数管理》和《固件安全与逆向防护》两个主题,都在待写清单上。


下一篇写多通道巡采的通道间串扰与 MUX 前置滤波的取舍——本篇只把 C_node 当成一个集总电容,实际上 8 路输入引脚之间还有容性耦合,一个高阻通道会通过 3~5pF 的引脚电容”偷看”邻居;以及”输入端到底该不该加 RC、加多大”这个问题的定量答案(滤波带宽 vs 建立时间 vs 通道串扰三者的一张等值线图)。顺带把本篇没展开的”共模注入如何用差分采样消掉”补上。