过孔设计与返回路径实战:30 台板子里 3 台”偶尔枚举失败”,最后问题出在换层过孔旁边少的那几个地过孔
引子:30 台里坏 3 台,换模组、换线、换电源都没用
事情起因是一块工业网关板:STM32 级别的主控,USB 2.0 高速口接一颗 Cat.1 模组。板子是常规的 1.6mm 四层板,成本敏感,不可能上六层。
小批量 30 台,客户测下来 3 台有问题,症状很统一:冷机上电十次里有六七次枚举成功,热机(连续跑两小时)几乎必成;同一台机器,把模组拆下来插到别的板子上就没事。
典型的”换模组没用、换线没用、换电源没用”三连。既然三换无效,说明问题不在模块,而在从主控到模组连接器之间那段走线上。
上示波器,USB 差分对(D+/D-)用差分探头量。眼图整体是开的,但在某个时间点有个轻微但稳定存在的台阶——不是振铃(振铃我们上个月刚在 25MHz 时钟线上处理过),是一个阻抗被拉低的凹陷,位置正好对应走线换层的那一段。
翻 PCB 文件,D+/D- 为了躲开板子底部的金属天线区,从 L1 换到 L3,换层点在连接器下方 8mm 左右。
我第一反应是残桩(stub)。算了半天,发现 1.6mm 四层板 L1→L3 的残桩只有约 0.25mm —— 这个长度在 USB 2.0 的上升时间面前根本不值一提。方向错了。
真正的问题,是在那个换层过孔旁边,我用尺子在 Layout 里量了三遍:最近的接地过孔在 12mm 外。
这一篇就把这件事讲透:过孔到底该怎么算、残桩什么时候才真的要管、以及为什么 90% 的现场翻车都不是过孔本体,而是它周围的返回路径。
先把过孔当成一个元件:两颗寄生参数,外加一段残桩
很多人把过孔当成”一个连接点”,这在 1MHz 的板子上没问题,但在几十 MHz 以上,过孔其实是一段竖起来的、直径很粗的传输线,而且它有自己的电感、电容,还带一截没人用的”尾巴”。
# 配套脚本:drafts/_tools/via_z0.py
python via_z0.py via --h 1.6 --drill 0.3 --pad 0.6 --antipad 0.8
输出(1.6mm 板、0.3mm 钻孔、0.6mm 焊盘、0.8mm 反焊盘):
过孔本体: h=1.60mm drill=0.30mm pad=0.60mm antipad=0.80mm
筒电感 L = 1.30 nH
电容 C = 1.15 pF (公式上限值)
等效阻抗 Z = 33.7 ~ 47.6 Ω (C 取 1.0~0.5 倍)
LC 谐振 f0 = 4.1 ~ 5.8 GHz
时延 t_pd = 11.07 ps (全长)
电感:跟板厚成正比,跟孔径只是对数关系
经典式(Johnson/Graham 口径,长度用英寸):
L(nH) = 5.08 × h × [ ln(4h/d) + 1 ] h、d 单位:英寸
换成 mm 口径就是 0.2 × h × [ln(4h/d) + 1](h 单位 mm)。
扫一遍板厚和孔径:
| 板厚 \ 钻孔 | 0.20mm | 0.25mm | 0.30mm | 0.40mm | 0.50mm |
|---|---|---|---|---|---|
| 0.8mm | 0.60 | 0.57 | 0.54 | 0.49 | 0.46 |
| 1.0mm | 0.80 | 0.75 | 0.72 | 0.66 | 0.62 |
| 1.6mm | 1.43 | 1.36 | 1.30 | 1.21 | 1.14 |
| 2.0mm | 1.88 | 1.79 | 1.71 | 1.60 | 1.51 |
| 2.4mm | 2.34 | 2.23 | 2.14 | 2.01 | 1.90 |
| 3.2mm | 3.30 | 3.16 | 3.04 | 2.86 | 2.72 |
(单位 nH)
看这张表要看两个”不”:
- 电感基本正比于板厚。1.6mm 通孔 1.3nH,3.2mm 通孔 3.0nH。想要低电感,第一选择是把过孔缩短(薄板、盲孔、埋孔),不是把孔径开大。
- 孔径的影响是对数关系:钻孔从 0.2mm 开到 0.5mm,电感只从 1.43nH 降到 1.14nH,降了 20%。而孔径开大会牺牲布线密度、增加钻孔成本。用大孔径去降电感,是性价比最低的做法。
电容与阻抗:一个 30~50Ω 的低阻小台阶
电容用经典式 C(pF) = 1.41 × εr × T × D1 / (D2 − D1)(T、D1、D2 单位英寸,D2 是反焊盘)。
算出来 1.15pF。这个式子是按过孔全长积分的,偏保守,实测常落在 0.5~0.9pF 区间,我这里按 1.0~0.5 倍给区间。
再算等效阻抗 Z = √(L/C),就是 33.7 ~ 47.6Ω;LC 谐振点在 4.1 ~ 5.8GHz。
先给结论:一颗 1.6mm 板上的常规通孔过孔,等效为一个 34~48Ω 的、谐振点在 4GHz 以上的低阻小台阶。在 500MHz 以下的嵌入式板子上,它本身几乎不背锅。
这句话很重要。因为我们下一节要说的”翻车”,问题根本不在这个 L 和 C 上。
让大多数人翻车的不是过孔本身,是返回路径
返回电流永远走”最近的”那条路
信号在走线上跑的时候,它的返回电流并不是”随便从地平面流回去”,而是紧贴在信号走线正下方的地平面上、沿着信号路径原路返回。高频下这几乎是强制的:返回电流会自动找回路面积最小的路径,因为那对应最小的回路电感。
走线在表层时,这是自然的——返回电流就在正下方的 L2 地平面里,跟着走线走。
但信号一旦换层,返回电流也得跟着换层。
换层的三种情形,只有一种不用管
情形一:信号换了层,但参考平面没变。
比如 L1 的参考是 L2 地,换到 L3 后参考还是 L2 地(L3 在 L2 下方,参考面朝上)。这时候返回电流全程待在 L2 里,只需要绕过信号过孔的反焊盘。这是最省事的一种,基本不用额外处理。
情形二:信号换了层,参考平面也换了,但两个平面都是地(GND→GND)。
比如 L1 参考 L2 地,换到 L4 后参考 L3 地。返回电流必须从 L2 跳到 L3。跳过去的唯一通路是缝合过孔(stitching via)。附近没有缝合过孔,返回电流就得绕到最近的缝合过孔那里去。
情形三:参考平面从地换到了电源(GND→PWR),或者反过来。
比如 L1 参考 GND,换到 L3 后参考 VDDQ(DDR 场景很常见)。这种情况下两个平面在直流上是隔离的,缝合过孔也救不了——返回电流必须通过平面间的去耦电容完成交流换乘。所以换层点旁边要有就近的 0.1µF,而且这个电容的过孔也要紧贴。
我们那块网关板踩的是情形二:L1 参考 L2 地,换到 L3 后参考 L4 地。返回电流得从 L2 跳到 L4,而最近的缝合过孔在 12mm 外。
回路电感与环路面积的账
用平行双圆柱近似 L ≈ (μ0/π) × h × ln(s/r)(s 是信号孔到地孔的中心距,r 是孔筒半径),1.6mm 板、0.3mm 钻孔:
| 信号孔—地孔中心距 s | 回路电感 | 相对 s=1mm 增加 | 环路面积放大 |
|---|---|---|---|
| 1.0mm | 1.21 nH | — | 1× |
| 2.0mm | 1.66 nH | +37% | 2× |
| 3.0mm | 1.92 nH | +58% | 3× |
| 5.0mm | 2.24 nH | +85% | 5× |
| 8.0mm | 2.54 nH | +110% | 8× |
| 12.0mm | 2.80 nH | +131% | 12× |
两个后果:
- 回路电感翻倍还多 —— 返回路径上的等效电感从 1.2nH 涨到 2.8nH,换层处这个”电感台阶”直接把信号边沿拖慢、把共模电流顶起来。
- 环路面积放大 12 倍 —— 辐射场强正比于环路面积 × 频率² × 电流。面积涨 12 倍,共模辐射直接上一个数量级。这也解释了后来我们在 375MHz 附近测到的那 5dB 超标。
所以对这个案子,整改动作就很明确了:
- 在 D+/D- 换层过孔两侧各 1mm 内加两个地过孔,把 L2 和 L4 缝合起来;
- 反焊盘从板厂默认给的 1.0mm 收到 0.8mm;
- 两颗信号过孔的间距调整到与走线间距一致(下一节讲)。
改版复测:眼图那个台阶消失,30 台全过,375MHz 附近辐射降了 5dB。
这就是”过孔问题”的真相——绝大部分不是过孔本体,是返回路径。
反焊盘:开小会短路,开大会把平面啃穿
反焊盘(antipad,也叫隔离盘 / clearance)就是过孔在参考平面上的那个”洞”。开大还是开小,很多人是凭”保险起见开大点”的感觉定的,我们把它算清楚。
python via_z0.py antipad --h 1.6 --drill 0.3 --pad 0.6
| 反焊盘直径 | 过孔电容 | 等效阻抗 | 单边间隙 |
|---|---|---|---|
| 0.70mm | 2.29 pF | 23.8 Ω | 0.050mm |
| 0.80mm | 1.15 pF | 33.7 Ω | 0.100mm |
| 0.90mm | 0.76 pF | 41.2 Ω | 0.150mm |
| 1.00mm | 0.57 pF | 47.6 Ω | 0.200mm |
| 1.20mm | 0.38 pF | 58.3 Ω | 0.300mm |
| 1.50mm | 0.25 pF | 71.4 Ω | 0.450mm |
看完这张表,有个反直觉的结论要先说:
反焊盘开大,过孔电容变小,过孔阻抗反而升高,单看阻抗匹配似乎是”变好”了。
那为什么不能一路开大?因为代价不在阻抗,在平面:
- 反焊盘每开大一档,参考平面上就多挖掉一圈铜。单颗过孔无所谓;但在 BGA 扇出区、连接器扇出区这种过孔密集的地方,一排排反焊盘会把地平面啃成一张渔网,局部平面阻抗升高,返回电流被迫四处绕行 —— 你辛辛苦苦换来的”阻抗匹配变好”,被”返回路径变差”吃回去还不够。
- 反焊盘开得太大时,相邻过孔之间的”桥”(平面残铜)会窄到不合理,极端情况下平面被切断成孤岛,那才是真灾难。
另一头的边界是工艺:
- 单边 0.05mm 就接近常规蚀刻能力的下限了,铜残留/CAF 风险高。行业常规最小单边间隙是 0.10mm(4mil),高多层板往 0.125mm 走。
- 所以常规取值就是 反焊盘直径 = 焊盘直径 + 0.20 ~ 0.25mm,也就是单边 0.10~0.125mm。
我们那块板的问题正是:板厂按”焊盘 0.6 + 反焊盘 0.4″给的默认值,反焊盘做到 1.0mm,单边 0.2mm。单颗看没问题,但那一片正好是模组连接器的扇出区,几十颗过孔排在一起,把 L2 地平面啃掉了一大片 —— 和”没有缝合过孔”叠加在一起,返回路径雪上加霜。
结论:反焊盘”够用就好”。定成焊盘 + 0.2~0.25mm,然后在 Gerber 里明确标注,不要留给板厂默认。
非功能焊盘(NFP):最容易被忽略的那 0.3pF
NFP = Non-Functional Pad,非功能焊盘。就是过孔在它并不连接的层上留下的那个圆焊盘。
1.6mm 四层板,一颗 L1→L4 的通孔过孔,会焊盘出现在 L1、L2、L3、L4 四层上。如果它只连 L1 和 L4,那 L2、L3 上的焊盘就是 NFP —— 没有电气作用,但真实存在。
代价有三个:
- 增加电容。 每个内层 NFP 贡献大约 0.2~0.4pF(量级参考,跟反焊盘尺寸相关)。四层板两颗 NFP 就是 +0.4~0.8pF,跟过孔本体的电容是同一量级。上面算出的 1.15pF 是”内层焊盘全保留”的上限值,就是因为它把这些 NFP 一起算进去了。
- 恶化阻抗连续性。 NFP 处结构突变,TDR 上会看到额外的毛刺。
- 可靠性隐患。 无连接的铜盘在层压中更容易成为 CAF(导电阳极丝)的起点。
处置方法很简单:在钻孔表/加工说明里写一句”内层非功能焊盘全部删除(Remove NFP on inner layers)”,并且在 Gerber 里核对一遍。 这是零成本优化,但很多板厂的默认流程不会替你删。
残桩:先算电长度,再决定要不要盲埋孔或背钻
残桩(stub)是通孔过孔连接点之外的那截多余孔壁。1.6mm 四层板,信号从 L1 走到 L3,过孔却是从 L1 打穿到 L4 的,那 L3 到 L4 这 0.25mm 就是残桩——一段一端悬空的开路线。
残桩的麻烦在于:它是一段开路细线,会在 λ/4 处产生串联谐振,表现为那个频率附近阻抗急剧塌陷。所以判断标准非常清晰:
残桩的单向电长度 t_pd 如果小于信号上升时间的 1/6,就不用管它。
算几个典型值:
| 残桩长度 | 单向电长度 t_pd | λ/4 谐振频率 | 需处理的上升时间门槛 |
|---|---|---|---|
| 0.25mm(1.6mm 四层,L1→L3) | 1.73 ps | 144.6 GHz | t_r < 10.4 ps |
| 1.10mm(1.6mm 六层,L1→L3) | 7.61 ps | 32.9 GHz | t_r < 45.7 ps |
| 1.70mm(2.4mm 八层,L1→L3) | 11.76 ps | 21.3 GHz | t_r < 70.6 ps |
| 3.00mm(3.2mm 八层,L1→L2) | 20.76 ps | 12.0 GHz | t_r < 124.6 ps |
(FR-4 中传播速度 ≈144.6 mm/ns,对应 6.92 ps/mm)
再把这几个门槛换成接口语言,就一目了然了(门槛长度 ≈ t_r × 0.0241 mm):
| 接口 / 速率 | 典型上升时间 | 残桩门槛长度 |
|---|---|---|
| USB 2.0 HS(480Mbps)/ 千兆以太网 | 400~500 ps | 9.6~12.1 mm |
| MIPI D-PHY(1.5Gbps) | 100~150 ps | 2.4~3.6 mm |
| PCIe Gen1/Gen2(2.5/5 GT/s) | 50~100 ps | 1.2~2.4 mm |
| 10Gbps SerDes | 30~40 ps | 0.7~1.0 mm |
所以结论很硬:
- 1.6mm 四层板(残桩最大约 0.3mm),门槛 9.6mm 起步 —— 残桩这辈子都轮不到它背锅。我一开始把问题往残桩上想,是纯粹的浪费。
- 1.6mm 六层板(残桩约 1.1mm),USB 2.0 / 千兆网仍然安全;要上 PCIe Gen2 就开始进入射程。
- 2.4mm 以上厚板 + MIPI / PCIe / 10G,残桩才是真问题,这时候才值得掏钱:盲埋孔、背钻(back-drill)、或者把高速网络安排在最靠近板面的层。
背钻是用一个比钻孔略大的钻头(通常大 0.2mm)把残桩那截铜壁钻掉,把残桩压到 0.2~0.3mm 以内。代价是成本和流程复杂度,只在确实需要时用。
判断顺序永远是:先算 t_pd,再算 t_r/6,最后才谈工艺手段。 别拿盲埋孔去治一个本来就不存在的病。
差分过孔:两根线一起换层时要盯的三个量
差分对换层比单端麻烦,因为两根线的一致性本身就是一个指标。
第一,共模转换(SCD21)。
差分对的返回电流方向相反,理想情况下在地平面里的感应电流严格相消。但换层时如果:
- 两个过孔的间距和走线段的间距不一致(过孔间距通常受焊盘尺寸限制,会偏大);
- 两个过孔周围的地过孔布局不对称(比如只在一侧放了一个);
差分信号就会被”掰”成一部分共模电流,跑回电缆、连接器、金属结构上去辐射。这在近场探头下是一个很清晰的单点热点。
处置规律: 差分对的过孔布局必须是镜像对称的。地过孔不要”塞在两个信号孔中间”(那看起来对称,实际上把差分对的紧耦合结构切断了),而是在两颗信号孔的外侧对称各放一个,或者四角各一个对称布局。
第二,偏斜(skew)。
差分对的本质是”两条线要走一样长、一样快”。同层一起换层时,两根信号孔的残桩长度是一样的,偏斜主要由过孔间距不一致和地过孔不对称引入。一般不需要精确算,遵循对称原则即可。
第三,过孔反焊盘在平面上形成的”槽”。
这点最隐蔽:两颗差分过孔并排,它们在地平面上的两个反焊盘如果挨得近,会合并成一条长条形的开槽。如果差分对换层后正好横跨在这条槽的两侧,返回电流的路就被切断了。
处置: 差分对换层点周围一定要补缝合过孔,把槽”两侧的地”重新连起来;必要时把反焊盘适当收小(回到 0.8mm 这一档),让平面残铜连成片。
电源过孔:别拿信号过孔的尺寸去算电流
信号过孔看的是阻抗,电源过孔看的是载流和散热,两套逻辑。
python via_z0.py current --drill 0.3 --plate 25
孔壁铜的环形截面积 A = π × drill × t_plate。0.3mm 钻孔、25µm 孔壁铜:
孔壁环形截面积 = 0.0236 mm^2 (36.5 mil^2)
~10C 温升单孔载流 ≈ 2.04 A (量级参考)
保守设计取值 ≈ 1.22 A (打 60% 折扣)
对照几个常用规格(10°C 温升,量级参考):
| 钻孔 | 孔壁铜 | 截面积 | 估算载流 | 保守取值(×0.6) |
|---|---|---|---|---|
| 0.20mm | 20µm | 0.0126 mm² | 1.29 A | 0.77 A |
| 0.30mm | 25µm | 0.0236 mm² | 2.04 A | 1.22 A |
| 0.50mm | 25µm | 0.0393 mm² | 2.9 A | 1.75 A |
三条经验:
- 过孔是个”短粗导体 + 两端接大铜面”,散热条件比同截面走线好,所以单位截面载流能力反而更强。别按走线那套表去保守折算,会过度浪费面积。
- 但密集穿孔会拉高温升。一排电源过孔挤在一起,铜面上的热量叠起来,实际温升比单孔估算差。大电流路径要用孔阵列(3×3 起)而不是放大单孔,孔间距留 1mm 以上利于散热。
- >2A 的路径请做温升实测(红外枪或热像仪,堵住风冷)。上面这些数字都是量级参考,真实值受板厂镀铜均匀性影响很大(有的厂标 25µm 实际只有 20µm)。
另外,电源过孔还有一个”顺带”的好用途:QFN/BGA 底部散热焊盘下的过孔阵列,就是主散热路径。这类过孔要小(0.2~0.3mm)、要多、而且必须塞孔或填平——下一节讲。
工艺边界:孔径、孔环、厚径比、塞孔
设计再漂亮,画不出来也是白搭。常规工艺的边界先摆出来:
| 项目 | 常规能力 | 备注 |
|---|---|---|
| 最小机械钻孔 | 0.20mm | 0.15mm 需激光孔(HDI,成本跳档) |
| 最小孔环(annular ring) | 单边 0.15mm | 0.10mm 属进阶工艺 |
| 厚径比(板厚/孔径) | ≤ 10:1 常规,≤ 8:1 更稳 | 1.6mm 板 + 0.2mm 孔 = 8:1,正好卡线 |
| 过孔焊盘直径 | 钻孔 + 0.3~0.4mm | 即单边 0.15~0.2mm 孔环 |
| 反焊盘直径 | 焊盘 + 0.20~0.25mm | 见上文 |
| 过孔到过孔 | ≥ 0.25mm 间隙 | 太近会连孔/断桥 |
厚径比这条特别容易被忽略。 1.6mm 板配 0.2mm 钻孔,厚径比就是 8:1,已经在常规工艺的偏上限一侧了,孔壁镀铜均匀性变差,可靠性下降。如果还想再压小孔径去提高布线密度,就该考虑上多层或 HDI,而不是硬顶。
塞孔(via plugging / tenting / filling) 这块,是焊接质量的直接影响项:
- 盖油(tenting):阻焊盖住过孔。最便宜,但孔径大时盖不住,回流焊时阻焊容易”爆油”。
- 塞孔(plugging):用油墨把孔塞实。防助焊剂/焊料从孔里流到背面。
- 填铜 + 磨平(POFV, Plated Over Filled Via):孔内填铜后电镀磨平,表面平整。凡是”过孔打在焊盘上”(via-in-pad,BGA 扇出、QFN 散热焊盘),必须做这个,否则焊点必然出现大气泡。
- 散热焊盘过孔:QFN 底部散热盘下的过孔如果不塞,回流焊时孔内空气受热冲出来,会在焊点中央形成大空洞(”吹孔”),热阻和可靠性双输。小孔 + 塞孔 + 阵列是标准答案。
顺带一句:板子受潮后再过回流焊,水汽也会从过孔/层间冒出,形成分层。老办法是焊前 120°C 烘板 4 小时,这个习惯在厚板上还是值得保留。
定位手段:TDR、近场探头,和固件侧的误码计数
硬件侧三件套:
- TDR(时域反射)看换层处的阻抗曲线。 过孔在 TDR 上是一个明显的低阻凹陷(1.6mm 板约 34~48Ω 对 50Ω 走线)。如果凹陷的深度异常深,或者凹陷后面跟着周期性波纹(说明有谐振),那就是过孔/残桩问题。TDR 的空间分辨率要够,边沿最好 <35ps。
- 近场探头扫换层点。 上面说过的 12mm 环路,在近场探头下就是一个清晰的热点。探头贴着板子慢慢扫,热点位置基本就是返回路径最差的地方。配合频谱仪看频点,能直接对上辐射测试超标的那个频点。
- 从谐振频率反推残桩长度。 如果 TDR/网分测到了明确的谐振凹陷,残桩长度可以直接反解:
# 从测到的 λ/4 谐振凹陷反推残桩长度,判断是否值得背钻
# 前提:残桩等效为一段开路细线,λ/4 处呈现串联谐振(阻抗凹陷)
V_MM_NS = 299.792 / (4.3 ** 0.5) # FR-4 中约 144.6 mm/ns
def stub_len_from_resonance(f_ghz):
t_pd_ps = 1e3 / (4.0 * f_ghz) # 1/(4f),单位 ps
return t_pd_ps * V_MM_NS / 1e3 # mm
for f in (4.0, 8.0, 12.5, 20.0):
print("%5.1f GHz -> 残桩约 %6.2f mm" % (f, stub_len_from_resonance(f)))
4.0 GHz -> 残桩约 9.04 mm
8.0 GHz -> 残桩约 4.52 mm
12.5 GHz -> 残桩约 2.89 mm
20.0 GHz -> 残桩约 1.81 mm
测到谐振在 12.5GHz 才值得考虑背钻;如果谐振点在 4GHz 以下,说明残桩接近 9mm —— 那已经不是过孔的事了,得先怀疑量测夹具。
固件侧:把”偶发”变成”可统计”。
这可能是这篇里最实用的一条。硬件偶发故障最难的地方是抓不到——你到现场,它好了。所以固件必须长期记账,让故障自己浮出来。
/* link_health.c —— 把"偶发"变成"可统计"
* 纪律:零动态内存;不用 %f(newlib-nano 的 %f 内部会走 malloc,
* 且 Release 版关掉 nanoprintffloat 时会静默输出空串)。
*/
#include <stdint.h>
#include <stdio.h>
typedef struct {
uint32_t enumerate_ok; /* USB 枚举成功 */
uint32_t enumerate_fail; /* USB 枚举失败(超时/STALL) */
uint32_t reconnect; /* 链路掉线重连 —— 重点盯这个 */
uint32_t eth_crc_err; /* 以太网 CRC 错误帧 */
uint32_t eth_sym_err; /* 符号错误(物理层质量) */
uint32_t eth_drop; /* 接收溢出/丢弃 */
uint32_t phy_speed_mbps; /* 当前协商速率 */
uint32_t last_fault_ms; /* 最近一次故障时间戳 */
} link_health_t;
static link_health_t g_lh;
/* 误码率用 ppm 表示:全程整数运算,不碰浮点 */
static uint32_t ppm_u32(uint32_t err, uint32_t total)
{
if (total == 0u) return 0u;
return (uint32_t)(((uint64_t)err * 1000000ull) / (uint64_t)total);
}
/* 一次性组帧上报,无动态分配、无 %f */
int link_health_json(char *out, size_t out_sz, uint32_t frames_total)
{
uint32_t err = g_lh.eth_crc_err + g_lh.eth_sym_err;
return snprintf(out, out_sz,
"{\"usb\":{\"ok\":%lu,\"fail\":%lu,\"reconn\":%lu},"
"\"eth\":{\"crc\":%lu,\"sym\":%lu,\"drop\":%lu,\"ppm\":%lu},"
"\"phy_mbps\":%lu,\"last_fault_ms\":%lu}",
(unsigned long)g_lh.enumerate_ok, (unsigned long)g_lh.enumerate_fail,
(unsigned long)g_lh.reconnect,
(unsigned long)g_lh.eth_crc_err, (unsigned long)g_lh.eth_sym_err,
(unsigned long)g_lh.eth_drop, (unsigned long)ppm_u32(err, frames_total),
(unsigned long)g_lh.phy_speed_mbps, (unsigned long)g_lh.last_fault_ms);
}
运维侧的判读规则,我们后来固定成了三条:
reconnect与phy_mbps同时异常(掉线且降速)→ 物理层嫌疑大:过孔、回流、连接器接触。crc/sym随温度漂移 → 阻抗不连续或训练余量不足,优先查换层点和连接器扇出区。enumerate_fail与上电时序强相关(每次都是冷机)→ 先查复位和供电,别赖过孔。
这三条把”玄学偶发”变成了”有指向的数据”。那块网关板改版前的统计是:reconnect 在 30 台里累计 47 次,且全部集中在 3 台机器上 —— 定位范围一下就缩到了那 3 台的板子上,直接指向焊接/工艺一致性,而不是设计。
配套小工具
所有数字都能用脚本复现,也方便评审时对着自己的叠层勾一遍:
# 过孔本体:电感 / 电容 / 等效阻抗 / LC 谐振
python via_z0.py via --h 1.6 --drill 0.3 --pad 0.6 --antipad 0.8
# 残桩电长度与"需处理的上升时间门槛"
python via_z0.py stub --len 1.1 --tr 150
# 反焊盘扫描
python via_z0.py antipad --h 1.6 --drill 0.3 --pad 0.6
# 返回路径:信号孔到地孔的距离 vs 回路电感
python via_z0.py loop --h 1.6 --drill 0.3 --s 3.0
# 板厚/孔径扫描
python via_z0.py table --h 1.6
# 单孔载流估算
python via_z0.py current --drill 0.3 --plate 25
脚本在 drafts/_tools/via_z0.py,公式为 Johnson/Graham 经典近似式(±20~30% 量级),够选型和评审,量产请以场求解或实测为准。全程定点输出、不依赖 %f,同类算法可以直接搬到 MCU 侧做板级自检计算。
落地清单(12 项)
- ☐ 每一处换层都检查:参考平面有没有变?变了就必须有就近缝合过孔
- ☐ 换层过孔周围 1~2mm 内必须有地过孔;越靠板边、速率越高,要求越严
- ☐ 参考平面 GND→PWR 换层时,换层点旁放了就近去耦电容,且电容的过孔也紧贴
- ☐ 反焊盘直径定成焊盘 + 0.20~0.25mm,在加工说明里明确标注,不接受板厂默认
- ☐ 加工说明写了 “内层非功能焊盘全部删除(Remove NFP)”
- ☐ 残桩先算电长度再谈工艺:t_pd < t_r/6 就放过它
- ☐ 只有 2.4mm 以上厚板 + MIPI/PCIe/10G 才考虑盲埋孔或背钻
- ☐ 差分对过孔布局镜像对称;地过孔放两颗信号孔的外侧,不要塞中间
- ☐ 差分对过孔的反焊盘没有在平面上连成长条开槽;有就补缝合过孔
- ☐ 电源过孔按孔阵列设计(≥3×3,间距 ≥1mm),>2A 做温升实测
- ☐ QFN/BGA 散热焊盘下的过孔必须塞孔或填铜磨平(POFV),防焊接空洞
- ☐ 固件里有链路错误计数器(掉线次数/CRC/协商速率)并周期上报
相关阅读
- 阻抗控制与叠层设计实战:同一块板上 0.2mm 的线,走外层 66Ω、走内层 39Ω
- 信号完整性与串阻源端匹配实战:一条 25MHz 时钟线上的振铃
- SDRAM 布线等长与反射实战:一块板子在高温下”隔几个字节就错”
- PCB 布局与 EMC 实战:一次辐射超标 8dB 的整改记
下一篇换个赛道,讲电池管理、电量计与 SOC 估算:为什么”电压查表法”在磷酸铁锂上能把剩余电量估到差 30%,以及库仑计、OCV 修正、内阻补偿这三件事该怎么落地。