十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

CAN总线原理与实战:差分信号、仲裁机制及达妙关节电机控制

CAN总线原理与实战:差分信号、仲裁机制及达妙关节电机控制 拆过任意一台量产车的门板、机舱或者仪表台你大概率会对它的线束感到震惊一捆又一捆的铜线几十上百个端子密密麻麻的插头。可如果你再细看会发现有一两根双绞线像脊梁一样贯串整车所有节点都挂在上面什么发动机电脑、ABS泵、车窗开关、气囊模块全在这根总线上说话。这根线就是CAN总线。它也是绝大多数工业机器人、协作机械臂、无人车、竞赛机器人的关节控制骨干。这篇文章我打算换个讲法不按教科书顺序铺物理层、数据链路层那种八股而是围绕你真正会碰到的三个问题来展开电压差到底是怎么变出来的、一帧报文如何在总线上抢到“发言权”、以及达妙这类关节电机靠CAN怎么做出精准的位置控制。同时我会把现场排查的实操流程一起放进来修车、做机器人、搞嵌入式、跑自动化产线的人都能直接用上。文章里涉及的一些协议细节不同厂家会各有定义我会标注清楚避免误导你去套某个具体产品。1. CAN总线为什么无处不在从整车到机器人的共同答案1.1 没有CAN的年代控制信号线是怎么把车“塞满”的如果你开过或者坐过二十年前的家用车一定记得车门里那根沉重的手摇窗机构。往后的电动车窗版本每个车门里就是一大捆橡胶皮包裹的线束升窗开关三根线、门锁电机两根、后视镜调节三四根、喇叭两根底盘上还要再拉过去。四个门加起来光是门控部分就是五六十根导线。模块之间哪怕只是交换一位“车门锁上没锁”的信息都必须在两个控制器之间专门拉一根线。信号越来越多线束就有几十公斤重插接器成百上千个任何一个端子接触不良都可能造成某个功能失效排查起来翻遍整车线束。CAN总线解决这个问题的核心逻辑其实很朴素不再让每两个设备之间单独“谈恋爱”而是让所有设备挂到一根公共的“会议电话线”上谁有话说就说大家都能听见说的话一句话就能覆盖所有听众。对量产的乘用车来说整车的动力系统、车身控制、信息娱乐各自区域只需要一根或几根CAN总线线束重量直接下降四成以上可靠性还提升了因为接点变少了。1.2 CAN被选中不是因为它复杂而是因为它“恰好的憨厚”工业界其实早就有一堆选择RS232、RS485、SPI、I2C、以太网。为什么汽车和机器人最后都大量采用CAN我个人的理解是CAN在以下三个方面做到了当时的最优平衡多主同时发送不怕冲突。RS485是典型的主从半双工主机不点名从机不能发言CAN则是多主架构任何一个节点检测到总线空闲就能抢着发数据而且它通过在报文ID上的“线与”机制自动解决冲突优先级低的节点会主动让路不需要主机干预这种实时性对车辆安全至关重要。传输距离和速率足够用。CAN在500kbps位速率下可以可靠传输几百米在1Mbps下也有一百多米的能力。车内一根总线最长也就几米到二十米机器人关节之间的线更短这个组合绰绰有余。硬件错误处理能力强。CAN控制器内置CRC校验、位填充错误检测、位监控、报文格式检查、ACK确认等多层防护节点自己会统计错误并主动断开总线防止“一个坏节点拖垮全车”。RS232点对点RS485主从轮询以太网需要交换机和协议栈。真正到了“一挂几十个节点实时性以毫秒计还要便宜抗干扰”的场景CAN在很长一段时间里没有对手。后来CAN FD和CAN XL出来本质上是沿用了同样的总线访问机制把数据段加长了、速率拉高了但物理层和仲裁逻辑仍然是CAN那套东西。所以把经典CAN吃透后面再学CAN FD就是水到渠成。1.3 说清区别物理层、链路层、应用层分别是谁的地盘很多同学调不通CAN就是因为把三层混在一起排查。我用大白话划分一下物理层管“信号在线上长什么样”。比如CAN_H和CAN_L的电压是多少怎么表示0和1总线末端为什么要接120欧电阻这都在物理层。数据链路层管“报文怎么组装、怎么发送、怎么确认”。11位ID、数据场、CRC、ACK、仲裁退避这是CAN控制器芯片自动完成的你只需要调用它的寄存器或库函数。应用层管“ID和数据的含义”。比如ID 0x200是底盘控制帧前两个字节是方向盘转角量程多少、单位是多少再比如电机驱动器的0x201反馈帧里哪两个字节是转速哪两个字节是角度。这是厂商定义或你自己约定的。我做项目时的排查习惯是先测物理层再抓链路层的帧最后才怀疑应用层数据解析。按照这个顺序走一遍大多数问题十分钟内能锁死位置而不是上来就翻开协议手册对着数据琢磨半天。2. 物理层核心CAN_H和CAN_L之间的电压差到底是怎么变出来的2.1 显性位和隐性位一对“主动”和“默认”的组合网上几乎每一篇讲CAN的文章都会告诉你CAN总线有显性电平Dominant和隐性电平Recessive两种状态显性对应逻辑0隐性对应逻辑1。但很多人没讲清楚一件事显性是主动驱动的结果隐性是没人驱动时的默认状态。CAN收发器比如TJA1050、SN65HVD230、MCP2551这些芯片内部有差分输出级。当它要发送隐性位逻辑1时发送端的两路驱动管都处于高阻状态不主动拉高也不主动拉低。这时候CAN_H和CAN_L在总线两端120Ω终端电阻的分压作用下会被拉到同一个电位通常是2.5V左右也就是电源电压的一半。两条线之间的差分电压接近0V。当它要发送显性位逻辑0时收发器内部的驱动级才真正“使劲”把CAN_H往高拉典型值是3.5V同时把CAN_L往低拉典型值是1.5V两条线之间的差分电压大概是2V。接收端把差分电压和阈值比较超过大约0.9V就判定为显性0低于0.5V就判定为隐性1。所以“电压差是怎么改变的”这个问题的本质就是驱动管打开与关闭。打开两条线的电位被硬生生掰开产生约2V的差压关闭终端电阻网络把两条线“拽”回到同一个中点差压回到0V附近。这个机制非常像一群人共用一个扬声器没有人按键时对讲机处于安静的待机状态隐性有人按住通话键时喇叭里才有声音显性。我用示波器抓过很多次总线波形正常情况下静态总线的CAN_H对GND是2.5V左右CAN_L对GND也是2.5V左右二者的对地电压波形几乎以2.5V为中点上下对称。一旦某一端电压明显偏了比如CAN_H只有1.8V或者CAN_L到了3.8V那多半是某个节点收发器异常或者总线上存在对电源/对地的短路。2.2 为什么必须用差分信号还要配120Ω终端电阻既然有两种电平为什么不用单根线拉高低电平来传答案还是抗干扰和可靠性。车辆发动机舱里电磁干扰极其凶残点火线圈、电机的换向火花、大功率逆变器随时在辐射噪声。单端信号线的电压会被外界噪声拉偏接收端就很难分清0和1。CAN的差分设计让干扰带来的影响“同进同出”外界电磁噪声作用在双绞线上时两根线被干扰的程度基本一致CAN_H和CAN_L同时抬高或同时降低而接收端看的是两者之差干扰被抵消掉了。就像两个人一起站在晃动的船上量高度差船体整体起伏不影响他们俩谁高谁矮的判断。终端电阻的作用是消除信号反射。任何传输线都有自己的特征阻抗CAN双绞线的特征阻抗大约是120Ω。信号在线上传播到末端时如果末端阻抗和特征阻抗不一致就会发生反射导致波形出现振铃、台阶甚至误码。总线两端各接一个120Ω电阻匹配了特征阻抗也让信号能量能被吸收而不是反弹回来。调试时最经典的检查手段就是断电状态下用万用表电阻挡量CAN_H和CAN_L之间正常约为60Ω。因为两端电阻并联120Ω // 120Ω 60Ω。如果你量出来是120Ω说明总线只有一端有终端电阻另一端缺失或断开如果量出来接近0Ω那就是短路了如果量出来无穷大两根线可能断线。这是每个CAN调试人员的第一反应操作。2.3 单点总线上的电位陷阱CAN_GND不能想当然不接有一个容易踩的坑我必须要单独拿出来说CAN收发器判断的是差分电压但这并不意味着CAN_GND可以被忽略。总线上所有节点的收发器需要有一个共同的参考地否则两个节点之间的地电位差会直接叠加在差分信号上轻则波形变形重则通信完全失败。在车里面由于整车的金属车身本身就是搭铁母线所以问题不太明显。但在机器人关节调试、实验室台架上经常出现“我用两个USB-CAN卡分别接两台电脑互相发数据发不过去”的怪现象最后查来查去就是两个USB-CAN卡没有共地。正确做法是除了接CAN_H和CAN_L之外还要把各节点的GND连接在一起或者使用带隔离的CAN收发器隔离后再通过隔离电源保证逻辑侧地参考统一。我见过更隐蔽的情况设备A的CAN接口自带了隔离模块设备B没有隔离结果A的地和B的地之间电压有1.5V的偏置正常通信时好时坏高速率下频繁报错。后来我在A和B之间补一根GND线问题立刻消失。所以调试CAN的第一课永远是先确认所有节点的地是通的。3. 协议层一帧报文从发出到被确认经历了什么3.1 标准帧格式逐位拆解11位ID和数据场是主角CAN协议层最常用的就是数据帧标准帧CAN 2.0A和扩展帧CAN 2.0B的主要差别是ID长度标准帧ID是11位扩展帧是29位。我们日常用的绝大部分车载网络和云台电机控制走的是标准帧所以我先以标准数据帧为例把它从头到尾拆开。一帧标准数据帧包含这些部分SOF帧起始1位显性标记帧的开始也是所有节点同步时钟的起点。仲裁场11位ID加上1位RTR远程发送请求位。数据帧的RTR是显性0远程帧的RTR是隐性1。控制场包括IDE位标准帧里是显性0、保留位r0以及4位DLC数据长度代码表示后面数据场有几个字节值为0到8。数据场实际载荷最多8字节。这是应用层真正关心的内容比如转速、温度、角度指令都放在这里。CRC场15位CRC校验码外加1位CRC分隔符用来验证数据在传输中有没有被干扰。ACK场2位包括ACK槽位和ACK分隔符。发送方在ACK槽发送隐性位而总线上任何一个接收正确的节点都会在ACK槽主动发送一个显性位来“响应”。发送方如果在这个位置读到显性位说明至少有一个节点成功接收了这帧数据如果读到隐性位就说明总线上可能只有自己在说话、没有接收者这就是常说的NO_ACK错误。EOF帧结束7位隐性位。IFS帧间空间至少3位隐性位让总线有时间恢复空闲状态。为什么数据场限制在8字节因为CAN诞生于80年代末的汽车工业设计目标就是短小、实时、高可靠。一帧报文如果需要8字节以上数据就发多帧绝不把一位总线占用太久这样其他节点才有机会抢线。这个反直觉的设计恰恰是CAN能实现毫秒级响应的重要原因。3.2 总线仲裁多个节点同时发言时ID数值小的人说了算CAN总线最迷人的机制就是仲裁多个节点同时开始发送时不会撞个你死我活而是通过硬件自动分个高下高优先级的帧继续发低优先级的帧自动退让、等下个总线空闲再重发。原理其实很优雅。前面说过显性位0会把隐性位1“覆盖”掉。当节点A发送ID0x100、节点B发送ID0x200时两个节点都从ID的最高位开始逐个发送。如果某一位上A发送了显性0B发送了隐性1那么B在发送的同时监听总线发现自己明明发的是1总线却是0就知道有更高优先级的节点在抢线于是B立刻停止发送转为接收状态。整个过程中A毫无察觉地继续发完自己的整帧。所以二进制数值越小的ID优先级越高。这个设计让车辆的CAN网络阶梯分明碰撞安全相关的帧比如安全气囊释放信号的ID通常很小优先级最高制动、转向、发动机控制紧跟其后车身舒适性设备比如车窗升降、空调调节排在后面信息娱乐和诊断报文则排在更后面。实际调试中这个机制的直接影响是当总线负载率很高时低优先级节点可能会长时间发不上数据。你要是在机器人上挂了十几个电机都在按1kHz发送反馈帧总线负载接近饱和某些电机的反馈会出现周期性延迟这时就得考虑降低反馈频率、增大ID间隔或者升级CAN FD来减小仲裁压力。3.3 位填充、CRC和错误状态机CAN是怎么把自己“管理”好的CAN协议为了保证时钟同步和数据完整性在数据链路层还埋了几个自动机制你平时可能感觉不到但它们在背后辛勤工作位填充在发送端从SOF到CRC场如果出现连续5个相同电平就要在第5个位之后强制插入1个反相位的位。这样接收端能持续从电平翻转中恢复同步时钟避免长时间同电平导致时钟漂移。接收端则会把填充位自动删除。只有在错误帧和EOF这种特定区域不执行填充。CRC校验帧里包含的15位CRC是发送端根据ID、控制场和数据场计算出来的接收端重新计算并比对如果对不上就认为这帧坏了。位监控除了仲裁场期间发送方会一边发送一边监听总线如果发现自己送出的显性/隐性状态和总线上读回的不一致立即报位错误。这能做到“发送即校验”。错误状态机每个节点硬件维护两个计数器发送错误计数器TEC和接收错误计数器REC。错误少、计数低于127时是主动错误状态犯错时发6位显性错误标志超过127后降级为被动错误状态犯错时发6位隐性错误标志如果TEC超过255节点进入总线关闭状态直接断开与总线的连接不再发送任何数据。这个自我管理机制意味着一个接口硬件上偶发故障的节点很可能被CAN控制器自动踢出总线而不是持续产生垃圾数据干扰别人。你看仪表盘上偶发的“通信故障”码很多情况就是某个节点的错误计数被抬高、短暂进入了被动错误状态导致的。我在以前一次现场调试里遇到过一个很典型的案例一个电机驱动器在不该发数据的时候不停发出一堆CRC错误的帧整个总线的错误帧多到其他正常节点都延迟了。最后排查出来是那个驱动器板子的CAN收发器供电电压偏低导致发送的电平不达标被总线上其他节点判定为无效数据。把供电恢复正常总线立刻安静。4. 应用案例达妙这类关节电机如何用CAN做精准关节控制4.1 为什么机器人关节选CAN而不是RS485或以太网聊完协议层回到热词里大家最关心的那个问题达妙电机怎么通过CAN总线实现精准关节控制。先要理解电机本身。这类关节电机通常是一个大中空/无框力矩电机搭配一个独立的驱动器板卡电机本体上集成编码器磁编码器居多。主控STM32、RTOS控制板等并不直接产生PWM去驱动电机而是把“我要电机转到哪个位置/输出多大扭矩”的命令打包成CAN帧发给驱动器驱动器收到后自行做电流环、速度环、位置环的运算通过FOC算法驱动绕组。也就是说CAN只是一个“传令兵”精准控制靠的是驱动器内部的闭环算法和执行能力。那为什么选择CAN而不是RS485原因有这么几个实时性与优先级CAN的仲裁机制决定了关键帧几乎不会被阻塞。机器人关节的控制指令通常是1kHz以上频率发送如果采用RS485主机必须一个个点名字从机才敢说话主机负担重且延迟随节点数增加。多主与自主上报CAN允许电机驱动器主动上报故障、位置等状态不必等主机来问。紧急情况比如堵转、温度过高能立刻发出报警帧。接线简单CAN只用两根线所有关节电机并联在一条总线上即可。机器人关节要旋转线束越少越不容易在运动中被磨断。做机器人关节时我一般会优先选CAN或者EtherCAT但EtherCAT的从站控制器成本高、调试门槛高所以中低端竞赛级关节电机清一色用CAN。达妙、大疆的RoboMaster电机、部分国产无框电机驱动基本都采用类似的CAN方案。4.2 硬件连接与ID分配几条规则决定能不能转起来关节电机CAN控制的第一步是把电机驱动器和主控正确连上。典型接线是驱动器上的CAN_H接主控CAN收发器的CAN_H驱动器上的CAN_L接主控CAN收发器的CAN_L所有电机驱动器、主控的GND共地总线两端各接一个120Ω终端电阻。我见过不止一次有人把CAN_H和CAN_L反接然后发现所有报文都发不出去。反接不会烧东西但物理上CAN_H的电平始终低于CAN_L总线上的显性位被反向理解节点之间完全无法通信。这个故障现场非常容易识别示波器上两条线电压关系反了或者逻辑分析仪一直报格式错误。终端电阻位置的规矩也很重要。总线如果有多个电机两个120Ω电阻应该被放在物理距离最远的两端而不是都堆在调试台上。如果其中一个电阻靠近中间的某个节点会影响信号完整性。然后是ID分配和波特率设置。每个电机驱动器都有一个节点ID你需要通过拨码开关或者上位机软件设置比如1号电机ID为12号电机ID为2。主控发送的控制帧ID要和电机的ID建立映射关系不同厂家有不同的映射规则。常见的一种方案是ID0x200的控制帧用于给1到4号电机发送目标电流帧里8字节每两个字节对应一个电机电机的反馈帧则各自拥有独立ID例如0x201对应ID为1的电机、0x202对应ID为2的电机反馈内容包含编码器角度、速度、扭矩等。波特率是另一个容易出问题的配置。机器人竞赛领域常用1Mbps部分车载设备用500kbps或250kbps。主控和所有电机驱动器必须设置在同一个波特率否则谁也不知道谁在说什么。好在现在大多数电机驱动器支持通过试收发来自动识别波特率但工业现场还是建议固定写死。4.3 从控制指令到反馈帧一帧报文里的数据是怎么被解析的下面用一个典型的“电流控制模式”来串一遍流程这也是很多竞赛级关节电机的默认工作模式。假设电机驱动器协议如下这里仅作示例实际请以具体产品手册为准控制帧主控 → 电机驱动器使用标准帧ID 0x2008字节字节内容说明0-1电机1目标电流int16有符号单位mA或0.01A视协议2-3电机2目标电流int164-5电机3目标电流int166-7电机4目标电流int16反馈帧电机驱动器 → 主控每个电机独立一帧例如ID 0x201是1号电机8字节字节内容说明0-1机械角度int16单位0.1度/位0x0000~0x0FFF为单圈2-3实际转速int16单位rpm4-5实际扭矩int16单位0.1A或0.01A6温度int8单位℃带偏移7状态标志故障码、使能状态等主控的关节控制循环通常跑在1kHz定时器中断里伪代码如下// 1kHz 关节控制主循环伪代码 while (1) { // 读取当前关节角度从CAN反馈解析得到 float current_angle parse_angle(rx_buffer_id_0x201); // 位置环PID计算输出目标电流 float target_current position_pid(target_angle, current_angle); // 将目标电流转成int16并填入控制帧 uint8_t tx_data[8]; tx_data[0] ((int16_t)target_current) 8; tx_data[1] ((int16_t)target_current) 0xFF; // 发送控制帧 CAN_SendFrame(0x200, tx_data, 8); // 接收各个电机的反馈帧 CAN_ReceiveFrame(rx_id, rx_buffer); parse_feedback(rx_id, rx_buffer); delay(1ms); }看到这里你就明白“精准关节控制”的闭环链路了主控知道目标角度从反馈帧知道当前角度做PID得到目标电流通过CAN帧把电流指令发给驱动器驱动器内部再做电流环和FOC把三相电流实际拉上去让电机转过指定角度编码器测到新角度由下一帧反馈送回主控。整个环路的刷新频率、CAN波特率、指令帧发送周期共同决定了控制的实时性和平滑度。一个非常实用的小细节是很多电机驱动器在使能之前并不响应电流指令。所以上电后的第一件事是先发送使能指令通常是特定ID加特定数据比如ID 0x1ff或0x000中的数据位置把电机切换到CAN控制模式然后再发目标电流电机才会有反应。如果你发电流指令后电机纹丝不动多半不是协议解析错了而是没使能或者使能位不对。4.4 关节控制项目里必须注意的几个细节做CAN关节控制越久越发现真正决定效果的不是CAN本身而是你如何处理控制循环和反馈数据。分享几个我踩过之后改掉了的细节反馈帧的接收不能只靠轮询。如果主控在1000Hz的循环里用阻塞式接收总线上稍微拥塞就会卡住下一个控制帧的发送。正确做法是用CAN接收中断把反馈数据写入环形缓冲区主循环只从缓冲区读最新值。注意大小端字节序。同样是int16有的协议是大端高字节在前有的是小端低字节在前解析错了角度会跳变。第一次拿到新电机时先用上位机发固定数据帧、观察反馈对应关系验证完再写死解析代码。位置数据溢出和掉线判定。CAN反馈里的角度值可能会因为编码器多圈而溢出自己写一个包装函数处理角度回绕掉线判定也要做比如200ms没收反馈就认为电机失效要进入安全状态否则主控会一直给一个失联电机发指令容易出安全事故。全双工CAN是半双工。主控发一帧、电机回一帧总线利用率其实很高。如果同时挂了8个电机都按1kHz反馈总线负载率会接近饱和这时适当降低反馈频率或者只在需要时才开启反馈通常能缓解。5. 现场测试用示波器和CAN分析仪把总线“看穿”5.1 常用测试工具和接线准备CAN调试没必要一次上昂贵的专业诊断仪日常手头这几样就能覆盖90%的场景数字万用表量终端电阻、量CAN_H和CAN_L对地电压、排查线束通断。示波器建议带宽100MHz以上最好有差分探头如果没有差分探头普通探头双通道分别测CAN_H和CAN_L然后使用数学通道做A-B效果也是一样的。CAN分析仪/USB-CAN工具类似周立功、PCAN、国产USBCAN这类能把CAN帧解析成ID数据的形式有些还能统计错误帧、总线负载率。逻辑分析仪部分逻辑分析仪自带CAN解码插件配合CAN收发器也能抓帧适合快速看波形的位时序。接线时我建议把仪表探头的地线夹子接在接近被测节点的地方不要隔很远避免引入地环路噪声。示波器触发方式选下降沿触发或者CAN协议触发一按单次捕捉就能稳稳抓到SOF开始的一段完整报文。5.2 用示波器测量电压差和波特率上电后静态测量CAN_H对GND约2.5VCAN_L对GND约2.5V。如果CAN_H和CAN_L对GND电压不对称查终端电阻和收发器供电。抓波形的时候观察一个完整的报文帧帧起始的SOF应该是显性跳变从隐性到显性的边沿非常陡一段报文结束后会回到隐性高电平位时间可以按示波器标尺量出来。波特率就是位时间的倒数。如果看到1us一个位就是1Mbps如果2us一个位就是500kbps。我经常用这个方法快速判断波特率让节点A周期发一个固定报文在示波器上看最短的一位电平宽度再用1除以这个宽度得到位速率。不过要注意ACK场、EOF的位宽会有变化所以要看中间的数据位或者CRC位这些位置的位宽都是恒定的。波形上如果看到很严重的振铃振荡过冲或者边沿变成圆弧形就要优先怀疑终端电阻位置和数量不对。总线分支过长也会造成反射尽量让CAN线走点对点的菊花链而不是星形连接。5.3 用CAN分析仪解码报文与统计错误帧USBCAN工具上电后先配置正确的波特率然后就能看到总线上所有收发帧。我会关注这么几列ID、数据长度、数据内容、帧类型、错误标志。如果某个ID一直在发但是数据内容一直不变多半是节点没有收到有效指令在发默认值。如果总线错误帧数量持续增长就要检查波特率是否一致、终端电阻是否正常、电源地是否可靠。如果某个节点一上电就导致总线所有通信中断先把这个节点单摘出来单独挂到测试总线上看它的波形和错误计数大概率能复现问题。调试记录这块我的习惯是把正常状态下的典型报文存档成模板比如“1号电机的反馈ID是0x201角度00 12 A1 B2”以后出问题时对比模板一眼就能看出来是数据解析错了还是硬件异常。6. 常见问题与排查技巧实录6.1 终端电阻的四个典型异常现场现象可能原因处理办法通信极不稳定距离一长就丢帧总线两端缺少一个120Ω终端电阻断电后量CAN_H-CAN_L应约60Ω补上缺失终端电阻总线完全不通量CAN_H-CAN_L为0ΩCAN_H和CAN_L短路或某个收发器损坏分段断开节点逐一排查短路点更换收发器量到约120Ω只有一个120Ω终端电阻在另一端补上120Ω终端电阻波形边沿有过冲/振铃终端电阻位置不对、总线分支过长将终端电阻移到物理两端缩短分支这里有一个容易被忽略的知识点很多CAN分析仪自身带有120Ω终端电阻通过跳线或开关控制。当你同时接了USBCAN和一条正常总线上时如果USBCAN的终端电阻开关一直开着会让总线变成三个电阻并联等效阻值会低于40Ω信号幅度反而变差。调试时先确认工具的终端电阻状态别让工具本身成为故障源。6.2 波特率不匹配时的现场特征波特率不匹配的故障非常典型总线上的帧发送方根本收不到ACK控制器一直报发送失败用CAN分析仪抓包会看到大量错误帧其他正常报文也受影响。示波器上看波形单个位宽度和软件设定的波特率对不上。排查时我一般这样做先用示波器测出实际位宽算出总线上正在跑的波特率再把所有节点的配置统一成一致。注意有些电机驱动器的拨码开关同时设置ID和波特率改ID时可能不小心也改了波特率务必检查驱动器的状态指示灯或上位机配置页面。6.3 电机CAN控制不动的排查顺序我接手过一个项目新到的关节电机怎么发指令都不转问题查了整整一下午最后发现是上位机配置界面把控制模式设成了“速度模式”而代码里发的是电流指令。所以我的排查顺序永远是先“上分”再“对码”电源和使能电机驱动器是否正常上电使能信号是否已置为允许CAN控制很多驱动器不使能时接收指令但不输出。物理层CAN_H/CAN_L是否接反终端电阻是否在两端GND是否共地。波特率主控和驱动器设置是否一致用示波器量位宽验证。ID映射主控发送的控制帧ID是否正确映射到电机的ID发送的是标准帧还是扩展帧。数据格式字节序、量程、符号目标电流的负数表示对不对。控制模式驱动器的控制模式是否与指令数据一致电流/速度/位置使能后是否还需要额外确认帧。这个顺序里的每一步都能用万用表或分析仪快速验证不要跳步。按照这个顺序走完基本能定位95%的“不动”问题。6.4 我踩过的一个隐性坑隔离CAN模块的地电位异常最后分享一个印象深刻的案例。一个四轴机械臂项目四个关节电机挂在同一条CAN总线上主控板用的是带隔离的CAN收发器。上电后四台电机偶尔有一两台反馈延迟而且问题随机出现有时这台、有时那台。我用示波器抓了很久发现只要某台电机启动瞬间CAN_H和CAN_L对GND的电压基线就会瞬间偏移1V左右虽然差分电压仍然正常但隔离模块输入端的共模电压超出了耐受范围导致数据错误。查到最后是电机本身的动力线和CAN线走同一个线槽电机启动时的大电流在动力线上产生压降而CAN的隔离侧地线没有和动力地良好连接共模电压被拉偏了。解决方法是把CAN线的屏蔽层如果线缆有屏蔽单端可靠接机壳地同时把隔离模块的地侧与驱动器电源地之间的阻抗降低。从那以后我做CAN布线都坚持两个原则动力线和CAN线不捆在同一束必须交叉或分开走所有CAN节点的地参考必须明确不要依赖“机壳自然导通”。7. 写在最后的一点实际体会把CAN从“会收发”到“懂机理”走一遍之后再回头看那些车辆协议、电机控制方案它们基本都是同一种思路的变体用一条双绞线把多个节点连接起来靠差分电压抗干扰靠ID仲裁定优先级靠短帧保实时靠多层校验保可靠。你只要把这个底层逻辑吃透了不管是修车时的数据流分析、做智能车竞赛的底盘调参还是搞机器人关节的高频控制第一反应不会是去背协议表而是先搞清楚这条总线上每一个物理现象背后的原因。真要说有什么经验值得记住我总结成一句话CAN调不通八成是地没接好两成是终端电阻不对剩下才轮到协议和代码。看似是玄学其实全是物理层的基础功。先把示波器、万用表这两样工具用好你在这条总线上就不会有真正难倒你的问题。
返回列表