2、CAN总线基础:物理层、帧格式、仲裁与错误处理
各位同学,今天咱们来啃一块硬骨头——CAN总线。说实话,在储能系统里,PCS和BMS能不能好好说话,全靠这条总线。我做了这么多年系统集成,见过太多因为CAN通信不稳导致的奇葩故障。所以这一章,咱们把底层的物理层、帧格式、仲裁机制和错误处理彻底讲透。
2.1 CAN总线物理层特性
CAN总线物理层,说白了就是信号怎么在线上跑。它用的是差分信号,两根线:CAN_H和CAN_L。为什么要用差分?抗干扰啊!储能站里逆变器一开,电磁环境那叫一个恶劣,单端信号根本扛不住。
我个人的习惯是,在设计CAN节点时,终端电阻一定不能省。120欧姆,两端各一个。为什么是120?因为CAN总线的特性阻抗就是120欧姆。不匹配的话,信号反射会搞得你怀疑人生。
关键参数速查表:
| 参数 | 值 | 说明 |
|---|---|---|
| 总线电平 | 显性0V / 隐性2.5V | 显性时CAN_H≈3.5V,CAN_L≈1.5V |
| 最大速率 | 1 Mbps | 总线长度≤40m时 |
| 最大节点数 | 110个(理论) | 实际受驱动能力限制 |
| 终端电阻 | 120Ω | 两端各一个 |
嗯,这里要注意:速率和总线长度是成反比的。你想想看,1Mbps时最多跑40米,降到125kbps就能跑500米。储能柜内部走线一般也就几米,所以用500kbps比较常见。我曾经在一个项目中,现场施工把CAN线跟动力线绑在一起走了20米,结果通信丢包率高达30%。后来分开走线,问题立刻解决。
2.2 CAN2.0A/B帧格式
CAN2.0A和2.0B的区别,说白了就是ID长度的不同。2.0A是11位ID,2.0B是29位ID。在储能系统里,我建议直接用2.0B。为什么?因为29位ID可以携带更多信息,比如把设备类型、功能码、数据索引都编码进去,方便后期扩展。
咱们来看一个标准数据帧的结构,我画了个图,你一看就明白:
数据场最多8个字节,这是CAN的一个硬限制。在储能系统里,BMS上报的电池电压、温度、SOC等信息,8个字节往往不够用。怎么办?我一般会采用多帧传输,或者把数据压缩编码。比如电压值用2字节表示,温度用1字节,这样一帧能塞下3组数据。
避坑指南:我曾经遇到过一个坑——CAN控制器默认是2.0A模式,只支持11位ID。如果你用了29位ID,必须显式配置为2.0B模式。否则,节点会一直收不到消息,还以为是硬件坏了。
2.3 CAN总线仲裁机制
仲裁机制,说白了就是多个节点同时发数据时,谁说了算。CAN总线用的是CSMA/CA + 逐位仲裁。每个节点在发送前先监听总线,空闲了才发。如果两个节点同时发,就看谁的ID优先级高。
这里有个关键点:ID值越小,优先级越高。为什么?因为显性位(0)会覆盖隐性位(1)。你想想看,如果节点A的ID是0x100,节点B的ID是0x200,它们在总线上逐位比较,A的ID更小,所以A胜出,B自动退出发送。
在储能系统里,我一般这样分配优先级:
- 最高优先级:紧急停机信号(ID=0x001)——命根子,必须最快响应
- 高优先级:BMS上报的故障告警(ID=0x010~0x01F)
- 中优先级:PCS的功率调度指令(ID=0x100~0x1FF)
- 低优先级:BMS周期性上报的电压温度数据(ID=0x200~0x2FF)
嗯,这里要注意:仲裁机制虽然好用,但如果总线上节点太多,低优先级的节点可能一直抢不到总线。这就是所谓的“饿死”现象。我建议在协议设计时,给每个节点留一个“保底发送窗口”,确保低优先级数据也能发出去。
2.4 CAN总线错误处理
CAN总线的错误处理机制,是我觉得最牛的地方。它不像串口那样,丢了数据就丢了。CAN有5种错误检测机制,而且每个节点都会参与错误监控。
这5种错误分别是:
- 位错误:发送节点监控总线,发现发送的位和总线上的位不一致
- 填充错误:连续5个相同位后没有插入反相位
- CRC错误:接收节点计算的CRC与发送的不一致
- 格式错误:帧格式不符合规范
- ACK错误:发送节点没有收到应答
每个节点内部有两个计数器:发送错误计数器(TEC)和接收错误计数器(REC)。错误多了,节点会进入三种状态之一:
| 状态 | 条件 | 行为 |
|---|---|---|
| 主动错误 | TEC<127 且 REC<127 | 正常通信,发送主动错误标志 |
| 被动错误 | TEC>127 或 REC>127 | 只能发送被动错误标志,且发送前要等待8个隐性位 |
| 总线关闭 | TEC>255 | 完全脱离总线,不再参与任何通信 |
警告:总线关闭状态是致命的!节点一旦进入这个状态,必须由主机通过特定指令才能恢复。我在一个项目中遇到过,BMS因为CAN总线干扰频繁进入总线关闭状态,导致PCS收不到电池数据,直接停机。后来我们在BMS软件里加了自动恢复机制,检测到总线关闭后,主动复位CAN控制器。
最后说一个我自己的经验:CAN总线调试时,一定要用示波器看波形。别光看软件日志,有时候硬件上的毛刺、振铃、电平异常,软件根本发现不了。我习惯在CAN_H和CAN_L之间挂一个示波器,看差分信号的质量。如果波形上升沿不够陡,或者有回勾,那就要检查终端电阻和布线了。
好了,CAN总线的基础就讲到这里。这些内容看起来枯燥,但都是实际干活时绕不开的。下一章咱们会深入PCS和BMS之间的具体通信协议,到时候这些基础都会用上。