做汽车电子或工业现场总线的同学,应该都撞见过这种怪事:波特率对得好好的,终端电阻测过是60Ω,线束长度也不算离谱,可节点一联网就冒出错误帧,单机测试却一切正常。换台设备、换块板子问题还复现。排查到最后,十有八九是采样点(Sample Point)这个参数在捣鬼。
这篇就绕着“采样点是啥、怎么算、怎么测、坏了怎么抓”四条线,把我这几年在CAN/CAN FD总线上实测的经验和踩过的坑摊开聊。适合刚接触总线的嵌入式工程师,也适合正在做车载网络测试、CAN一致性测试的老手。只要你有过被偶发错误帧折磨到深夜的经历,这文章就值得看完。
1. 采样点原理:一个位到底在哪儿“取数”,决定了通信生死
1.1 位时间结构:一个“比特”内部还有分段
CAN和CAN FD的每一个位,不是简单地发送高或低电平就结束了。在控制器内部,一个位时间会被切成四段:同步段(SYNC_SEG)、传播段(PROP_SEG)、相位缓冲段1(PHASE_SEG1)和相位缓冲段2(PHASE_SEG2)。接收节点会在一个非常精确的时间点去读取总线电平,这个点就是采样点,它通常位于PHASE_SEG1结束、PHASE_SEG2开始的那个时刻。
每段都有各自的任务。同步段固定占用一个时间量子(TQ),用来处理总线边沿跳变,收发双方靠它对齐节奏;传播段用来补偿信号在总线上的延迟——线缆有长度,收发器有响应时间,信号不可能瞬间到对面再回来,这段时间必须留出来;相位缓冲段1和相位缓冲段2则是用来吸收振荡器偏差和干扰导致的相位误差,左右各留一段缓冲,采样点就夹在两者中间。
这有点像打羽毛球:对方击球后球要飞一会儿才过网,你提前站好位置、举拍等着,在球落到最佳击球点的那个瞬间挥拍。击球点太早或太晚,球都会打飞。总线采样也是同样的道理。
1.2 采样点选错位置会怎样
如果采样点设得太靠前,总线电平可能还处于信号边沿附近的暂态区。CAN总线上的显性位和隐性位切换时,电平不会瞬间跳变,而是一个有上升沿、下降沿的过渡过程。线缆长、节点多、寄生电容大的时候,边沿会被拉得更缓。在这个窗口内采样,读到的电平可能既不是1也不是0,接收器就会报位错误,触发错误帧。
采样点设得太靠后同样麻烦。一个位时间结束前,下一个位的边沿可能已经悄悄到来。尤其在连续相同位之后出现一个翻转位,信号刚刚有个“苗头”,你在这个临界点采样,很容易把下一位的状态提前读进来。按CAN的机制,接收节点检测到电平与期望不符时,会发错误帧,要求发送方重传。表现就是总线错误计数器蹭蹭上涨,严重的直接Bus Off。
需要注意,采样点不是“越居中越好”。对于传统CAN,业内普遍推荐的区间是75%到87.5%之间。为什么偏后而不是居中?因为接收节点要等发送节点传过来的信号经历完整线缆延迟和收发器延迟后,再结合自己的时钟去采样。信号到达得本来就晚,采样点如果太靠前,根本没等到对方电平稳定就已经取了数。
1.3 CAN FD 对采样点更苛刻
CAN FD相比经典CAN,变化最大的就是数据段速率更高。经典CAN最高1Mbit/s,CAN FD数据段可以到2Mbit/s、5Mbit/s,甚至8Mbit/s。位时间越短,物理延迟对采样窗口的压缩就越明显。比如8Mbit/s下,一个位只有125ns,而一个普通高速CAN收发器的TXD到RXD环回延迟往往就有150ns到250ns。也就是说,信号绕一圈回来,比你一个位的时间还长。这种时候,采样点在数据段就不能按老CAN的习惯来设。
实际工程中,CAN FD通常分两段配置采样点:仲裁段沿用CAN的策略,75%到80%左右,因为仲裁段速率低,还要兼顾同网络里老节点的兼容;数据段则建议安排在85%到90%左右,给高速位流留出足够裕量。很多现代控制器(比如带M_CAN内核的MCU)允许仲裁段和数据段分开配置TQ参数,这就是为FD准备的。老一代只支持CAN的控制器没这个能力,跑FD自然就吃力了。
2. 采样点怎么算:公式、实例与常见误区
2.1 采样点计算公式:一页纸讲清楚
现在看采样点公式,先给定义:
采样点百分比 = (SYNC_SEG + PROP_SEG + PHASE_SEG1) / 位时间总TQ数
注意,很多MCU的寄存器里不单独分PROP_SEG和PHASE_SEG1,而是合并成一个TSEG1。这时候公式就简化为:
采样点百分比 = (SYNC_SEG + TSEG1) / (SYNC_SEG + TSEG1 + TSEG2)
其中SYNC_SEG固定等于1个TQ。TSEG1是传播段与相位缓冲段1之和,TSEG2就是相位缓冲段2。
举一个实际算例。某项目用40MHz系统时钟,目标波特率500kbps,取BRP=4,则TQ = 4 / 40MHz = 100ns。一个位时间2000ns,分成20个TQ。若想采样点落在75%,则SYNC_SEG=1,TSEG1=14,TSEG2=5,计算:(1+14)/20 = 75%,成立。寄存器里TSEG1写14,TSEG2写5,完事。
但如果你随手配成TSEG1=10,TSEG2=9,采样点就是11/20=55%,这个值在实际网络中必然出问题。我有一次在客户现场排查丢帧,读出来的TSEG1/TSEG2正是这种“随手配置”,问就是“默认值没改过”。默认值真不一定能用。
2.2 传播段的工程估算方法
很多人只关注采样点公式,却忽略了一个关键前提:传播段到底该留多少个TQ?传播段是用来覆盖物理层延迟的,包括三部分:
- 线缆传播延迟。双绞线信号传播速度约为光速的0.65到0.7倍,换算下来大概每米5到7ns。这个数字看着小,但总线动不动十几米,乘上2(发送到接收是单程,但收发双方都需要经过总线,工程上常按往返估算),就得翻倍。
- 收发器延迟。从TXD输入到RXD输出,一个完整环回少说100多ns,高速FD收发器可能超过200ns。这是延迟的大头,也是最容易被忽略的部分。
- 节点内部逻辑延迟。MCU内部滤波、比较器建立时间,一般几十纳秒到上百纳秒,取决于芯片设计。
工程估算公式可以写成:
总传播延迟 ≈ 2 × (线缆长度 × 5~7ns/m) + 2 × 收发器环回延迟
举个例子,总线长度10m,收发器环回延迟按200ns算:
总延迟 ≈ 2 × 10 × 6ns + 2 × 200ns = 120ns + 400ns = 520ns
在500kbps下,一个位是2000ns,520ns的延迟意味着采样点前至少要留出26%的位时间来等信号稳定。如果你设计采样点85%,前面留给“信号到达+稳定”的窗口大约是位时间的(85%-边沿建立时间)比例,算下来是够的。但如果总线长度拉到40m,延迟变成2×40×6+400=880ns,接近半个位时间,采样点就算设在87%,信号稳定区也只剩不到380ns,裕量很悬。这就是为什么长线缆必须重新算,不能拿着短线的参数直接上。
2.3 时间量子分配:TQ数量直接限制你的调整精度
还有一个常见的坑:位时间总TQ数太少,导致采样点只能粗调。
还是用40MHz时钟算账。如果BRP=1,TQ=25ns。跑1Mbps时位时间1000ns,只有40个TQ,采样点能以2.5%的步进调整,还算灵活。但跑8Mbps FD时位时间125ns,只有5个TQ,想调出85%的采样点?5×0.85=4.25,只能取4或5,实际采样点要么80%要么100%,根本没法精准落在目标上。这不是算法问题,是TQ数不够,物理上就没法细调。
所以做CAN FD高速配置时,一个基本原则是:数据段位时间内的TQ数一般不能少于8个,太少的话采样点位置和SJW配置都会受限。有些控制器允许少到4个,那是极限,工程上别轻易碰。
下表是几种典型配置的采样点对照,方便快速验算:
| SYNC_SEG | TSEG1 | TSEG2 | 总TQ | 采样点 | 是否适合CAN |
|---|---|---|---|---|---|
| 1 | 8 | 7 | 16 | 56.3% | 否,太早 |
| 1 | 10 | 5 | 16 | 68.8% | 偏早,短总线勉强 |
| 1 | 14 | 5 | 20 | 75.0% | 推荐,经典值 |
| 1 | 15 | 4 | 20 | 80.0% | 推荐,常见 |
| 1 | 13 | 2 | 16 | 87.5% | 可用,接近上限 |
表格里“是否适合”只针对常规工业和车载短线场景。如果你的系统是收发器延迟极小、线缆极短的板级通信,68.8%也能跑,但抗干扰能力和兼容性会差,市场上的ECU不一定会买账。
3. 采样点测试实操:从示波器到一致性测试
3.1 工具选择与接线:测试第一步就决定可信度
测采样点,工具选型和接线方式决定了数据的可信度。最基础的是数字示波器,建议带宽至少100MHz,采样率至少1GS/s。带宽不够,边沿都测不准,后面全是白做。探头方面,强烈建议用差分探头,因为CAN信号是CAN_H和CAN_L之间的差分电压,用两个普通探头分别测然后相减,寄生电容和共模噪声会污染波形,测低速CAN还行,测CAN FD的高速位流会得到一堆假边沿。
如果手里只有普通探头,也要把两个探头的地线夹尽量短,并保证两个通道的垂直刻度、水平刻度完全一致,再通过示波器的数学运算做差分。但这种方法只适合验证,不适合出正式报告。
更专业的做法是用CAN总线一致性测试工具,比如CANscope、CANoe的一致性测试包,或者带CAN触发的示波器。这些工具能直接解码CAN报文,显示ID、数据场,还能自动标注位时间和采样点的理论位置。测起来效率比纯手动高一个量级。
接线有个容易被忽略的点:探头的测量点要尽量靠近被测节点的CAN收发器引脚,而不是在连接器处。因为连接器到收发器之间的PCB走线、TVS管结电容都会影响信号边沿,你量到的可能是“板级噪声”,不是真实总线信号。量产节点测试,我都是直接在收发器的CANH/CANL引脚上飞线出来测。
3.2 手动测量法:一把示波器推算采样点位置
没有专用工具的时候,手动测采样点也能获得有用结果。步骤如下:
首先,配置被测节点为循环发送模式,不断向总线发送固定报文。示波器差分通道接好CAN_H和CAN_L,触发模式设为下降沿触发。CAN的显性位对应差分电压约2V,隐性位约0V,显性到隐性的跳变是下降沿,用它触发能看到完整的位流。
其次,打开示波器的解码功能。直接用波形解出波特率,让示波器自己识别位时间。如果示波器支持CAN解码,它会用带色块的方格把一个一个位标出来,采样点位置也能覆盖显示。这一步是验证你的物理层波形是否与协议层对齐的关键。
第三,测量显性位宽度。用光标卡住一个显性位前后的两个下降沿,读出位时间。多抓几个位求平均,降低抖动误差。将这个位时间乘以你的目标采样点百分比,在波形的对应位置放一条光标线。观察这条线所在位置的波形是否平坦——如果光标落在边沿附近而不是稳定的高电平或低电平区域,说明采样点裕量不足。
最后,再做一次极限测试。用示波器的“余辉”模式,把波形叠加几百次,观察边沿的抖动范围。如果抖动导致某个位的边沿漂移到了采样时刻附近,这个系统的时序裕量基本告急。实测中,边沿抖动超过位时间的10%,就建议回查晶振质量和收发器驱动能力。
3.3 专用工具测试法:直接测出采样点的实际边界
手动测只能看到“配置的采样点在哪里”,测不出“实际能容忍采样点偏移多少”。真正有工程价值的是边界测试——也就是把接收端的采样点向左向右逼,逼到出错为止,那个临界点就是实际采样点位置的近似。
用CANscope一类的工具做这个测试很直接。让被测节点正常收发,测试工具作为总线上的干扰源,发送一个相对于被测节点时钟有一定相位偏移的帧。偏移量从0开始逐步增大,观察被测节点是否出现错误帧。错误出现的那一刻,说明干扰边沿已经越过采样点的稳定窗口,两者的差值就是采样点裕量。
更系统的方法是先测发送节点,再测接收节点。测发送节点时,干扰工具充当接收方,记录它对偏移的容忍能力;测接收节点时,干扰工具充当发送方,给被测节点喂偏移帧,记录它能正常接收的偏移范围。把两个方向的结果一拼,就得到整个链路在采样点维度上的时序窗口。
CAN FD做这个测试时,仲裁段和数据段要分开测。有些工具支持在报文的仲裁段保持标准速率,进数据段切换到不同位速率,此时要针对数据段的采样点做专门的偏移注入,不能拿仲裁段的结果代替。
3.4 干扰注入与相位裕量测试:贴近真实场景的试金石
干扰注入测试比单纯看波形更贴近实际。市面上有CAN总线干扰设备,比如CANstress这类,能在正常报文里插入短至几十纳秒的毛刺,或者把一个位的边沿往前、往后挪动特定的量。测试思路是这样的:
先让DUT与干扰工具正常通信,建立稳定基线,记录错误帧率。然后逐步加大干扰强度——把边沿往前挪1个TQ、2个TQ,或者调整毛刺的宽度。每加一档,观察DUT的错误计数器变化和丢帧情况。直到DUT出现错误帧或者恢复不了通信时,当前干扰量减去典型干扰量,就是它的采样点裕量。
这个测试的价值在于:示波器只能告诉你“静态的采样点设在哪里”,干扰注入能告诉你“动态情况下系统还能不能扛住”。我做过一个很有意思的对比:两块硬件设计几乎一样的板子,一块采样点设75%,干扰容限有±6个TQ;另一块设85%,看着更靠后,但因为相位缓冲段2只有2个TQ,为了同步跳变,SJW被压缩得很小,实际干扰容限只有±3个TQ。这说明,好配置不是单一采样点数值决定的,而是采样点、SJW、TSEG2三者的组合结果。
判断合格的标准,业界一般要求至少能容忍±2个TQ的偏移而不产生错误帧。如果项目对EMC要求高,比如过ISO 11452-4大电流注入(BCI)测试,建议放宽到±4个TQ,否则实际跑测试时总会有一两个极端频率点触发错误帧。
4. 常见通信问题与调试心得
4.1 典型故障现象速查表
调试现场遇到的大部分通信问题,都能从现象反推原因。下面这张表是我整理的排查速查表:
| 故障现象 | 可能原因 | 排查方向 |
|---|---|---|
| 单节点正常,多节点联调丢帧 | 采样点靠前,边沿未稳定就采样,或不同节点采样点偏差过大 | 读各节点TSEG配置,统一采样点 |
| 错误计数器反复增减,偶发Bus Off | 采样点靠后,接近下一位边沿,同步条件恶化 | 缩短相位段2,或后移采样点但保留足够SJW |
| 线缆加长后通信失败 | 传播段预留不足,线缆延迟吃掉稳定窗口 | 按总线长度重算传播段,增大TSEG1 |
| 高温或低电压下偶发错误帧 | 收发器延迟变化,振荡器漂移增大,采样裕量不足 | 复测常温下边界,留出温度余量 |
| 上电后首帧就错误,随后恢复 | 同步段和SJW配合差,初始同步能力弱 | 增大SJW,检查BRP配置 |
| FD通信仲裁段正常,数据段乱码 | 数据段采样点偏早或偏晚,TQ数太少 | 数据段单独配置85%附近采样点 |
4.2 多节点混用场景下的采样点协调
真实车载或工业总线网络,几乎不会所有节点用同一颗芯片。不同MCU内部时钟精度不同,不同收发器的延迟特性也不同,甚至线束分支长度都不一致。这种混合场景下,“每个节点独立最优”不如“全网协调一致”来得重要。
比如A节点振荡器容差±0.3%,B节点±0.2%,收发器延迟差50ns,线束长度差3m。各节点都按自身参数校到最优采样点,彼此间反而可能错开太大,导致任何一边同步时另一边跟不上。最稳妥的做法是:全网按最差节点的参数统一配置。线缆最长的那个节点,它的传播段需求就是全网基准;收发器延迟最大的那个节点,它的采样点边界就是全网边界。别让好节点迁就坏节点,但也不能让坏节点拖垮全网,取中庸偏保守的值,牺牲一点点单点优化,换来全网的稳定。
我见过一个项目,因为两个ECU用了不同批次的晶振,初始偏差差了一倍,低速CAN死活不出问题,一上CAN FD数据段就丢帧。最后就是统一采样点、增大SJW解决。
4.3 经验与避坑指南:几条拿实测换来的心得
测试时千万别用默认配置代表“调好了”。很多控制器上电复位后的TSEG1/TSEG2默认值,只是为了芯片能自测,并不是给真实总线用的。凡是出过问题的节点,第一步就是读寄存器实际值,而不是问“你配了多少”,因为很多人答不上来。
测采样点时,不要只看单次波形。采样点的稳定性本质上是个统计问题:连续抓一屏波形,用余辉模式看边沿分布,重复上百次触发,确认采样点所在的区域始终是“干净”的。只看一两个位就下结论,很容易漏掉偶发性抖动。
还有个容易栽的坑:三次采样模式。某些控制器提供单次采样和三次采样两种模式,三次采样是对采样点前后各取一次,再做多数表决,目的是抗毛刺。听起来很美,但它有个副作用:相当于把实际采样时刻往后挪了几个TQ,因为多数表决需要等待后两次采样数据。这会让有效采样点比你配置的值偏后。如果你在三次采样模式下把采样点配到85%,实际等效可能接近87%甚至更高。设计时要把这个隐藏偏移算进去。
最后说一个关于CAN FD数据段的经验,数据段采样点往85%以上调,直观上越靠后给信号稳定留的时间越长,但别忘了相位缓冲段2还在采样点后面。如果TQ总数固定,采样点越靠后,PHASE_SEG2就越短,接收节点能用来吸收下一拍边沿误差的空间就越小。这个矛盾没法两头占,只能在中间找平衡。我试过的组合里,总TQ数20、数据段采样点87.5%配SJW=4,综合表现最稳。当然每套系统芯片不同,值也不一样,但思路是一致的——代价均衡,别走极端。
采样点这东西,看着是个寄存器参数,实际上牵动的是物理层延迟、时钟精度、协议层重传机制,一整条链路。算好它,测准它,车载网络里一半的偶发通信故障都能在台架上提前揪出来,而不是等整车路试了才暴露。真到了路试阶段再来查采样点,那才叫一个痛苦。