做嵌入式开发这几年,CAN总线几乎躲不开。不管搞车规级ECU还是工业PLC通信,涉及多节点数据交互,CAN大概率是那个被选中的方案。但很多人对它的理解停在"差分信号、仲裁机制"几个词上,真正动手设计应用系统时问题就来了。
CAN总线原理是什么
CAN的核心就一件事:在一条总线上让多个节点公平地说话。它用CSMA/CA加冲突检测,不是CSMA/CD。节点要发数据前先监听总线,空闲就发,不空闲就等。万一半路撞上了,靠报文ID的数值仲裁,ID越小优先级越高,输的那方立刻退出去转接收模式,不丢数据也不破坏总线。整个过程对上层完全透明。
物理层是差分信号,CAN_H和CAN_L两根线,显性电平(0)覆盖隐性电平(1),所以仲裁时显性方天然胜出。波特率汽车域控常用500K或1M,工业现场250K到1M不等。位编码用NRZ,连续5个同电平位时自动插入一位相反电平做位填充,保证所有节点时钟同步。
CAN总线应用怎么设计
设计应用系统第一步不是画电路,是定通信矩阵。哪些信号走CAN、周期多少、谁发谁收、错误帧怎么处理,全写进一张表。我见过的坑最多的就是信号周期和节点处理能力没对齐,比如一个10ms周期的刹车信号,接收端固件里轮询间隔设了20ms,数据直接丢半拍。DBC文件里把信号字节序、缩放因子、偏移量定死,硬件端和上位机解析才不会对不上。
硬件上,MCU自带CAN控制器基本够用,外置就挂MCP2551加SJA1000。终端120Ω电阻别忘,接法上放总线两端。网关节点做协议转换时注意隔离——电源隔离和信号隔离分开做,光耦隔离CAN收发器是最稳的方案。固件层面用OS任务或中断把接收和发送分开,发送队列深度留8到16帧,溢出时要有降级策略,丢低优先级帧、保住关键安全信号。
CAN协议看着不复杂,难的是工程里那些边界条件:总线负载跑到80%以上仲裁延迟怎么补偿、热插拔节点时错误计数器怎么恢复、多段总线加CAN网关的拓扑怎么规划。没有标准答案,只能靠一版版测试磨出来。把原理吃透、通信矩阵定扎实,剩下的就是反复调试的事了。










