做汽车电子或者嵌入式通信的兄弟,十有八九都遇到过这种怪事:两边的CAN配置看着一模一样,波特率都写对了,ID也设好了,但就是通信不稳定,线束一改或者气温一高,错误帧就冒出来。查了半天寄存器,最后才发现是采样点位置不对。这个藏在位时间寄存器里的参数,平时没人注意,可一旦出问题,排查成本比想象中高得多。这篇文章就把采样点这个事情彻底讲透——它是什么、怎么算、怎么配、用什么方法测、实际项目里踩过哪些坑。搞懂这一个点,至少能少熬几个查CAN通信故障的夜。
1. 先搞清楚采样点是什么,以及它为什么重要
1.1 一位CAN数据是怎么被"切"成四段的
CAN总线上传输的每个位,物理上都是一段时间的长度。比如500kbps的波特率下,一个位的时间就是2微秒。千万别小看这2微秒,为了能让多个节点在一条总线上稳定通信,CAN控制器硬是把一个位的时间细分成了四段:
- 同步段(SYNC_SEG):固定为1个时间量子(TQ),负责让各个节点找到位的边界,总线上的下降沿/上升沿就是在这里被对齐的。
- 传播段(PROP_SEG):用来补偿信号在总线上往返传输的物理延迟,以及收发器内部电路带来的延时。总线越长,这段就需要越长。
- 相位缓冲段1(PHASE_SEG1):采样点之前的一段缓冲,可以在重同步时被拉长。
- 相位缓冲段2(PHASE_SEG2):采样点之后的一段缓冲,可以在重同步时被缩短。
所谓采样点,就是控制器实际读取总线电平的那个时刻。在CAN的位时间模型里,它位于相位缓冲段1结束、相位缓冲段2开始的交界处。换句话说,一个位被分成两大部分:采样点之前的部分占比多少,采样点就落在百分之多少。
拿日常生活中的事情打个比方:采样点就像拍全班合影时按下快门的那个瞬间。按早了,同学还没走到位置,画面里全是人影晃动;按晚了,队形已经开始散掉,拍出来模糊。CAN控制器干的事情比这个还严苛,它不管画面糊不糊,只知道在那个固定瞬间去读总线上是高电平还是低电平,这一位读成0还是1,从此再无反悔。
1.2 采样点放太前或太后会怎样
采样点并不是随便定的,它决定了整个网络对相位误差、传输延迟和晶振偏差的容忍能力。
如果采样点放得太靠前,比如不到60%,那么当总线上的信号边沿由于传输延迟、线缆反射、寄生电容等原因还没有稳定下来时,控制器就已经采样了。这时候读到的电平可能是瞬态毛刺,也可能是上一位的残留,极容易产生误码。
如果采样点放得太靠后,比如超过90%,问题就出在相位缓冲段2太短。相位缓冲段2在重同步机制中承担"缩短位时间"的职责。当某个节点的位时钟比其他节点稍微快了一点点,硬同步或者重同步要靠缩短相位缓冲段2来补偿。如果这段太短,控制器就没有余量去修正偏差。结果就是:时钟稍微飘一下,采样点就踩到了下一个位的边沿上。
所以业内普遍推荐的采样点范围是75%到87.5%。带过载波、重同步能力强的网络可以放宽到70%上下,追求长距离传输稳定性的网络则偏好85%以上。这些数值不是拍脑袋定的,背后都是对传播延迟、晶振精度、重同步能力的权衡。
2. 采样点怎么算,寄存器怎么配
2.1 通用公式和不同控制器的寄存器差异
采样点的计算公式,在所有CAN控制器芯片上都一样。先弄清一个概念:时间量子TQ。这是CAN控制器内部一个极短的时间单位,由CAN外设时钟经过预分频得到。一个位时间由若干个TQ组成,而这个TQ数量必须在配置时算好。
通用的采样点计算公式是:
采样点(%) = (SYNC_SEG + TSEG1) / (SYNC_SEG + TSEG1 + TSEG2) × 100%其中SYNC_SEG固定为1个TQ,TSEG1是传播段和相位缓冲段1合并后的长度,TSEG2就是相位缓冲段2。
这里有个特别让人头疼的地方:不同芯片厂商对寄存器的命名和定义不一样。同样一个概念,ST叫TS1/TS2,NXP叫PSEG1/PSEG2,Microchip叫SEG1/SEG2,英飞凌更复杂,分成了NBTP和DBTP两套寄存器。这直接导致同一个采样点百分比,在不同芯片上配出来的寄存器值完全不一样。
更麻烦的是,写寄存器的时候,不少芯片还要做减一操作。比如STM32的bxCAN,寄存器里存的数值是实际TQ数减1的结果:TS1[3:0]写5,实际相位缓冲段1是6个TQ。很多人配置失败,就是忘记了这个减一,把采样点算得跟自己预期差了十万八千里。
2.2 实际计算:从需求到寄存器值
拿一个最常见的需求来算一遍:STM32F4系列,APB1外设时钟42MHz,要求CAN波特率500kbps,目标采样点约80%。
先确定每个位需要多少个TQ。42MHz除以500kbps,得到84。也就是说,如果不做预分频,一个位要占84个TQ。但STM32的bxCAN一个位最多只能有25个TQ(3到25),84远超标了。所以必须预分频。
取预分频系数4,CAN外设时钟变成10.5MHz,一个位占21个TQ。设采样点前(含SYNC段)需要的TQ数为X,那么采样点就是X除以21。80%的话X大概16.8,取整后要么16要么17。取17,即采样点81%:TSEG1要占16个TQ(因为SYNC段占了1个),TSEG2占4个TQ。对应到STM32寄存器,TS1[3:0]要写15(因为要减一),TS2[2:0]要写3。
这里注意了:STM32这种老牌CAN控制器,TSEG1最大只能到16个TQ,所以在这个预分频条件下,采样点顶多配到17/21=81%。想配87.5%?那就得换个预分频方案,让每个位占更多TQ,比如让每个位占32个TQ,采样点前28个TQ,刚好87.5%。可惜STM32的bxCAN单个位最多25TQ的限制又卡死了。这就是为什么在很多用STM32的老项目里,采样点普遍是80%而非87.5%——不是不想配,是硬件结构限制了。
2.3 常见场景采样点参考表
为了不让你在项目里踩坑,我把几个典型场景的推荐采样点整理成表,直接照着用:
| 应用场景 | 推荐采样点 | 说明 |
|---|---|---|
| 车内短距离模块互联,线束小于3米 | 75%~80% | 传输延迟小,更看重重同步能力 |
| 常规车身网络,线束5~10米 | 80%~85% | 平衡传播延迟和同步余量 |
| 长距离总线,线束超过10米 | 85%~87.5% | 采样点靠后,给信号充分稳定时间 |
| CAN FD仲裁段(速率较低段) | 80%~87.5% | 对应CAN FD方法,仲裁段兼容CAN |
| CAN FD数据段(高速段) | 75%~80% | 速率越高越要偏早,保证相位余量 |
这个表的逻辑其实很简单:总线越短,采样点可以偏早,留出更多相位缓冲段2吸收时钟偏差;总线越长,采样点必须偏晚,否则远端节点发过来的信号还没稳定到采样点就已经开始采样了。
3. 采样点测试:三种方法由浅入深
采样点光靠算还不够,因为配置值只是纸面上的,实际总线上受晶振精度、PCB寄生参数、线缆长度、环境温度的影响,真正发生的采样位置会有偏移。所以测试是必须的。测采样点的方法,从最基础的到最严格的,我按顺序讲。
3.1 最基础:静态核对寄存器采样点
最不用动设备的方法,就是把各节点的CAN位时间寄存器读出来,手动算一遍采样点,确认它是不是和设计值一致。这个方法看似笨,其实最实用。很多所谓"通信不稳定"的项目,第一轮排查就发现某个节点的采样点被配到了65%甚至50%,原因往往是某位工程师照搬了另一个项目的初始化代码,而那个项目的时钟和波特率跟当前项目根本不一样。
读寄存器也有讲究。如果是量产ECU,没法直接连调试器,可以借助CAN诊断服务去读应用层上报的配置参数,或者读内存。如果是自己开发的板子,直接开调试器看寄存器最方便。注意芯片手册里寄存器是"实际TQ值减1"还是直接存储的原始TQ值,别算错。这一步的价值在于排除低级人为错误,省下的时间够你喝半壶茶。
3.2 实战常用:示波器抓波形做粗略评估
静态核对只能证明配置对了,不能证明物理层真的稳定。示波器是进阶手段。
先准备设备:100MHz以上带宽的数字示波器,配差分探头最好;没有差分探头就用两个普通探头分别接CAN_H和CAN_L,然后用示波器的数学通道做减法,得到差分波形。触发方式选下降沿触发,因为CAN帧的起始位SOF是显性位(低电平),从隐性到显性的边沿非常干净,适合做触发点。
接线后,用CAN工具或者直接让ECU周期发报文,示波器调到余辉显示模式或无限余辉,把上百帧波形叠加起来。这就是所谓的"眼图"观察法。正常情况下,每个位的边沿位置高度重合,波形中间会形成一块明显的"眼睛"。这块眼睛越宽、越清晰,说明采样点的余量越大。如果眼睛变窄、边沿抖动明显、甚至看到回冲和振铃,那采样点就悬了。
具体怎么判断采样点位置是否合适?在示波器上把时基调到刚好显示一个完整位的时间,比如500kbps时设200ns/格,找到位时间的中心点。前面讲过,普通推荐值是75%~87.5%,所以采样点大约在位宽度靠后三分之一处。看这个位置的电平是否已经稳定、波形是否平滑。如果在这个位置还能看到明显的振铃边沿,说明采样点偏早了,可能会采到毛刺。
3.3 进一步:带采样点统计功能的工具
示波器只能给个大概印象,真要量化采样点,得上带采样点测量功能的CAN工具。
市面上主流的高端CAN分析仪,比如Vector的CANoe配合特定接口硬件,软件里有一个采样点测量功能:硬件以极高的采样率对总线电平做过采样,软件通过分析边沿位置与理想位边界的差异,统计出每个位的实际采样位置,然后把结果画成直方图或者分布图。从这个分布图能直接读出采样点的均值和抖动范围。
用这类工具测采样点的时候,有个关键步骤:工具本身也要配置成和你目标网络相同的波特率。否则工具解码出来的位边界位置都是错的,后面的统计就没意义了。上位机软件里一般会显示每次测量的样本量,建议测到上千个位再做结论,别拿几个位就当真理。
国产分析仪里也有部分支持类似功能,便宜的USB-CAN盒子做到这个级别的少,多半要配支持FD的高速硬件。我的建议是:项目预算允许的情况下,直接上一套支持采样点测量的工具,平时排查故障、做供应商一致性验收都会用到,这笔钱花得不亏。
3.4 一致性做法:边界扫描测接收窗口
示波器和统计工具测的是"发送端到接收端这条链路"的综合表现,但汽车电子测试中经常需要单独评价某个节点(DUT)的采样点余量。这时要用边界扫描法。
边界扫描法的思路很简单:测试设备(比如CANoe)自己的位时间参数可以精确微调。设备先按标准位时间(比如87.5%)向DUT发CAN帧,确认通信正常。然后逐步降低发送端的采样点百分比(其实是把TSEG1缩短、TSEG2拉长),每改一个数值发一帧,观察DUT是否还能正确应答。持续往这个方向扫描,直到DUT开始不回ACK或者报错,这个临界点就是DUT接收能力的下限。
再用同样的方法向另一个方向扫描,把发送端采样点百分比逐步提高,找上限。这样扫出来的完整范围,就是DUT的采样点接收窗口。窗口越大,说明DUT的采样点余量越充足;窗口窄得只有两三个百分点,那它离故障爆发就只有一步之遥。
这个方法在整车厂对供应商的一致性测试中很常见。测试报告里会明确要求DUT的采样点窗口必须覆盖某个区间,比如70%~90%。你如果有供应商不配合调采样点,直接把这份扫描报告甩给对方,比扯半天嘴皮子管用得多。
4. 采样点不对引发的典型故障与排查思路
4.1 三个真实场景
先说第一个场景:两个控制器单独和总线上的其他设备通信都正常,但互相收发数据时频繁丢帧。查了很久的ID滤波和数据字节序,最后发现A节点的采样点是70%,B节点是87.5%。单独看,每个节点都能工作,但两个节点在相位容限上差异太大,在总线噪声比较大的时候,一个节点用70%采样点采到了边沿附近的毛刺,产生错误帧,把整条总线带乱了。
第二个场景:设备在台架上测试没问题,装到整车上线束加长之后就不断冒错误帧。用示波器一测,发现远端节点的波形边沿已经明显变缓,到达接收节点时比原来晚了将近半个位时间。原配置还守着75%的采样点,正好踩在边沿附近。把采样点调到85%之后,问题消失。这就是典型的传播延迟和采样点位置不匹配。
第三个场景比较隐蔽:某个低成本方案,主控用的晶振精度只有几百ppm,正常工作温度下通信好好的,一进高温箱就偶发错误帧。低温下晶振偏差小,采样点勉强够;高温下偏差变大,相位缓冲段2余量又不足,重同步能力跟不上,直接就把错误帧干出来了。换了个精度的晶振,或者把采样点从87.5%往前提了两个百分点,就好很多。
4.2 从波形到窗口的排查步骤
遇到CAN通信不稳定的问题,我建议按下面这个顺序排查,能少走一半弯路:
第一步,静态核对全网所有节点的波特率、采样点配置,排除人为配置错误。重点查那些"从别处复制"的初始化代码。
第二步,示波器抓物理波形,看幅值、边沿斜率、振铃程度。重点抓两条:SOF的下降沿、帧末尾的ACK槽。ACK槽能够直观看到接收节点何时发送应答位,这里的边沿状态能反映接收节点是否在正确的时间点完成了采样并做出响应。
第三步,分析错误帧的类型。总线错误计数器飙高时,统计错误帧是位错误还是填充错误。位错误说明采样点位置可能太靠近边沿,填充错误大多是速率偏差太大或者数据被毛刺污染。
第四步,用工具扫描采样点窗口,量化每个节点的余量。这一步能直接暴露哪个节点是薄弱环节。
第五步,如果有条件,把可疑节点放进高低温箱,复测采样点窗口随温度的变化。很多偶发故障都是在这里现形的。
这五步走完,问题基本能定位到底。最怕的是跳过前四步直接换芯片改程序,改来改去可能把原本正常的节点也改崩了。
5. CAN FD 的采样点有哪些新讲究
5.1 为什么CAN FD需要两个采样点
CAN FD和经典CAN最大的区别,就是帧内变速。一帧报文里,仲裁段用较慢的速率(比如500kbps)传输,到了BRS位之后,数据段切换成高速率(比如2Mbps甚至5Mbps)传输,等CRC段结束再切回慢速。
这种变速设计带来一个直接后果:一个位时间里,仲裁段的位宽度和数据段的位宽度完全不同。500kbps下2微秒一位,2Mbps下只有500纳秒一位。如果控制器只用一个采样点,根本没法同时应对两种位宽下的采样需求。
所以CAN FD控制器内部必须配置两套位时间参数:一套管仲裁段,一套管数据段。采样点也自然有两个:仲裁段采样点和数据段采样点。配置的时候要分清楚,很多新手第一次配CAN FD,只改了波特率没改采样点,或者只改了数据段参数没管仲裁段,结果网络要么进不了FD模式,要么高速段CRC错误满天飞。
5.2 CAN FD采样点的推荐值和调试细节
前面参考表里说过:CAN FD仲裁段采样点推荐80%~87.5%,数据段推荐75%~80%。为什么数据段反而要偏早?因为数据段速率高,位时间短,边沿振铃和反射在高速下占的比例更大。采样点如果放得太靠后,靠近下一个位的边沿,很容易踩到高速信号的回冲。稍微提前一点,反而让采样点落在信号相对稳定的区域。
另外,数据段的SJW(同步跳转宽度)也要注意。CAN FD高速段的重同步能力其实比经典CAN弱,因为位时间短,能够调整的幅度有限。如果SJW配得太小,即使采样点本身没问题,遇到一点晶振偏差也纠正不过来。
示波器抓CAN FD波形的时候有个技巧:不要把整个帧拉进屏幕看,那样数据段的位宽太小,根本看不清。用示波器的CAN FD解码功能,让它自动识别BRS速率切换点,然后在数据段单独展开波形看。有些示波器可以把仲裁段和数据段的眼图分开叠加,这样就能分别评估两段速率下的采样点余量,非常方便。
工具扫描CAN FD采样点时,也要分两段扫。先固定数据段采样点为推荐值,扫描仲裁段;再把仲裁段固定为公司规范值,扫描数据段。两段都测试通过,才说明这个节点在FD模式下真正可靠。如果只测一端,另一端可能早就处于临界状态而不自知。
6. 留给我自己的几条经验
最后聊点掏心窝子的经验,都是我实际项目里摸爬滚打攒下来的。
第一,采样点这东西,强烈建议在项目初期就写进硬件设计规范和软件配置清单里,不要等到联调阶段出了问题再去调。每个节点的采样点配置、晶振精度、终端电阻方案,都应该是白纸黑字的文件,而不是某工程师脑壳疼时随手改的寄存器值。
第二,两条总线上共存的节点,采样点差异尽量控制在5%以内。超过这个范围,短期可能看不出问题,长期工作就是定时炸弹。我曾经因为一个节点用了65%的采样点,另一个节点用了87.5%,两个人各调各的,结果整个项目拖了整整一周。
第三,调试CAN通信不稳定,最优先怀疑采样点,其次才是波特率误码率。这个顺序不要搞反。很多人一遇到问题就怀疑波特率设置错了,其实波特率错的话,通信是完全断的,而不是偶发故障。偶发故障十有八九是相位问题,而相位问题的核心就是采样点。
第四,示波器该配就配个差分探头,别再用两根鞭子减来减去。CAN差分信号在共模干扰大的环境里,用普通探头量出来的波形会误导你半天。这笔投入对长期做CAN测试的人来说,太值得了。
第五,做供应商验收或者新产品导入的时候,把采样点窗口测试列入例行项。一台设备,如果它的采样点窗口窄到临界,那就意味着它在未来几年里随时可能因为环境变化而失效。宁可现在退货换个批次,也不要等装车之后批量召回。
采样点这个参数,教科书上就几行字,但实际牵动的却是整车网络可靠性的大问题。希望这篇把原理、计算、配置、测试、排障的全流程讲清楚后,你再遇到CAN通信的疑难杂症,能少走好几个弯路。