资讯动态

车载总线CAN与CAN-FD从物理层到协议层实战解析

发布时间:2026/10/23 5:32:18 来源:尧图企业网站定制
1. 为什么车载总线里CAN和CAN-FD是绕不开的一课如果你拆过任何一台近十年的车不管是燃油车还是新能源扒开内饰板之后大概率会看到两根绞在一起的线一根CAN_H、一根CAN_L终端各挂一个120欧姆的电阻。这两根线就是整台车的神经系统主干。我最早接触CAN是在做一套数据采集盒的时候当时天真地以为这就是个差分串口接上就能读数据结果折腾了整整两天才让第一帧报文稳定收上来。后来做域控制器项目又被迫从经典CAN迁移到CAN-FD踩的坑更多。所以这一篇我想把CAN和CAN-FD这两代总线从物理层到协议层彻底讲透重点放在实际工程里真正会卡住你的地方而不是复述手册。先说清楚这篇文章适合谁看。如果你是刚入行的嵌入式工程师正在做车载节点开发、数据采集或者诊断工具那这篇能帮你少走至少一周的弯路。如果你是从其他总线比如RS485、以太网转过来的老手那重点看协议层和位定时那几节因为CAN的仲裁机制和错误处理跟大多数总线都不一样。如果你只是好奇为什么车上的线能这么少还这么可靠那也能从里面看到一套分布式系统是怎么在两根线上跑起来的。CAN的全称是Controller Area Network最早是上世纪八十年代为汽车电子设计的多主总线。它的核心设计目标就三个多节点共享总线、基于报文优先级的无损仲裁、以及极强的错误检测与容错能力。这三点决定了它跟RS485那种主从轮询完全不是一个物种。而CAN-FDFlexible Data-rate是2012年前后推出的升级版主要解决两个痛点经典CAN最高1Mbps的速率在刷写和标定场景下太慢以及单帧最多8字节数据在传输大块信息时协议开销太高。FD把数据段速率提到最高8Mbps实际常用2M到5M数据长度扩展到64字节同时保留了仲裁段的兼容性。理解这两代总线的差异不能只看速率数字得从帧结构、位定时、收发器要求三个层面一起看否则你会在迁移时遇到一堆莫名其妙的问题。下面我按实际工程中会碰到的顺序一层层拆开讲。2. 差分线背后的物理层为什么两根线能抗住发动机舱的干扰2.1 显性位与隐性位CAN的线与逻辑CAN总线最巧妙的设计之一是用差分电压直接表达逻辑值而且这个逻辑值天然支持线与。具体来说收发器把总线驱动到两种状态显性Dominant和隐性Recessive。显性状态下CAN_H约3.5V、CAN_L约1.5V差分电压约2V隐性状态下两根线都约2.5V差分电压接近0V。关键点在于只要有一个节点发显性位总线就是显性所有节点都发隐性位总线才是隐性。这就像一群人开会只要有一个人举手就算通过了。这个特性直接支撑了后面要讲的仲裁机制。我见过不少新手把CAN当成普通差分串口以为两个节点同时发就会冲突丢数据其实CAN在物理层就解决了这个问题——冲突时显性赢发隐性的那个节点会自动退出而且不丢帧。这里有个实操细节隐性到显性的转换时间也就是上升沿会直接影响你能跑多高的速率。总线越长、节点越多、寄生电容越大边沿就越缓。经典CAN在1Mbps下要求总线长度不超过40米就是这个原因。很多人调不通高速CAN最后发现是线太长或者终端电阻只焊了一个。2.2 终端电阻不是可选项是必须项CAN总线两端各需要一个120欧姆的终端电阻并联之后总线等效负载约60欧姆。这个电阻的作用是消除信号反射。你可以把总线想象成一根水管信号是水波如果末端开口波会反射回来跟后面的波叠加导致电平判断错误。终端电阻就是那个堵头让能量被吸收掉。我踩过的一个典型坑做台架测试时用两根短线接了两个节点觉得线短就懒得焊终端电阻结果低速下勉强能通一上500kbps就疯狂报错。后来用示波器看波形隐性位被反射顶出一个鼓包收发器直接判成显性仲裁全乱。所以记住一条只要总线长度超过十几厘米两端终端电阻就必须焊而且只能两端各一个中间节点不能加。有些节点内部集成了可切换的终端电阻调试时一定要确认状态我见过两个内部终端都打开的节点接在一起等效30欧姆总线直接驱动不起来。2.3 共模电压与地偏移双绞线为什么必须绞CAN_H和CAN_L必须用双绞线绞在一起原因是差分信号对共模干扰有天然抑制。发动机点火、电机PWM这些干扰源会同时耦合到两根线上差分接收端只关心两线之差共模部分被抵消。但前提是两根线绞得足够紧耦合到的干扰才一致。实际布线时还有一个容易忽略的点地偏移。CAN收发器的共模输入范围是有限的经典CAN大约在-2V到7V之间。如果两个节点地电位差太大比如一个在车头一个在车尾大电流回路导致地偏移超过范围收发器就识别不了信号了。解决办法是确保所有节点有良好的公共参考地或者用隔离型收发器。我在一套分布式采集系统里就遇到过电机启动瞬间CAN通信中断最后查出来是电机地和采集板地之间有几百毫伏的动态偏移换成隔离收发器后彻底解决。3. 帧结构拆解从仲裁场到CRC场每一段都在干什么3.1 经典CAN标准帧与扩展帧的字段布局一帧经典CAN标准帧的结构是这样的帧起始SOF1位显性、仲裁场11位ID RTR位、控制场IDE 保留位 4位DLC、数据场0到8字节、CRC场15位CRC 1位界定符、ACK场1位槽 1位界定符、帧结束7位隐性。扩展帧把11位ID换成29位ID多了一个SRR位和IDE位来区分。这里重点说几个实际开发中会用到的地方。DLC是数据长度码不是字节数本身经典CAN里DLC取值0到8直接对应字节数但CAN-FD里DLC是编码值9到15分别对应12、16、20、24、32、48、64字节。我第一次写FD驱动时就栽在这按DLC9去读9个字节结果实际是12字节数据全错位。RTR位区分数据帧和远程帧。远程帧就是我要这个ID的数据谁有谁发听起来很美好但实际项目里几乎不用因为它的仲裁机制会导致响应延迟不可控而且现代架构更倾向于周期广播。我建议新手直接忽略远程帧把精力放在数据帧上。3.2 仲裁机制ID越小优先级越高且不丢帧CAN的仲裁发生在仲裁场。每个节点在发送ID的同时也在监听总线如果自己发隐性位但总线上是显性位说明有更高优先级的节点在发自己立刻退出转为接收等总线空闲再重发。因为ID是从高位到低位逐位比较所以数值越小的ID优先级越高。这个机制的精妙之处在于仲裁失败不丢帧、不重传、不冲突退出后自动重试。对比以太网的CSMA/CD冲突后要随机退避重传实时性差很多。这也是CAN能用在刹车、转向这些安全相关场景的原因。实操经验设计ID分配表时一定要把安全关键报文比如刹车、气囊放在低ID段把舒适性报文车窗、空调放在高ID段。我见过一个项目把诊断响应ID设得比刹车还低结果刷写时刹车报文被挤掉台架上直接报故障。ID规划是架构级决策后期改起来牵一发动全身。3.3 CRC与错误处理CAN为什么这么抗造CAN的CRC是15位覆盖从SOF到数据场的所有位。接收节点算完CRC跟帧里的比对不一致就报错。除了CRCCAN还有位填充错误、格式错误、ACK错误等检测机制。位填充规则是连续5个相同电平后必须插入一个相反电平接收端自动去掉。这个机制保证接收方能持续从跳变沿恢复时钟同时也是一种错误检测——如果连续6个相同电平直接判错。错误处理的核心是错误计数器TEC和REC。发送错误加TEC接收错误加RECTEC超过255节点进入Bus Off也就是彻底脱离总线。这个设计是为了防止某个故障节点一直发错误帧把整条总线拖垮。我在调试时遇到过节点频繁Bus Off最后查出来是波特率配置差了那么一点点导致位采样点偏移错误累积。所以波特率配置必须精确到每个节点的晶振误差范围内后面位定时那节会细讲。4. CAN-FD到底改了什么不只是快是整套时序逻辑的重构4.1 可变速率仲裁段慢、数据段快CAN-FD最核心的变化是引入了两个位速率仲裁段位速率Nominal Bit Rate和数据段位速率Data Bit Rate。仲裁段必须跟经典CAN兼容所以还是用原来的速率通常500kbps或1Mbps。一旦仲裁结束、进入数据段节点切换到更高的速率常见2M、5M甚至8Mbps。为什么要分开因为仲裁需要所有节点同步比较速率越高对线长和拓扑越敏感所以仲裁段必须保守。而数据段是点对点传输只有发送方和接收方参与可以激进一些。这个设计让FD在保持兼容的同时把有效吞吐提上去了。但这里有个大坑数据段速率越高对收发器和布线要求越苛刻。经典CAN收发器在5Mbps下边沿可能跟不上必须换FD专用收发器。我做过对比测试同一套线束用普通收发器跑2Mbps数据段勉强能通换FD收发器后5Mbps都很稳。所以迁移FD时收发器选型是第一步不能省。4.2 数据长度扩展到64字节与新的DLC编码前面提过FD的DLC编码变了。0到8还是对应0到8字节但9到15分别对应12、16、20、24、32、48、64。为什么不是连续的因为FD允许数据长度不是2的幂但为了简化实现只定义了这几档。实际用的时候如果你要传20字节DLC填10实际发20字节接收端按DLC查表得到20。这个设计带来的好处是协议开销大幅降低。经典CAN传64字节需要8帧每帧都有仲裁场、CRC、ACK开销巨大。FD一帧搞定有效载荷占比从不到50%提到80%以上。做刷写和标定时这个提升非常明显我实测同一段固件用FD刷写比经典CAN快4倍以上。4.3 位填充与CRC的调整FD在数据段用了更强的CRC数据长度小于16字节用17位CRC大于16字节用21位CRC。同时位填充规则也调整了数据段允许更长的连续相同位因为高速下填充太频繁会浪费带宽。这些细节在写底层驱动时必须严格按协议实现否则跟标准节点通信会出CRC错误。还有一个容易忽略的点FD帧没有远程帧RTR位被保留并固定为显性。所以FD网络里不能再用远程请求那套逻辑架构设计时要改成周期广播或事件触发。5. 位定时配置让CAN跑起来容易跑稳难5.1 位时间的四段划分与采样点一个CAN位时间被分成四段同步段Sync、传播段Prop、相位缓冲段1Phase1、相位缓冲段2Phase2。采样点位于Phase1结束处。同步段固定1个时间份额Tq其他三段可配置。采样点的位置用百分比表示经典CAN推荐75%到87.5%FD数据段推荐60%到75%因为速率高留更多余量给相位缓冲。这个百分比不是随便定的它决定了你对晶振误差和传播延迟的容忍度。我调过一个案例两个节点都用8MHz晶振但一个误差0.5%一个-0.5%波特率配500kbps采样点都设87.5%。低速下能通但一上1Mbps就间歇性错误。后来把采样点降到80%问题消失。原因是采样点太靠后留给Phase2的缓冲不够累积的相位误差没地方吸收。5.2 波特率计算从晶振到Tq的完整推导假设晶振8MHz预分频器BRP设为1则Tq 2 × BRP / f_clk 2/8M 250ns。一个位时间由Sync Prop Phase1 Phase2组成总Tq数设为16则位时间4us波特率250kbps。要500kbps就把总Tq数降到8或者提高晶振频率。实际配置时大多数MCU的CAN控制器提供BRP、SJW、TSEG1、TSEG2四个参数。TSEG1 Prop Phase1TSEG2 Phase2SJW是同步跳转宽度决定一次同步能调整多少Tq。SJW一般设为1到4太大容易受干扰误同步太小则容错差。提示配置完位定时后一定要用示波器测实际位宽或者用CAN分析仪看错误计数。纸面计算和实际总有偏差尤其是晶振精度和收发器延迟。5.3 采样点不一致导致的玄学通信故障我遇到过最诡异的一次故障两个节点单独跟分析仪通信都正常但两个节点互相通信就随机丢帧。查了三天最后发现两个节点的采样点差了10%。一个设75%一个设87.5%。单独通信时分析仪采样点居中两边都能对上两个节点互发时采样点靠前的那个在对方还没稳定时就采样偶尔采错。这个坑的教训是同一网络里所有节点的位定时参数必须统一尤其是采样点。做架构设计时位定时配置应该作为网络规范的一部分写进文档而不是让每个节点开发者自己拍脑袋。6. 从经典CAN迁移到CAN-FD的实战踩坑记录6.1 收发器不换速率上不去前面提过但值得再强调。经典CAN收发器如TJA1050数据段速率超过2Mbps时边沿严重退化。FD专用收发器如TJA1044、TJA1057支持到5Mbps甚至8Mbps。迁移第一步就是换收发器别想着省这个钱。我做过一个对比实验同一块板子同一段线束只换收发器。经典收发器在2Mbps数据段下错误率约10的负4次方FD收发器在5Mbps下错误率低于10的负7次方。差距是数量级的。6.2 终端电阻与拓扑的重新评估FD速率提高后对反射更敏感。原来经典CAN能容忍的短分支stub在FD下可能就成了问题。建议FD网络尽量用总线型拓扑分支长度控制在几厘米以内。终端电阻还是120欧姆两端但如果速率上到5Mbps以上可能需要用分裂终端两个60欧姆串联中间接地来改善共模特性。6.3 软件层的兼容性处理FD控制器通常兼容经典CAN帧但反过来不行。所以迁移时可以先让新节点支持FD老节点继续用经典帧网络里混跑。但要注意FD帧的仲裁段跟经典帧一样所以混跑时仲裁没问题但数据段速率不同老节点收到FD帧会报错。解决办法是FD帧只在支持FD的节点之间发或者用FD的无FD帧模式也就是数据段也用仲裁段速率来兼容。我在一个混跑项目里用的策略是安全关键报文继续用经典帧大块数据标定、日志用FD帧并且FD帧的ID段跟经典帧错开避免老节点误收。这个方案跑了一年多没出过问题。7. 调试工具与实测方法没有分析仪等于盲调7.1 CAN分析仪的选型与使用调试CAN离不开分析仪。入门级可以用带CAN的USB转接盒配合开源软件看报文。但要做FD调试必须用支持FD的分析仪否则你连帧都收不全。我手头常用的是一台支持双通道CAN-FD的分析仪能同时抓两路总线做对比排查网关问题时特别有用。使用分析仪时一定要打开错误帧显示。很多人只看数据帧忽略了错误帧结果通信时好时坏找不到原因。错误帧里包含了错误类型和位置能直接指向问题。7.2 示波器看眼图判断信号质量的终极手段分析仪告诉你错了示波器告诉你为什么错。用示波器看CAN波形重点看几个地方显性电平幅度是否够差分2V左右、边沿是否陡峭上升时间、隐性电平是否干净有没有反射鼓包、位宽是否一致有没有抖动。我习惯把示波器设成差分探头直接看CAN_H减CAN_L。正常波形应该是干净的方波如果看到振铃、台阶、或者幅度不够就是物理层问题。有一次查一个间歇性故障示波器上看到每帧最后一个字节的边沿明显变缓最后发现是那个节点的收发器供电滤波电容失效了。7.3 压力测试让问题在台架上暴露台架测试一定要做压力测试不能只做功能测试。方法很简单让总线负载率跑到70%以上持续跑几个小时同时用分析仪统计错误帧。如果错误率随负载上升而上升说明位定时或物理层有隐患。我还习惯做温度测试把节点放到温箱里从-40度到85度循环同时跑通信。CAN收发器的延迟随温度变化极端温度下采样点偏移可能暴露出来。这个测试帮我提前发现过一批晶振温漂过大的问题。8. 一些没人写在手册里的经验最后分享几个我在实际项目里攒下来的经验都是手册上不会写的。第一ID分配表要留余量。我见过太多项目后期加功能时ID不够用只能重新规划牵一发动全身。建议按功能域分段每段留20%余量。第二总线负载率不要超过50%。虽然理论上CAN能跑到80%以上但实际工程里超过50%后延迟抖动明显变大安全关键报文的实时性没法保证。FD虽然带宽大了但负载率控制原则一样。第三每个节点上电后先自检再上线。我遇到过节点因为初始化失败一直发错误帧把整条总线拖到Bus Off。后来在软件里加了自检逻辑初始化不通过就不使能CAN控制器问题再没出现过。第四保留一份完整的网络数据库文件DBC。所有报文的ID、周期、信号定义、字节序都写在里面用工具生成代码和文档。没有DBC的网络维护起来就是灾难。我接手过一个没有DBC的遗留项目光整理报文定义就花了两周。第五FD的64字节不是越多越好。数据段越长一帧占用总线时间越长高优先级报文的延迟就越大。我一般建议单帧不超过32字节超过就拆帧平衡效率和实时性。这些经验听起来简单但每一条背后都是真金白银的调试时间换来的。CAN和CAN-FD这套东西入门不难难的是在复杂电磁环境和严苛实时性要求下把它跑稳。希望这篇能帮你少踩几个我踩过的坑。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑