资讯详情

资讯详情

CAN总线同步机制详解:采样点与SJW对通信可靠性的影响

1. 为什么波特率相同节拍还是对不齐从一次现场故障说起做汽车电子和工业通信的工程师很少有没被CAN总线玄学故障折磨过的——波形看着正常、波特率也都对但报文就是偶尔错一帧严重的时候整个网络直接卡死。我曾经在某设备联调现场耗掉一整个下午排查的就是这样一个问题三个节点单独跑都稳稳当当接在同一根总线上之后接收错误计数一路涨错误帧隔几秒就蹦出来一次。用示波器抓波形电平、波特率、帧格式全都没毛病最后打开三个节点的位时序配置寄存器我才找到了真正的差异——三个节点的采样点分别是68%、80%和87.5%波特率都是500kbps但它们对一个bit到底怎么切分的理解完全不同。这正是CAN总线同步机制要解决的核心问题。总线上每个节点都有自己的本地时钟没有任何一根独立的时钟线把大家拉到完全一致CAN能工作靠的是每个节点把位时间切成小段然后在信号跳变沿上不断做硬同步和重同步把彼此的节奏校准到同一个节拍上。采样点只要错开几个百分点长距离、高负载场景下就会隐藏不住最终变成误码和重传。这篇文章我想把CAN总线同步机制从头到尾拆开讲透位时间为什么必须切成多段、硬同步和重同步到底怎么工作、采样点和SJW应该怎么配、传播延迟和时钟误差对同步有什么影响最后再给三个现场排查案例。内容适合刚接触CAN的初学者也适合那些被偶发错误帧困扰、想搞明白为什么明明波特率一样还是不同步的工程师。1.1 故障现场三个节点各自正常组网却出错那次联调环境并不复杂A节点是一个主控板B和C是两个执行器总线总长不到两米终端电阻也都在。单独把B接上去连续跑一整天错误帧计数纹丝不动单独把C接上去也一样。但只要A、B、C三个节点同时上电问题就来了。最先出现的其实不是通信错误本身而是执行器的动作偶发不响应。查应用层看不出问题示波器抓波形也看不出明显的电平畸变。直到我把各个节点的错误状态寄存器读出来才发现B节点的接收错误计数在持续增长而且时不时报出CRC错误。按照经验CRC错误大多意味着某个节点在某一位上采样到了错误的电平值而不是数据真的被干扰了。1.2 先看真凶位时序被默认值坑了逐节点读位时序寄存器之后真相很明显了三个节点虽然都配置成500kbps但内部对位时间的切分方式完全不同。A节点的采样点落在68%B节点是80%C节点是87.5%。问题就出在采样点不一致上。A节点采样太早总线信号从远端的B节点传播过来需要时间边沿刚刚落下、电平还没完全稳定A节点就已经采样了。在某些位组合下它读到的电平和实际发送的电平不一致于是CRC校验失败。把A节点的采样点调成和B、C接近之后错误帧立刻消失。这让我后来养成了一个习惯任何多节点组网的项目第一件事就是统一所有节点的位时序参数而不只是波特率。波特率相同只是每个bit的时间长度一样但采样点差多少、同步能力差多少完全取决于位时序的具体配置。2. 位时间的四段结构一个bit是怎么被切开的要说清楚同步机制绕不开位时间结构。CAN总线上传输一个bit在时间轴上并不是简简单单占一个固定时长而是被切成了四个先后衔接的时间段。理解这四个段采样点这个概念就自然清楚了。2.1 先认识最小时间单位tq位时间的最小颗粒叫时间量子简称tqTime Quantum。一个tq的长短由控制器时钟和预分频器共同决定tq 1 / (控制器时钟频率 / 预分频值)举例来说控制器外设时钟是40MHz预分频器设成4那么每个tq就是100ns。每个bit时间由一个整数个tq组成典型值在8到25个tq之间。自己算的时候记得先确认你的芯片有没有额外的分频很多芯片把BRP波特率预分频和时钟源选择分开配错了会导致tq和你预期完全对不上。tq这个概念的引入让CAN控制器可以用一个计数器来管理位时间每过一个tq计数器加1走到采样点就采一次电平按完整个位时间后清零重新开始。同步机制对这个计数器的干预就是后面要讲的硬同步和重同步。2.2 四段位时间的分工与采样点一个完整的CAN位时间按标准分为四段段名英文缩写作用典型长度tq同步段SYNC_SEG用于检测信号跳变沿总线跳变应该落在这里固定1传播段PROP_SEG补偿信号在总线上的传播延迟1~8相位缓冲段1PHASE_SEG1采样点之前可被延长的时间段1~8相位缓冲段2PHASE_SEG2采样点之后可被缩短的时间段1~8四段加起来就是一个位时间采样点就位于PHASE_SEG1和PHASE_SEG2的边界处。换句话说采样点的位置 (SYNC_SEG PROP_SEG PHASE_SEG1) / (四段之和) × 100%。拿一个常见的500kbps配置举例外部时钟40MHz、预分频4tq为100ns一个500kbps的位时间正好是2000ns也就是20个tq。把这20个tq按1 3 13 3分配采样点就是(1 3 13) / 20 85%。SYNC_SEG固定为1个tq这是所有CAN控制器的共同规定。跳变沿只要落在这个段里就说明本节点的位计时相位和总线上实际传输的位置基本对齐。PROP_SEG负责吸收传播延迟。信号从发送节点到最远接收节点需要时间接收节点做出反应再传回来又需要时间所以这个段至少要覆盖两倍的端到端传播延迟。总线越长这个段占的tq就要越多。PHASE_SEG1和PHASE_SEG2是重同步的可调节区。当检测到边沿偏移时控制器可以把PHASE_SEG1延长或者把PHASE_SEG2缩短从而微调采样时机。这也是整个同步机制最核心的执行机构。2.3 为什么采样点必须在中间偏后采样点的位置不是拍脑袋定的。CAN协议要求采样点放在位时间的后半段实际工程中绝大多数配置落在75%~90%之间85%和87.5%是最常见的两个值。原因有两个。第一总线信号从发送节点到接收节点有传播延迟边沿到达接收节点时已经比发送时刻晚了一段时间采样点太靠前看到的电平可能还是旧的。第二边沿附近往往存在振铃和过冲采样点太靠近边沿容易采到正在变化中的不稳定电平。把采样点推到中后段相当于等信号真正稳定下来之后再去读取。但也不是越靠后越好。采样点太靠后比如做到95%以上会压缩PHASE_SEG2的长度导致重同步几乎没有反向调整的余地。这就像合唱时指挥给了节拍你只留了一小段反应时间稍微抢拍就纠正不回来了。3. 硬同步与重同步一次对表和无数次微调CAN总线的同步机制分为两种硬同步和重同步。两者都利用总线上的隐性到显性跳变沿在物理电平上表现为下降沿但作用时机和调整幅度完全不同。3.1 硬同步从SOF沿重新起跑硬同步只发生在总线空闲状态后的第一个跳变沿上也就是一帧报文起始位SOF的下降沿。检测到这个沿时每个节点的CAN控制器都会把自己内部的位时间计数器立即复位到SYNC_SEG的起点相当于大家一起把表盘拨回到12点整。硬同步是一次性的、彻底的复位不涉及任何微调。它的作用是消除节点之间在空闲期积累的任意相位差——因为总线空闲时没有任何边沿信号每个节点只能靠自己的晶振自由运转经过一段时间后相位漂移可能很大。SOF沿一到所有人的计时器从同一个位置重新起跑这一帧报文的基础节奏就建立起来了。有一点值得注意硬同步之后尽管大家从同一条起跑线出发但各自的晶振频率并不是绝对一致若干个bit之后相位偏差又会慢慢累积起来所以还需要重同步不断修正。3.2 重同步晚到就延长早到就缩短重同步发生在报文传输过程中。接收节点每检测到一次隐性到显性的跳变沿就判断这个沿落在自己位时间的哪个位置边沿落在SYNC_SEG之后相位误差为正也就是边沿来晚了说明本节点跑得比发送节点快控制器会延长PHASE_SEG1把采样点往后推边沿落在SYNC_SEG之前相位误差为负也就是边沿来早了说明本节点跑得比发送节点慢控制器会缩短PHASE_SEG2让位时间提前结束采样点相应前移。这里的关键点在于重同步只改变位时间内部的相位段长度不会像硬同步那样把整个计数器复位。每次调整的量也受SJW限制而不是一步到位。所以重同步更像是在合唱中跟着指挥的手势不断微调自己的节拍越跑越偏就会越纠越准。协议里还有一个细节一个位时间内如果出现多个跳变沿只取第一个有效边沿作为同步参考。而且同步只利用隐性到显性的沿这是因为显性电平在总线上具有优先级覆盖作用这个沿是所有节点公认的换挡时刻显性到隐性的沿则可能夹杂着仲裁丢失导致的电平变化不够可靠。3.3 SJW与位填充对同步的隐形影响SJW同步跳宽度指的是每次重同步允许调整的最大tq数量。如果说PHASE_SEG1和PHASE_SEG2是调整空间SJW就是每次调整的步长上限。SJW设置得越小每次重同步能纠正的相位误差就越小遇到大幅度的相位跳变时跟不上误差会在多个bit上累积。SJW设置得越大纠错能力越强但采样点的位置也会随着每次重同步发生较大的前后摆动反而可能引入额外的不稳定。常规建议是SJW取1~4个tq一般不超过较小的那个相位缓冲段。位填充bit stuffing对同步的影响也经常被忽略。CAN协议规定连续发送5个相同电位的位之后必须插入一个反向位。很多人以为这是为了直流平衡其实它还有一重身份同步参考的密度保障。没有位填充长串的连续相同位会导致总线上很久没有跳变沿接收节点就算有重同步机制也没有参考边沿可用。填充位保证了每5到6个bit必然出现一次跳变让重同步可以稳定地持续进行。4. 采样点与SJW怎么配计算、选型与实测这一节直接给可以落地的配置方法。我见过不少工程师在初始化代码里直接抄例程的寄存器值从不关心这些数字怎么来的结果换了主控芯片或者改了总线长度问题就开始冒头。4.1 一套可以抄作业的配置流程配置位时序我一般按下面这个流程走确定目标波特率和控制器时钟。比如目标500kbps外设时钟40MHz。计算tq选择预分频值使位时间的tq数落在16~25之间。tq太少四段分配空间不够tq太多采样点的位置粒度太粗同步调整的分辨率也会下降。确定物理层的传播延迟预算。计算总线最长距离和收发器环路延迟据此设定PROP_SEG。在剩余空间中分配PHASE_SEG1和PHASE_SEG2把采样点落在85%左右。设置SJW一般从1个tq开始长线或干扰较多的环境放宽到2~3个tq。举个例子某项目控制器时钟40MHz目标波特率500kbps预分频4得到tq100ns位时间20个tq。总线长度约10米双绞线信号往返延迟按每米10ns估算加上收发器延迟大约200ns总传播延迟约300ns需要至少3个tq的传播段。所以我用SYNC1PROP3PS113PS23这个配置采样点85%SJW2。实测跑了好几天没有任何错误帧。如果是8MHz时钟的经典控制器500kbps位时间只能分到16个tq常见的配置是11122采样点87.5%。这套配置在短总线上非常经典但总线一旦超过20米PROP_SEG只有1个tq就明显不够了。4.2 不同采样点的时钟容错对比采样点选择不仅影响误码率还直接决定整个网络对节点时钟偏差的容忍度。有一个在CAN一致性测试中常用的估算关系在采样点位于75%~100%的区间时允许的振荡器容差约为Δf ≤ (2 × (1 - 采样点位置)) / (10 × 位时间tq数)按20个tq计算不同采样点的容差对比如下采样点振荡器容差上限工程判断80%0.20%余量一般短距离可用85%0.15%常规推荐87.5%0.125%经典配置常见于16tq90%0.10%对时钟要求更严格看到这个表你就明白为什么晶振选择很关键了。常见的无源晶振精度约±100ppm0.01%离极限远得很但如果有人图便宜用了±3000ppm的陶瓷谐振器0.3%单独一个节点可能还能跑接上网络之后波特率稍有偏差重同步又来不及补偿误码就会不请自来。4.3 三采样模式要不要开不少CAN控制器内置了连续采样三次、多数表决的模式也就是标称采样点前后各半个采样周期各采一次三个结果二比一判定位值。这个模式对滤除窄毛刺很有用代价是采样点在时间上被摊开了一些同时收紧了时序余量。我的习惯是总线上有大量电感性负载、波形边沿不够干净的时候开三采样能明显改善误码如果总线很短、波形干净就没必要开保持单点采样更利于精确控制时序。判断依据很简单示波器抓一下波形看边沿附近有没有明显振铃——有就开干净就不开。5. 隐藏在物理层的两个隐形杀手传播延迟与时钟容差很多人把同步机制理解成纯粹的控制器内部逻辑认为只要寄存器配对了同步就自然没问题。实际上位时序参数永远要跟物理层条件放在一起算传播延迟和时钟容差是两个最容易出问题的外部变量。5.1 传播延迟真的会吃掉采样点信号在总线上的传播速度大约是光速的2/3换算到双绞线里大概每米延迟5ns左右。再加上CAN收发器的电路延迟通常单向总延迟可以按线缆延迟 收发器延迟来估算收发器环路延迟普遍在200~300ns的量级。为什么PROP_SEG要覆盖两倍的传播延迟因为发送节点需要保证自己发出的显性位传到最远端节点后最远端节点的响应信号还能在同一个位时间里被其他节点稳定看到。只覆盖单程延迟远端节点就可能在采样点上收到还没到达的电平。总线越长PROP_SEG需要占用的tq越多。很多人在短总线上的配置拿到长总线上直接用结果发现远端节点丢帧。原因基本就是PROP_SEG不够采样点算出来虽然是85%但实际采到的电平还是边沿跳变前的旧值。这时候不是改SJW能救的必须重新分配传播段或者降低波特率以增大位时间内的tq数量。5.2 时钟容差为什么±100ppm够用而陶瓷谐振器可能翻车每个节点的晶振都有误差不同节点之间的实际波特率并不完全相等。同步机制能容忍一定范围内的偏差超过这个范围位时间就会被不断积累的相位误差拖垮。前面那个容差公式估算过在20tq、采样点87.5%的配置下容差约0.125%也就是1250ppm。单个节点用无源晶振误差通常只有几十ppm看起来余量很大但别忘了极端的现场情况温度漂移、老化、两端的误差方向相反误差会叠加。多节点组网时不同节点的晶振误差相互独立最坏情况下两个节点的相对偏差接近各自误差上限的和。我建议在任何CAN网络中至少保证所有节点使用精度不低于±100ppm的时钟源。这个精度等级在现在的产业链里成本很低没必要为了省几分钱在可靠性上冒险。批量生产的产品还要注意晶振的负载电容匹配偏离标称值会导致频率偏移这在高温环境下尤其明显。5.3 CAN FD时代TDC是怎么补偿自己的讲同步机制不能只停留在经典CAN。到了CAN FD数据段的位时间被大幅压缩波特率动辄几Mbps一个位时间可能只有几十ns而收发器环路延迟就占了其中很大一部分。此时如果还靠接收节点边沿同步、再等信号稳定后采样时序就完全不够用了。CAN FD引入了一个叫TDC发送延迟补偿的机制。发送节点知道自己的信号什么时候发出、什么时候在总线上被自己看到用这个时间差减去固定延迟算出数据段采样点应该额外偏移多少。说白了经典CAN是大家一起对表CAN FD快节奏下各节点往往各发各的发送延迟补偿让发送节点精确知道自己听到的总线是什么时候的自己。如果你用CAN FD做设计除了仲裁段的采样点还要额外关注数据段的TDC配置。很多控制器需要在初始化时做一次基于测量或手工估计的延迟补偿设置这部分在芯片手册里通常有专门的寄存器千万不能沿用经典CAN的思路只看采样点。6. 三个现场问题的定位与修复实录最后用三个实际排查过的案例收尾都是同步机制出了问题但表象各不相同的情况。排查思路比答案本身更有价值。6.1 偶发CRC错误采样点不一致引发的误读回到开头那个故障。三个节点各自单独测试都正常组网后B节点报CRC错误A节点所在地离B节点最远。读寄存器的结果是A节点采样点68%B和C都是85%以上。这个场景最迷惑人的地方在于单独通信时只有两个节点距离很短传播延迟小A节点采样早的问题被掩盖了。三节点组网后B节点发出的信号传到A节点需要更长时间A节点那个早得离谱的采样点就采到了边沿跳变过程中的不确定电平位值误判导致CRC对不上。修复方式是把A节点的采样点改成和B、C一致用的是上一节那套20tq配置。改完之后跑了一整天错误计数为零。这件事给我最大的教训是不要用单独测试正常来证明同步配置没问题。单节点通信只是必要不充分条件多节点组网时的相位差才是真正的考验。6.2 远端节点丢帧PROP_SEG只给了1个tq的代价另一个项目用的是16tq的经典配置SYNC1PROP1PS112PS22采样点87.5%短距离测试全部通过。后来总线为了绕线多走了将近30米远端节点开始丢SOF和首个数据字段。30米双绞线的单程延迟约150ns加上收发器延迟单程总延迟接近250~300ns往返就接近600ns。而当时tq是125nsPROP_SEG只有一个tq连往返的一半都覆盖不到。这个案例的修复方案有两类如果必须保持500kbps就把tq数增大到20个给PROP_SEG分配到3个tq来覆盖300ns再配合采样点后移到合理位置如果波特率可以降降到250kbps会让位时间翻倍同样能把PROP_SEG扩大。最终为了兼容网络上的其他设备选了后者。修复之后远端节点不再丢帧错误计数归零。6.3 长分支线接入后错误帧飙升反射与SJW的博弈第三个案例比较隐蔽。一个原本用菊花链连接的现场总线为接入一个执行器加了一条1.5米的分支线之后整条网络上错误帧明显增多。起初怀疑是终端电阻位置不对检查后发现终端电阻还挂在总线两端没有因为分支线改变。问题出在分支线末端产生的信号反射上。反射波叠加在原信号上让本来就受传播延迟影响的边沿附近出现了额外的抖动。节点的重同步参考位置变得不稳定而当时SJW只设了1个tq每次只能纠正很小一段偏差反射造成的相位跳变远远超出一个tq的补偿能力。处理办法有两步第一步把SJW从1放宽到3个tq给重同步更大的纠错空间第二步是把分支线长度尽量缩短或者改成T型连接点从物理上减小反射路径。只改软件也能缓解但根治还得靠布线。这个案例提醒我同步机制能不能胜任和网络拓扑是强耦合的别把问题都推给位时序参数。7. 我这些年配置位时序的一些习惯写到这里分享几个我长期在用的实操习惯全都是踩过坑之后沉淀下来的。第一任何新项目的CAN初始化我都不直接抄例程而是先算出tq和位时间的tq数再按传播延迟预算→采样点→SJW的顺序逐个确定参数。这个过程只需要几分钟但能让你对每条总线的边界条件心中有数。第二多节点组网时我会把所有节点的采样点和SJW统一成同一组参数。哪怕有的节点采样晚一点也能工作从设计上消除差异隐患才是最省事的做法。第三每次改完位时序我都会把采样点、SJW、tq数和总线长度记录在测试文档里下次排查故障时这些数据能省掉大量重新测量和试错的时间。还有一个容易被忽视的地方CAN控制器的位时序寄存器在不同芯片上字段可能合并或重排有些把PROP_SEG和PHASE_SEG1合成了一个字段有些增加了额外的TQ精度位。换芯片平台时务必重新按公式推导寄存器值而不是把旧值平移过去。芯片手册里的时序图配合示波器抓出来的实际波形是验证配置正确与否最直接的方法。CAN总线的同步机制说复杂很复杂但拆到底就是一句话用精细的位时间切分和持续的边沿校准让所有的节点在共享一条总线时保持同一个采样节拍。把握好采样点、SJW、传播预算和时钟精度这四个变量这个节拍就能稳定下来那些玄学错误帧自然也会离你远去。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →