尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
CAN总线从原理到调试:帧结构、终端电阻与错误帧排查
上周一个做车载设备的朋友发来一张CAN总线的波形图问我说“你看这波形能跑吗”图上空闲电平是2.5V报文出来一瞬间差分电压只有0.8V左右。我说能跑也是勉强跑因为ISO 11898-2规定接收端把差分电压大于0.9V才算显性你这个0.8V已经踩在阈值边缘线束再长一点、干扰再强一点错误帧就会开始刷屏。这种事在CAN总线调试里实在太典型了协议看上去不难但物理层稍微不达标上层就花式报错。这篇“CAN总线详细讲解”我就顺着这个路子展开从帧结构、SRR位这种容易搞混的协议细节到终端电阻、并联分支长度、总线保护电路这些物理层实操再落到调试抓包和常见错误排查。适合刚接触CAN的嵌入式工程师、做汽车电子的朋友以及用CAN做机器人、工业设备、储能设备的同学慢慢读。本文默认你已经知道CAN是两条线的总线但不太清楚底层怎么工作——我会尽量把“为什么”也讲透。1. 理解CAN的第一步为什么靠两条线就能撑起整车通信1.1 差分信号两根线之间的“电势差”才是真正信息CAN总线物理层用CANH和CANL两根线正常空闲时两根线都稳定在2.5V左右。接收端真正判断的不是某根线对地的绝对电压而是CANH减去CANL的差值。显性位时发送器把CANH拉高到3.5V、把CANL拉低到1.5V差分电压约2V隐性位时两根线都回到2.5V差分电压接近0V。为什么非要用差分如果用UART那种单端信号逻辑电平参考的是本地地而车上电机、点火线圈、继电器产生的共模噪声会直接叠加到参考地上稍微来点尖峰逻辑就要翻转。CAN用两根线同时受干扰时CANH和CANL会一起上下浮动但两者之间的差值基本不变干扰就在接收端被抵消掉了。这个思路生活里也有类比两个人用麦克风唱歌你只听两人之间的声压差现场噪音再大只要同时作用于两个麦克风差值里基本没有噪音成分。接收端还留了滞回窗口差分电压小于0.5V判为隐性大于0.9V判为显性中间这段既不算0也不算1。这样设计的好处是波形即使有一点振铃和过冲也不容易在阈值边缘反复横跳。但反过来说如果显性差分电压只有0.8V余量就非常小稍微来点共模噪声接收端就可能把一个显性位读成隐性位错误随之而来。1.2 多主仲裁谁先说话由“逻辑0”说了算CAN不是主从总线没有中心节点。理论上任何节点准备好就能往总线上发那多个节点同时发送怎么办CAN用的是载波侦听多路访问加上非破坏性的位仲裁机制。原理其实不复杂总线上逻辑0是显性逻辑1是隐性显性电平会覆盖隐性电平。每个发送节点在发出一位之后会立刻回读总线状态做比较。如果自己发的是隐性位却读到显性说明有另一个节点在发优先级更高的帧自己就立刻退出发送等下次总线空闲再重试。所以仲裁拼的是帧ID数值ID越小优先级越高。打个比方会议室里一群人同时开口规则是“数字最小的人先说”。CAN比这个更聪明的地方在于它不需要等大家说完再判断在边说边听的过程中就能实时确认谁的数字最小。高优先级报文只需要等到总线空闲甚至可以在冲突发生的那个位周期内就胜出延迟上界非常短。这个机制是CAN能用于刹车、转向等实时控制信号的根本原因。对于主从式总线主节点轮询一圈可能几十毫秒而CAN的优先级抢占基本上可以让重要报文在几个毫秒内送达而且最坏延迟可预测。1.3 一帧最多8字节短报文反而更“抗造”经典CAN的数据场最多8字节放在今天看确实不大可是这是80年代的设计决策。当时单片机内存小总线速率也不高一帧传太多数据会长时间占用总线对实时性非常不利。8字节意味着一个报文在1Mbps下算上帧头、仲裁、CRC、ACK这些开销占用总线时间也就是一百来微秒。哪怕十几个节点同时在抢重要报文也能在毫秒级窗口内完成刷新。后来博世做CAN FD才把数据场扩展到64字节同时保留了经典CAN的帧格式用于兼容。实际工程里也形成一个习惯很多老工程师拿到新需求第一反应仍然是把一个信号拆成几个8字节帧而不是盲目上CAN FD。数据短意味着单帧出错的代价小。配合下面要说的CRC校验和硬件自动重发机制整个网络在中等干扰环境下非常皮实。这也是CAN在发动机舱、工业现场这种恶劣环境里几十年不退休的原因之一。2. 一帧报文从头到尾帧结构、SRR位与错误检测2.1 数据帧的七段结构逐段拆开看CAN数据帧从起始位SOF开始到帧结束EOF结束。我把各段的作用整理成一张表调试时对照解码器看会很清晰段长度/内容作用SOF1位显性同步所有节点宣布总线从空闲转到忙碌仲裁场11位或29位ID RTR/SRR等决定帧优先级和帧类型控制场IDE、r0/r1、DLC标记标准帧还是扩展帧声明数据长度数据场0~8字节真正要传的数据内容CRC场15位CRC 1位隐性分隔符校验数据完整性ACK场ACK槽1位 分隔符1位接收节点回显性表示正确收到EOF7位隐性帧结束标记这里最关键的一个认知转变是CAN的标识符ID不是设备的地址而是“内容的标识”。同一个ID的帧可以被多个节点接收这就是CAN天然支持多播的原因。节点到底收不收某一帧是按ID掩码做滤波跟“发给谁”没有直接关系。很多从UART转过来的人总想找一个“目的地址”字段怎么找都找不到就是还没转过这个弯。2.2 标准帧和扩展帧仲裁场完全不同CAN 2.0A定义了标准帧2.0B定义了扩展帧。标准帧的仲裁场是“11位ID RTR位”扩展帧的仲裁场则是“11位基本ID SRR位 IDE位 18位扩展ID RTR位”。网上很多资料只告诉你“扩展帧ID变长了”这个说法不够准确仲裁场的位布局完全变了。对数据帧来说标准帧的RTR位置是隐性扩展帧的SRR位置也固定是隐性所以这两者在仲裁时不会因为“请求位”产生冲突。真正的帧类型区分是在后续的IDE位上表态。这也是后面SRR位容易被人误解的根源。如果你用示波器看扩展帧波形前面仲裁段的长度明显比标准帧长不少。总线判优先级时并不是先看完整ID再决定而是从SOF之后逐位比较谁先发出显性谁就赢。所以理解仲裁不能只看“谁的ID数字小”必须结合位顺序和显性/隐性电平一起看。2.3 SRR位被误解最多的“替代远程请求”SRR全称是Substitute Remote Request直译是“替代远程请求”。这个位为什么存在因为标准帧里本来有一个RTR占位到了扩展帧这个位置必须放点东西占住否则老节点在逐位仲裁时会对不上节奏。SRR被设计成固定隐性位而扩展帧真正的远程请求位被放到了18位扩展ID后面仍然叫RTR。很多初学者以为SRR就是“扩展帧里的RTR”其实不对。SRR既不请求数据也不参与远程帧判断它的作用就是占位加参与仲裁。但占位符照样影响优先级如果两个节点同时发相同基本ID的帧一个是标准数据帧一个是扩展帧标准数据帧的RTR是隐性扩展帧的SRR也是隐性先打平接下来标准帧走的是IDE位标准帧的IDE是显性扩展帧的IDE是隐性显性压过隐性标准帧胜出。所以“相同基本ID时标准帧优先于扩展帧”这句话在数据帧和远程帧的场合基本都成立原因就在这一串位设计上。要注意的是CAN总线的远程帧实际使用得比较少更多场景是用数据帧覆盖—发送方周期性地主动发数据而不是靠对方来“请求”。即便如此SRR位仍然是理解扩展帧仲裁绕不过去的细节面试和实际抓包都会遇到。2.4 位填充与CRC靠什么在噪声里保住一帧数据CAN的可靠性不只靠差分信号协议层还做了两道保险。第一道是位填充机制发送端在连续出现5个相同电平后强制插入一位相反电平接收端如果发现连续6个相同电平就直接判定为填充错误。填充位的好处之一是给接收节点提供额外的跳变沿帮助恢复时钟同步代价是带宽损失最坏情况下会多出约20%的位时间开销。第二道是CRC校验。CRC场的15位CRC覆盖从SOF到数据场的全部内容接收端计算不一致就会丢弃该帧并且不会在ACK槽回显性。发送方看到ACK槽没有被拉低就知道发送失败硬件会自动重发。这个自动重发机制对应用层完全透明你不需要在代码里处理重传只要把一帧数据塞给CAN控制器剩下全部由硬件负责。位填充、CRC校验、自动重发这三件事叠加在一起让CAN在中等干扰环境下的误码率可以压得很低这也是它能在发动机舱这种恶劣环境里稳定工作几十年的底气。3. 物理层和布线的门道终端电阻、并联分支长度、保护电路3.1 120欧终端电阻为什么必须放在总线两端CAN总线电缆的特性阻抗典型值是120欧所以规范要求在物理拓扑的两端各放一个120欧终端电阻。为什么非要匹配信号在电缆里传输走到末端时如果阻抗突变一部分能量会反射回来。反射波叠加到后续信号上就会在边沿处产生振铃严重时直接超过接收阈值造成误判。终端电阻的实质是让信号“感觉”电缆还在延续把末端反射吸收掉。实测经验是单端终端或者完全没有终端波特率低的时候可能还能跑但波形上升沿会有明显过冲。一旦线长拉到几十米或者波特率上到500k以上错误帧就开始刷屏。很多汽车ECU内部已经把终端电阻做进去了常见做法是两个60欧串联中点通过电容接地既匹配差分阻抗又给共模噪声一个低阻泄放路径。自己画板子我也建议用这个结构电阻选1%精度别凑合。终端电阻该放几个答案是两个放在总线物理距离的两端。如果一个节点已经内置了终端另一个远端必须再放一个否则整个网络只有一个终端反射问题依然存在。用万用表在总线上测量终端电阻正常值应该是60欧左右这是两个120欧并联的结果。3.2 并联分支长度到底指哪段干线到节点的“支线”有段时间后台搜“can总线并联分支的长度是指哪个长度”这个关键词的人特别多那我直接回答它指的是从主传输干线引出的节点接入线也就是干线到节点收发器引脚之间的这一段支线通常叫stub。它不是指整条总线并联后的总阻抗长度更不是总线总长度。理想拓扑是手拉手的菊花链每个节点尽量直接挂到主线上。现实工程总有接插件离得远不得不用一段支线拉出来。问题就出在这段支线上支线末端的节点收发器输入阻抗很高信号传到那里会反弹反射波回到干线后再叠加到后续信号上形成振铃。支线越长往返延迟越大振铃越容易落在采样点附近。工程上有一个经验范围按波特率控制支线上限波特率建议支线上限1 Mbps0.3m左右500 kbps0.6m左右250 kbps1.2m左右125 kbps2.5m左右为什么是这个数量级信号在普通线缆里的传播速度约0.2m/ns。0.3m支线的往返延迟只有3ns在1Mbps下位时间是1us3ns只占0.3%基本可以忽略但如果支线拉到3m往返延迟就变成30ns占了采样窗口的3%以上再多几个节点的反射叠加起来波形就会很难看。所以我的建议很简单能用短支线就一定用短支线迫不得已要长时要么降低波特率要么用CAN中继器/集线器把星型拓扑转成规范接入不要硬上。3.3 总线保护电路怎么搭TVS、共模电感和防反接做车载、工业设备的都知道CAN口不像板内信号它直接暴露在接插件上静电、浪涌、线束短路、反接都可能遇到。最基本的保护方案是在连接器后面放一颗CAN专用TVS管钳位共模浪涌再串一对共模电感滤掉共模干扰总线对地放100pF到1nF的小电容滤高频噪声。这里有两个选型要点。第一TVS结电容会影响信号边沿不要随便拿一颗通用TVS就往上怼优先选低结电容的CAN专用型号比如SM712这类常见器件。第二对地电容不能贪大不然高波特率下上升沿变缓反而引入位错误。现代收发器普遍内置斜率控制、过流保护和热关断选TJA1050/1042这一档处理一般短路问题不大。如果节点之间地电位差很大比如电机驱动器和控制器之间建议用隔离收发器或加DC-DC隔离电源别让共模电压变成烧板元凶。电路顺序可以这样组织接插件进线先过TVS再过共模电感然后到终端电阻最后进收发器。示意如下[CANH接插件] → [TVS管] → [共模电感L1] → [终端电阻组合] → [收发器CANH] [CANL接插件] → [TVS管至CANH/地] → [共模电感L1] → [终端电阻组合] → [收发器CANL] 终端电阻组合两只60欧串联在CANH-CANL之间中点经4.7nF电容接地一句话总结这套做法先把外界能量挡在防护器件上再让差分信号穿过滤波网络最后进入收发器。这几块钱的器件真的不能省一个CAN收发器烧掉整条总线的节点都可能跟着遭殃。3.4 汽车CAN电路图怎么看汽车总线一般分动力CAN和车身CAN波特率不同大多数ECU内部已经集成了终端电阻通常挂在总线物理末端。拿到一张CAN电路图我习惯三步走先找终端电阻两个60欧串联或一个120欧找不到就看看是不是在网关或者某个ECU内部再找收发器型号判定供电电压、静音模式引脚怎么接、TXD/RXD连到MCU的哪个引脚很多MCU片内已经自带CAN控制器只需要外接收发器最后顺着CANH和CANL往外走检查有没有TVS、共模电感、防反接二极管接插件处有没有做ESD保护。车辆诊断口上CAN-H和CAN-L通常是第6和第14脚诊断仪就是靠这对线读出整车数据。看到一版图纸里CAN节点挂得密密麻麻不要慌CAN节点的连接其实就是所有ECU并联在同一对双绞线上。规范的接法是“手拉手”的菊花链如果图纸画出来是星型或者一堆很长的支线就要多留个心眼调试时优先怀疑装配妥协带来的反射问题。4. 调试实录抓包、波形判读与错误帧排查4.1 工具与接线别一上来就插分析仪读报文调试CAN不需要多贵的设备但接线和配置顺序很容易出错。我现场通常备四样东西万用表、双通道示波器、USB-CAN分析仪、逻辑分析仪。拿到一套通信不上的设备第一件事先断电用万用表量总线两端的终端电阻。标准值应该是60欧左右如果量到120欧说明只有一个终端量到无穷大说明至少一端没接电阻。上电后再量静态电平CANH和CANL都应该在2.5V附近。CANH偏低或者CANL偏高说明收发器的偏置或共模处理有问题。接着抓波形看显性时差分电压是否足够边沿有没有振铃。最后才用分析仪看协议层。这个顺序可以把物理层和协议层分开定位。我见过太多团队拿着分析仪一通抓包报文解码看着都对但设备就是偶发故障最后发现是终端电阻少了一颗。工具分工大致如下工具主要看什么注意点万用表终端电阻、短路、静态电平断电测终端上电测电平示波器差分波形、振铃、采样点、位宽探头地线要短有差分探头更好USB-CAN分析仪报文内容、错误帧、总线负载率确认波特率和采样点别盲目自动识别逻辑分析仪协议解码、错误帧现场采样率至少8倍波特率以上4.2 看波形先看这四个地方判读CAN波形我习惯看四处静态电平是否稳定在2.5V上下显性位的差分电压够不够猛理想是2V至少要明显大于1V上升沿和下降沿有没有明显过冲或振铃位时间宽度与配置的波特率是否吻合。采样点这个概念也必须理解透。CAN接收端在一个位时间的大约70%到80%位置采样电平。采样点太靠后离下一个边沿太近总线上只要有一点信号延迟就容易采错采样点太靠前又可能把前一位的尾巴当成当前值。这个值由CAN控制器的TSEG1/TSEG2寄存器配出来。如果你有两台不同厂商的设备波特率相同但采样点差异很大就会出现偶发错误帧这是多设备混用时的经典坑。4.3 波特率与采样点的一个计算实例拿STM32F103的bxCAN举例APB1时钟是36MHz目标是1Mbps。CAN位时间由同步段1个tq、TSEG1和TSEG2组成波特率等于APB1时钟除以预分频值再除以位时间tq数量。我常用的配置是预分频4TSEG16TSEG22SJW1。算一下tq 36MHz / 4 9MHz也就是111ns位时间 1 6 2 9个tq正好1us对应1Mbps。采样点 (1 6) / 9 77.8%这个值在短总线场景下很稳。CAN_InitStructure.CAN_SJW CAN_SJW_1tq; CAN_InitStructure.CAN_BS1 CAN_BS1_6tq; CAN_InitStructure.CAN_BS2 CAN_BS2_2tq; CAN_InitStructure.CAN_Prescaler 4;如果总线比较长我会把采样点往75%附近调比如TSEG15、TSEG22那位时间变成8个tq预分频也要相应调整。关键还是理解公式不要背一组参数到处套。4.4 错误帧是调试里最有用的信息CAN控制器会统计并上报不同类型的错误。我把常见的错误类型和排查方向整理成速查表错误类型含义优先排查ACK错误发送帧的ACK槽没有被任何节点回显性是否只有单节点在工作、接收节点是否处于只听模式位错误发送方回读电平与自己发的不一致总线短路、终端缺失、多节点冲突、收发器损坏填充错误收到连续6个相同电平波特率不匹配、干扰太强、收发器边沿太差CRC错误CRC校验失败线缆过长、终端匹配差、接触不良、外部干扰显性位错误本应隐性的位置读到显性节点故障、错误帧风暴、总线被一直拉低排查思路永远是先按4.1节查物理层再抓错误发生时的波形。如果错误帧分布没有规律优先怀疑干扰源和地电位差如果错误帧集中在某个节点发送时段优先怀疑那个节点的晶振偏差或收发器性能。4.5 我踩过的几个坑写出来给大家避雷第一个坑两个节点通信我只在一端放了120欧终端电阻另一端省了。低速时一切正常一上500k就开始丢帧。补上第二颗电阻后世界清静了。答案是CAN必须两端都有终端只有一端不行。第二个坑为了装配方便把一个节点支线拉到差不多两米看起来只是“一根细线”结果高速下频繁出现CRC错误。把支线缩短到0.5米内问题彻底消失。支线长度这件事真的不能懒。第三个坑把屏蔽层在两端都接地结果形成地环路低频共模电流在屏蔽层上跑来跑去波形出现低频漂移。改成单端接地后稳定了。第四个坑用万用表在线测终端电阻量出好几个奇怪数值。原因很简单收发器内部的偏置电路也在回路上“捣乱”。正确做法是断电后测量或者把疑似节点暂时断开再测。这些坑单独看都很小但组合起来能让人折腾一整天。多花十分钟做物理层检查比在协议层猜问题高效得多。5. 写在最后的实操体会做CAN相关调试这些年我最大的体会是这总线的门槛不在协议理解而在工程细节。帧结构、仲裁、CRC认真读一天就能讲完但真正让项目翻车的往往是120欧电阻少了一颗、支线多拉了几米、地电位差没处理好这类“小事”。所以我现在接手新项目第一件事就是定物理层验收标准终端电阻必须实测、静态电平必须在正常范围、显性差分电压要留足余量、波形边沿不能有明显振铃。这一套做完再谈报文不迟。我也强烈建议所有做CAN产品的人都留一组调试测试点把CANH、CANL、GND引到方便测量的位置丝印标清楚现场能省一大半时间。调试接口不是成本是保险。最后再说一句实在话。CAN这套设计虽然出身早但它的差分传输、非破坏性仲裁、错误恢复机制到今天仍然是各种总线的重要参考。把这些基本功打扎实后面换CAN FD、CANopen、J1939都只是换了个外壳内功是相通的。
RELATED

相关推荐

Python asyncio并发采集数百台Modbus TCP温湿度变送器实战

Python asyncio并发采集数百台Modbus TCP温湿度变送器实战

1. 项目缘起与整体架构思路1.1 为什么会有这个采集需求做过机房动环监控或者仓储环境监测的朋友应该都有体会:当你要监控的温湿度点位从几个变成几十个、上百个的时候,事情的性质就完全变了。早期我用轮询的方式,一台一台设备去读&#xff0c…

📅 2026/9/29 11:24:51
物电学子专访:循序渐进厚积薄发,从专业中游到保研双一流的成长模型

物电学子专访:循序渐进厚积薄发,从专业中游到保研双一流的成长模型

1. 认识这位“厚积薄发”的物电学子:李承泽物电学院的楼道里经常能看到这样一个身影:背着双肩包,手里拿着一个记满公式的旧本子,见人就笑。他是李承泽,2021级应用物理专业学生,国家奖学金获得者&#xff0c…

📅 2026/9/29 11:24:51
C/C++ static关键字全面解析:存储期、链接属性与工程实践

C/C++ static关键字全面解析:存储期、链接属性与工程实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/9/29 11:24:51
MORE NEWS

更多资讯

📰

技术速递|Agent 模式对所有用户开放:VS Code 中启用 chat.agent.enabled 并接入 MCP

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

IMX6ULL | SPI 协议详解与 ADXL345 加速度传感器

一、SPI 基础介绍SPI 是高速同步串行通信接口,通信速度远高于 I2C。I2C 速率:100K、400K、1.xM、最高 3.4MHzSPI 速率:1MHz ~ 上百 MHz,常用于驱动 OLED、加速度计等外设。SPI 传输特点:高位先行。SPI 四根信号线引脚名…

📰

用 ±1% 计量精度做机房 PUE 测算:PDU 级电量采集的数据链路

用 1% 计量精度做机房 PUE 测算:PDU 级电量采集的数据链路 PUE 是数据中心最常被引用、也最容易被算错的指标。 问题往往不在公式(公式很简单),而在分子分母的数据来自不同精度、不同采样窗口的采集点。这篇从 PDU 级计量出发&…

📰

智慧档案馆八防数字化落地:边缘计算与状态机实现库房自治

档案库房这地方,外行看就是一间放满铁皮柜的大屋子,内行才知道它是个微气候环境、生物环境、电磁环境叠加的复杂系统。防火、防盗、防潮、防光、防尘、防虫、防鼠、防高温,这"八防"喊了几十年,但真正落到数字化系统里&a…

📰

AI编程Skill实战指南:从安装到自建,让AI自带老师傅经验

聊到AI编程,绕不开一个词:Skill。很多人以为AI写代码就是复制粘贴提示词,但真拿它做项目时你会发现,模型不缺语法知识,缺的是“项目经验”。它会给你写出一段能跑的demo,却不知道你团队用的是什么架构、哪个…

📰

GEO底层机制拆解:AI搜索如何决定企业内容的可见度

一、企业搜索结果可见度的四个常见问题传统搜索引擎优化围绕网页排名展开,企业竞争的是链接位置。但当用户转向豆包、文心一言、DeepSeek等对话大模型提问时,游戏规则变了。第一个问题是:企业内容不被AI引用,即便官网排名靠前&…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬