公司动态

106.CAN总线详解:物理结构、仲裁机制与通信原理(车载嵌入式必学)

📅 2026/8/31 14:43:23
106.CAN总线详解:物理结构、仲裁机制与通信原理(车载嵌入式必学)
前言在汽车电子、工业控制领域CAN总线绝对是最经典的串行通信总线。和串口、I2C、SPI不一样CAN天生支持多节点组网、总线容错、非破坏性位仲裁一条总线可以挂几十个MCU、ECU即使某一个节点故障短路也不会让整个总线瘫痪。本文结合CAN总线物理层结构、帧结构、仲裁逻辑、容错机制完整讲解适合车载开发、工业设备开发人员阅读。一、CAN总线硬件物理结构1.1 总线线缆组成CAN总线采用两根差分信号线CAN_H、CAN_L不是单端信号。空闲状态下CAN_H和CAN_L电位相等约2.5V总线隐性电平显性状态下CAN_H拉高至约3.5VCAN_L拉低至约1.5V两根线产生2V左右压差差分信号的优势抗干扰能力极强汽车发动机、继电器产生的电磁干扰对差分信号几乎没有影响这也是车载全部使用CAN而不用UART的核心原因。总线两端必须接120Ω终端电阻两个120Ω电阻并联为60Ω匹配阻抗。作用消除信号反射、抑制高频干扰常见错误只接一个终端电阻会出现波形畸变、通信丢包完全不接电阻远距离完全无法通信。1.2 总线拓扑结构CAN是多主式总线没有主机、从机之分所有节点地位完全平等。一条总线可以挂载最多110个节点所有节点并联在CAN_H和CAN_L两根线上任意一个节点都可以主动发起报文发送不需要主机轮询。1.3 收发器结构MCU内部只有CAN控制器CAN外设不能直接驱动差分总线必须搭配外置CAN收发器典型型号TJA1050、SN65HVD230控制器处理帧格式、校验、仲裁、重发逻辑收发器把控制器的单端逻辑电平转换成CAN_H/CAN_L差分电平。二、CAN两种电平显性位与隐性位CAN总线只有两种电平状态所有节点同步监听总线隐性电平1CAN_H2.5VCAN_L2.5V压差为0多个节点同时发隐性位总线依然保持隐性。显性电平0CAN_H3.5VCAN_L1.5V压差2V显性位优先级高于隐性位。核心规则只要总线上任意一个节点发出显性0整条总线就会变成显性覆盖所有节点的隐性1这个特性就是CAN仲裁的基础。三、非破坏性逐位仲裁CAN最核心机制这也是CAN区别于其他总线的灵魂也就是CSMA/CD非破坏性仲裁。3.1 仲裁过程多个节点同时检测到总线空闲同时开始发送报文ID仲裁段所有节点逐位发出ID一边发一边回读总线上的电平如果自己发出的是隐性1但是读到总线变成了显性0说明有更高优先级节点抢占总线失去仲裁的节点立刻停止发送转为接收模式等待下一次总线空闲获胜的节点不受任何影响继续完整发送报文数据不会损坏、不会中断。3.2 ID优先级规则CAN标准帧ID共11位ID数值越小优先级越高。举例节点A ID0x001节点B ID0x002两个节点同时发送。从最高位开始逐位对比高位相同到低位时低ID会发出显性0抢占总线。3.3 为什么叫“非破坏性”以太网冲突检测后双方都必须停止发送、等待随机延时重发而CAN输掉仲裁的节点仅仅放弃发送赢家完整发完数据不会造成数据损坏总线利用率远高于以太网。四、CAN报文帧类型CAN一共有四种帧数据帧、远程帧、错误帧、过载帧日常开发只用数据帧。标准数据帧结构分段从起始到结尾帧起始1位显性0通知所有节点总线开始传输仲裁段11位ID RTR位RTR0代表数据帧控制段4位标识后面数据场长度0~8字节数据段0~8字节有效数据这是用户真正需要传输的内容CRC校验段15位CRC校验保证数据传输无误ACK应答段发送器发出隐性位接收正确的节点拉低为显性应答帧结束7位隐性位一帧结束。补充CAN FD扩展了数据长度最大支持64字节工业设备使用较多。五、总线容错与故障隔离CAN具备强大的错误处理机制这也是车载安全等级的关键每个节点都时刻校验CRC、位错误、填充错误检测到错误时节点立刻发送错误帧终止当前报文节点内置错误计数器发送错误、接收错误分别计数计数器超限后节点会自动进入总线关闭状态脱离总线不会因为一个节点硬件短路把整条总线拉死。就算某个ECU内部短路收发器损坏其余上百个节点依旧可以正常通信这是普通串口完全做不到的。六、CAN总线典型应用场景汽车电子发动机ECU、ABS、仪表、车灯、BMS电池管理系统全部挂在CAN总线上工业自动化伺服驱动器、PLC、传感器组网工程机械挖掘机、装载机控制器通信新能源设备电池BMS、电机控制器、车载充电机交互。七、CAN和UART、I2C核心对比表总线拓扑多主仲裁抗干扰节点数量容错能力UART串口点对点不支持差2个无容错I2C多节点主机轮询一般最多8个无故障隔离CAN多主总线硬件自动仲裁极强差分信号110个故障自动脱离总线八、STM32最简CAN收发示例标准帧#include stm32f10x.h #include can.h CAN_TxHeaderTypeDef TxHeader; CAN_RxHeaderTypeDef RxHeader; uint8_t TxData[8]; uint8_t RxData[8]; uint32_t TxMailbox; // CAN发送函数 void CAN_Send_Msg(uint16_t id,uint8_t *buf,uint8_t len) { TxHeader.StdId id; TxHeader.IDE CAN_ID_STD; TxHeader.RTR CAN_RTR_DATA; TxHeader.DLC len; HAL_CAN_AddTxMessage(hcan1,TxHeader,buf,TxMailbox); } // CAN中断接收回调 void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) { HAL_CAN_GetRxMessage(hcan,CAN_RX_FIFO0,RxHeader,RxData); // 在这里解析RxData数据 }九、开发常见坑点总结总线两端必须安装120Ω终端电阻只装一端波形失真CAN_H和CAN_L不能反接反接后收发器无法正常工作长距离布线必须使用双绞屏蔽线减少电磁干扰ID越小优先级越高报警、紧急信号使用低IDCAN控制器自带重发机制软件不需要手动重发报文。十、总结CAN总线的核心优势总结为三点差分抗干扰、多主非破坏性仲裁、硬件级容错隔离。没有固定主机多节点自由抢占总线冲突时低ID报文优先发送故障节点自动下线让CAN成为汽车、工业控制领域几十年经久不衰的总线标准。理解物理差分电平与位仲裁逻辑就能彻底看懂CAN所有底层行为。