首页 / 资讯中心 / 文章详情

CAN总线实战排查:终端电阻、采样点与物理层坑位总结

CAN总线实战排查:终端电阻、采样点与物理层坑位总结 ★ FEATURED ARTICLE
干CAN总线的人几乎都经历过这种玄学时刻同一套代码、同一块板子在台架上跑一个月不出问题换个环境就疯狂报错帧示波器一量波形上的毛刺长得吓人可程序逻辑怎么查都查不出毛病。搞了三年CAN总线我最大的感受是八成以上的故障不在代码而在物理层和那些你觉得“差不多就行”的参数上。这篇就把我这几年攒下来的几句大实话一次性倒出来。从终端电阻、并联分支长度、SRR位到采样点、保护电路和现场排查尽量用操作现场的口吻说透。不管是正在调车的学生还是被现场问题折磨的工程师应该都能从这里找到几句能直接拿去用的东西。1. 三年踩坑下来我对CAN总线的整体认知1.1 CAN到底“神”在哪里两层东西要分开看CAN总线经常被人当成一种“串口协议”上来就照着例程配置波特率、发数据出了问题就怀疑配置不对。实际上CAN是个分层的系统你得把它拆成两件事来看。物理层处理的是CANH和CANL两根线上的差分电压。IDE、DLC、CRC这些是协议层的内容但不先把电平搞对后面全白搭。ISO 11898-1定义了数据链路层ISO 11898-2定义了高速物理层。物理层做的事很简单把显性位逻辑0表现为CANH约3.5V、CANL约1.5V差分电压约2V把隐性位逻辑1表现为CANH和CANL都稳定在2.5V附近差分电压接近0。协议层做的事就有意思多了。CAN不是“主机问、从机答”的轮询模式而是所有节点都挂在同一条总线上谁先发数据由ID仲裁决定。ID数值小的帧优先发送节点同时在监听总线发完一个位后如果发现被别人抢占了就自动转为接收。这种多主仲裁机制加上错误检测、错误帧重传才是CAN能扛住汽车高噪声环境的根本原因。所以排查CAN问题之前先问自己一句我到底是在查物理层的事还是在查协议层的事这两者的现象很像但处理思路完全不一样。1.2 为什么CAN的故障总是“偶发性”的刚接触CAN时我很不理解一个问题明明程序逻辑完全正确为什么总线偶尔就报一个错帧然后又自己恢复后来才明白CAN的容错机制是“人类友好”的但物理层信号质量的恶化程序里根本看不出来。可以这样理解总线就是一根传输线不是普通排线。信号从发送端传到末端遇到阻抗变化的地方就会反射。反射回来的能量叠加在原信号上轻则让波形出现一个台阶重则直接让差分电压跌破接收器的判定阈值。ISO对接收器差分输入的要求是显性电压大于0.9V必须识别为显性隐性电压小于0.5V必须识别为隐性。如果反射导致电平在这个区间内来回晃动接收器就可能误判。这种误判不是每次都发生它与温度、供电电压、干扰强度都有关。于是表现出来的就是“偶发错误帧”、“偶尔丢一帧”、“空调一开就有问题”等玄学故障。后面我学会了一件事遇到偶发错误第一时间别翻代码先拿示波器看波形。这句话值得先记下来。2. 物理层设计里最容易翻车的几个细节2.1 终端电阻两个120Ω一个都不能少先说终端电阻这是CAN网络中最大的“隐性坑”。规范要求总线两端各接一个120Ω电阻注意是物理两端不是“设备两端”也不是“逻辑两端”。为什么是120Ω因为CAN总线用的双绞线特征阻抗大约是120Ω。在传输线末端接上跟特征阻抗相等的电阻信号到达末端时能量会被电阻吸收不再反射回来。如果没有这个匹配电阻信号到了末端就会反射叠加在原波形上形成振铃。判断终端电阻是否正常有个简单的万用表方法把设备断电直接在总线任意位置量CANH和CANL之间的电阻。如果系统里正好有两个终端电阻读到的是两个120Ω并联也就是60Ω左右。如果读到120Ω说明有一个终端电阻没接或者接丢了。如果读数是无穷大说明压根没有终端电阻或者线缆已经断开。这个60Ω的判断标准我用了很久几乎百试百灵。但注意一定要断电测量。我已经见过不止一个现场工程师带电去量电阻量出来一个莫名其妙的几千欧然后开始怀疑收发器芯片烧了其实那是芯片内部的偏置电阻。断电再量干净利落。单终端电阻时波形长什么样我实测过显性位到隐性位的跳变沿会出现一个明显的“台阶”然后回弹像是信号犹豫了一下。如果波特率再高一点这个台阶可能直接让后续采样点落在错误电平上。2.2 并联分支的长度到底指哪个长度“CAN总线并联分支的长度”这个话题在网上被搜爆了说明大家确实分不清。这里把话说清楚并联分支也叫支线或stub指的是从总线干线引出、连接到某个节点的那一小段线。它不是节点与节点之间的间距更不是总线总长度。比如一条主线上串了5个节点每个节点通过一段30厘米的线缆接到干线上这30厘米就是每个节点的分支长度。很多人布线的习惯是把总线像蜘蛛网一样接到各个设备每个设备一段线这些就是分支。分支为什么不能太长因为分支是一段末端开路的短截线。信号沿干线传播时经过分支结点会分流一部分能量进入分支到达分支末端后发生反射反射波回到干线污染后续信号。分支越长这个反射延迟越大对高速通信的影响越明显。我整理过一张经验表算是比较好记的参考值波特率建议最大分支长度1 Mbps约 0.3 米500 kbps约 1 米250 kbps约 2.5 米125 kbps约 5 米这个表不是绝对严格的标准但很能说明趋势速度越快支线越得短。除非用CAN中继器或有源集线器否则别指望用一根两米长的线把一个节点挂在1Mbps的总线上还不出问题。我自己就干过这种事结果误码率高得让人崩溃。2.3 节点数量和线缆选择同样有讲究一个高速CAN网络上能挂多少节点ISO 11898-2给出的常见参考上限是32个节点。原因是每个节点的收发器输入阻抗都是有限值节点越多并联后的等效负载电阻越低收发器驱动的差分电压就越小。节点数超过一定量之后总线上可能连200mV的有效差分电压都保证不了。实际项目中别把32当铁律去卡。我曾经在一个测试台上挂了20多块板子波形已经开始发“软”。这种时候尽量分层处理多路总线通过网关互联别指望单条总线包打天下。线缆选择上优先使用特性阻抗120Ω的双绞屏蔽线。车载环境常用AVSS 0.5平方或0.75平方的屏蔽双绞线工业现场至少要选带有编织屏蔽层的线缆。很多朋友图便宜用普通双绞网线这里提示一下CAT5/CAT6网线的特性阻抗是100Ω不是120Ω用在CAN上阻抗不匹配反射会比正规CAN线严重不少。短距离、低速场景可能能跑但高速长距离时会有隐患。还有一点容易被忽略屏蔽层怎么接地。原则是一点接地别让屏蔽层形成回路。常见做法是只在总线某一点把屏蔽层接到保护地别把每个节点的屏蔽层都单独接一遍大地。3. 协议层几个容易忽略的坑3.1 SRR位和扩展帧仲裁标准帧为什么总是“赢”SRR位是热词搜索榜上的常客说明很多人卡在这里。要理解SRR位先得把标准帧和扩展帧的仲裁过程对比着看。标准数据帧的仲裁段是SOF 11位ID RTR IDE。RTR位为显性0时表示数据帧隐性1表示远程帧。扩展数据帧的仲裁段是SOF 11位基本ID SRR IDE 18位扩展ID RTR。这里注意扩展帧在标准帧RTR的位置安放的是SRR位固定为隐性1。为什么会有这个设计为了保证标准帧在仲裁时优先于同ID的扩展帧。假设一个11位基本ID相同的标准帧和扩展帧同时在总线上标准帧走到RTR位时是显性0扩展帧对应位置是SRR隐性1显性位在CAN仲裁中会覆盖隐性位于是标准帧赢得仲裁扩展帧乖乖退出发送变为接收。SRR全称是Substitute Remote Request可以把它理解成一个“占位符”。它并不携带实际请求信息存在的意义就是让标准帧和扩展帧在同ID前提下有一个确定的仲裁顺序。实际开发中要注意如果总线上的设备既有标准帧又有扩展帧且ID区段重叠标准帧设备会持续抢占总线可能导致扩展帧设备饿死。我在调试一个混合协议系统时就遇到过标准帧流量大扩展帧一帧都发不出去查了半天才想到是仲裁顺序导致最后把两边的ID区间错开才解决。另外一个相关坑是RTR和远程帧。远程帧是节点请求对方发送数据时用的RTR隐性1。很多人只用数据帧完全没处理远程帧。如果上位机定时发远程帧请求而节点没有响应总线上的表现就是一直出现“请求-无应答”的状态错误计数器还可能往上飙升。3.2 波特率、采样点和位时序配置不能只看波特率数字波特率配置不匹配出错帧一眼就能看出来总线上一片错误帧帧ID乱跳看起来像广播风暴。但还有一个更隐蔽的坑即使波特率一样采样点不同也可能导致偶发错误。CAN的一位时间在协议里被分成好几段同步段、传播段、相位缓冲段1、相位缓冲段2。采样点就是接收器在每个位时间内采样电平的时刻推荐位置一般在75%到85%之间。如果采样点太靠后离下一位太近总线抖动稍微大一点就会把下一位的电平采进来。以STM32的bxCAN为例外设时钟36MHz目标500kbps。波特率公式是36MHz / (分频值 x (1 BS1 BS2))。要让等号右边等于500kHz分频值x(1BS1BS2)必须等于72。取分频值Prescaler41BS1BS218那BS113、BS24就是一套很合理配置采样点正好是(113)/1877.8%。面板上只有波特率配置的工程师可能直接套BS115、BS22的例程那样采样点算下来88.9%偏晚时序余量就差一截。示波器测采样点比较麻烦但对配置的理解很重要。给个小技巧如果总线上偶发错误帧而波特率明明一致试着把采样点从87%调到80%附近很多问题会自己消失。3.3 位填充、错误帧和错误计数器CAN协议有个很容易被忽略的规则位填充。发送节点每发出5个连续相同电平的位之后必须插入一个反相电平位接收端收到后会自动把这个填充位删除。这样做是为了保证总线上有足够的电平跳变便于接收器做时钟同步。位填充机制会引发一个连锁反应如果电磁干扰导致总线上的电平跳变异常接收端检测到填充错误就会发错误帧。错误帧的形态是6个连续显性位或6个连续隐性位加上定界的隐性位。而且CAN有个错误计数器机制发送错误和接收错误的计数规则不一样错误计数累积到一定等级节点状态会从主动错误变为被动错误最终变成总线关闭态。总线关闭状态要特别小心达到128次错误后节点会进入Bus Off相当于从总线上“隐身”既不发送也不接收直到软件让总线恢复或满足恢复条件。我见过一个项目节点偶发Bus Off后没有处理逻辑直接“掉线”主站那边只能看到节点长时间没响应。排查时记得查节点驱动里的错误计数寄存器别只盯着主站日志。4. 通信协议实例从报文到代码的一次完整调试4.1 一个典型的控制报文长什么样做CAN开发读帧结构是基本功。拿一条经典的标准数据帧来说完整序列是SOF一位显性11位IDRTR位IDE位一位显性表示标准帧r0保留位4位DLC数据长度接着是0到8字节数据15位CRC加1位CRC界定符ACK槽和ACK界定符最后7位EOF和3位IFS。这条报文里ID的作用不只是标识它同时决定了总线仲裁优先级。比如ID0x100的数据帧和ID0x200的数据帧竞争总线0x100因为数值更小仲裁率先通过于是它先占住总线完成发送。CRC覆盖的范围包括SOF之后的全部位用于检测传输中的位错误。ACK槽是发送节点发一个隐性位所有正确接收到该帧的节点把这个位拉成显性这样才能让发送节点确认“有节点收到我的报文了”。所以遇到发送节点报“无应答”错误时八成是总线上只有发送节点自己或者对方的验收滤波把帧过滤掉了。4.2 报文收发流程与常见现象实际调试中协议栈里最容易出问题的不是CRC也不是DLC而是验收滤波和缓冲器管理。很多CAN控制器的硬件接收过滤是按ID区间配置的。你要接收ID0x123结果过滤器配成了标准帧ID而对方发的是扩展帧那帧在硬件层就被丢弃了软件层面连影子都看不到。我调试时习惯先把过滤器设为全收跑通了再逐步收窄ID范围这样少走很多弯路。发送流程的坑也很多。以常见CAN控制器为例发送过程是软件请求发送、等待总线空闲、参与仲裁、逐位发送、等待ACK。如果节点持续发不出去先看总线是否一直忙再看自己的CAN_TX引脚电平。一个排查的小技巧把CAN收发器的TXD引脚接示波器总线上没有报文时TXD应该保持隐性高电平。如果看到TXD在持续拉低说明芯片一直在尝试发送但发不出去这往往是仲裁失败或者总线错误导致的。接收丢帧的排查思路也是先分层物理层用示波器量差分波形确认每个帧都在线上协议层用CAN卡看错误帧数量软件层查FIFO溢出标志。一个酷似“软件丢帧”的故障最后查出来是CAN控制器FIFO溢出后软件没有及时读数据一帧丢了之后后续帧也全挤丢了。这种问题加一个接收中断里快速搬数据的逻辑就解决了。4.3 实际调试中用到的工具和判断方法调试CAN我个人必备三样东西一台带CAN解码的示波器或逻辑分析仪、一个USB转CAN适配器、一台万用表。示波器和逻辑分析仪看协议层和物理层CAN卡主要用来模拟节点和监控总线流量。用示波器测CAN是最直观的。正常波形上隐性电平稳定在2.5V附近显性位是CANH向上抬、CANL向下拉像一对对称的翅膀。如果看到CANH和CANL的幅值不一致比如一个抬高1.8V而另一个只降了0.6V大概率是收发器的驱动能力出了问题或者总线上的某个设备把某一根线轻微短路了。逻辑分析仪的优势是能直接解码出ID、DLC、数据内容。抓一帧报错的数据先用解码功能看ID和数据对不对再用示波器看发生错误瞬间的物理波形。很多时候错误帧是因为总线上某个瞬间出现了两个节点同时发帧的“位冲突”在逻辑分析仪上看就是CRC校验失败在示波器上看则是波形畸变。这两者一对照问题定位就非常快了。5. 总线保护与汽车级电路设计5.1 为什么CAN这么容易坏共模和ESD很多人认为CAN是差分信号两根线互相抵消干扰抗干扰能力自然强。这话只说对了一半。差分确实能抑制共模干扰但CAN收发器的输入引脚直接暴露在外部环境里汽车上12V/24V系统电压波动、感性负载的浪涌、人体静电都是直接攻击收发器的“杀手”。收发器芯片内部对ESD有一定的承受能力但绝对扛不住持续性的过压。最常见的情况是总线上的某个节点地电位升高导致CANH和CANL相对本地地的电压超出共模输入范围。收发器一般允许的共模范围在-2V到7V左右具体看芯片手册一旦超出轻则信号失真重则直接烧毁总线引脚。另一个典型场景是两根总线线被错误地碰到电源线上。24V电源碰到CANH瞬间的高压就可能把收发器击穿。我在现场见过一块板子的收发器烧出一个小洞查了半天原因是线束在震动中磨破了绝缘层CANH碰到了24V线。所以节点设计里保护电路不是可选项而是标配。5.2 典型节点电路TVS、共模电感、电阻怎么选一个典型的CAN节点硬件链路按信号流向是MCU的CAN控制器很多MCU内置接CAN收发器收发器的CANH/CANL引脚先经过共模电感和TVS保护再接到外部连接器最后是总线。如果在总线两端还需要在总线最外侧各放一个120Ω终端电阻。具体选型上交流经验是这样的TVS管选双向的比如PESD1CAN这类专用于CAN的型号钳位电压要低于收发器绝对最大额定值结电容要尽量低。放在连接器入口处用来泄放ESD和浪涌能量。共模电感常见封装是ACM7060或B82793系列。它主要抑制共模噪声对差分信号本身的损耗很小。如果没有共模电感仅靠TVS高频共模干扰还是能耦合进收发器。有些设计会在CANH/CANL上串接一个几欧到几十欧的电阻比如22Ω或33Ω。这个电阻能限制故障状态下的电流同时也能在一定程度上阻尼高频振铃。但注意电阻太大会衰减差分信号幅度得不偿失。终端120Ω电阻要直接连接在CANH和CANL之间。如果节点不是布线两端终端电阻就不要放。很多节点为了“方便”每个板子上都预留120Ω跳线一旦在中间节点上误接了终端电阻总线上的等效电阻就会低于60Ω信号幅度明显下降。提示能用集成方案就别自己拼保护电路。现在很多隔离收发器自带ESD和过流保护比如ISO1042、CTM1051系列。自己做分立保护电路虽然省钱但布局布线一不留神保护就变成了噪声源。5.3 隔离与非隔离的选择什么时候需要隔离记住一条经验两个节点之间的地电位差超过收发器允许范围或者现场环境存在持续大共模干扰就老老实实用隔离。非隔离方案里所有节点共地信号回路经过地线。如果节点间距离几十米甚至上百米地线上的电位差可能达到几伏甚至十几伏CANH和CANL相对地电压被整体抬高或拉低通信就会间歇失败。隔离方案则是把节点内部的信号地与总线的地彻底分开CAN收发器这一侧只跟总线的地电位发生关系。我做过一个项目现场有电机变频器地线干扰很大。最初用非隔离收发器表现为运行一段时间后偶发错误帧电机一启动错误帧就暴增。后来换成了带隔离电源的CAN收发器模块把节点内部的信号地和总线地断开问题直接消失。隔离会增加板子面积和成本但在工业环境或新能源车上这笔钱省不得。6. 常见问题与排查技巧实录6.1 故障速查表三年折腾下来我把高频故障整理成了一张速查表遇到问题可以对着查。故障现象可能原因排查方法完全收不到报文波特率不匹配CAN卡配置相同波特率看错误帧数量偶发错误帧分支过长、终端电阻缺失示波器测波形测量总线静态电阻发送超时无应答只有发送节点在线或验收滤波配置错误用CAN卡监听确认是否有节点在应答ACK波形幅值偏小节点过多、终端电阻误接多处断电测CANH-CANL电阻正常应为60Ω左右电机一启动就报错共模干扰、地电位差换隔离收发器或检查地线连接节点间歇掉线Bus Off读错误计数器检查驱动软件恢复逻辑能通信但数据偶发错乱ID仲裁冲突、混合标准扩展帧检查ID分配策略用CAN卡分帧监控一根线断掉还能通信但报错率高单线工作依赖地回路检查线束CAN必须两根线才能差分传输6.2 三个亲历案例第一个案例是单终端电阻。一台设备在产线上测试三个节点组网偶尔报错。我去现场量总线静态电阻发现只有120Ω也就是说两个终端电阻只接了一个。补上另一个后波形上的台阶消失错误帧清零。这个案例我常拿来提醒别人先量电阻再看波形不要一上来就改程序。第二个案例是分支过长。一个项目中有一个传感器节点供应商给的线束自带一条三米长的支线。波特率500kbps系统表现是传感器数据偶尔丢一帧。我让供应商把这条支线改成在传感器端用短跳线就近接入干线并把这段支线控制在1米以内丢帧现象完全消失。那条三米支线就是典型的“末端开路反射源”。第三个案例是地电位差。两个柜体相距50米CAN线走桥架信号地通过保护地回流。调试时发现通信时好时坏两柜之间的地电位差实测有7V。普通收发器的共模范围根本受不了。最后两端都加了隔离通信稳定得一批。这件事教育我距离一长隔离就得当默认选项。6.3 给新手的几条实在建议第一排查顺序固定下来断电量静态电阻、示波器看波形、CAN卡看协议、最后再看软件。按这个顺序来至少能排除掉一半以上的“玄学”问题。第二开发阶段就把所有调试接口暴露出来。板子上预留CANH、CANL测试点留出终端电阻跳线MCU的CAN错误计数器寄存器做成可读状态这些都能在出问题时省下大量时间。第三不要迷信“高速”。很多场合250kbps甚至125kbps完全够用但抗干扰能力和布线容忍度成倍上升。能用低速解决就别追求高速这是我用教训换来的。第四多备一台便宜的CAN分析仪开发板上电之前先接上看看总线上有没有别人在发数据。两个设备用相同波特率但不同帧格式互相不认识但也会在总线上产生干扰这类问题只看自己的日志永远发现不了。这几句大实话说到底就是一句话CAN总线的问题绝大多数不是它不行而是设计时没把它当成一根传输线去认真对待。把物理层扎实做好协议层的那些坑其实都好填。最后再分享一个小习惯我现在每次设计CAN节点都要在实验室把样板挂到真实线缆上跑一整晚第二天看错误计数器。很多白天测不出来的偶发问题过一夜就自己显形了。
阅读完成 · 觉得有帮助?
咨询建站