前言:很多新手把 CAN 总线当成稍微高级一点的 UART(串口)来用,认为只要波特率算对了(比如 1Mbps),挂多少个设备都能跑。 但 CAN 总线在物理层和协议层有一个极其严苛、极具“破坏性”的机制:一人生病,全村吃药。
一、 灾难的起点:传染性极强的“错误帧”
CAN 协议为了保证绝对的可靠性,赋予了每个节点“砸场子”的权利。 当总线上的任意一个节点(哪怕是一个微不足道的传感器),发现当前传输的波形有问题(比如位填充错误、CRC 错误),它会立刻无视一切规则,连续发送 6 个显性电位(极度违反 CAN 编码规则的波形)。 这就是错误帧(Error Frame)。
雪崩效应:总线上的其他所有节点看到这 6 个异常电位后,也会立刻认为总线被干扰了,集体丢弃当前数据,并跟着一起发错误帧。瞬间,总线上全是垃圾波形,有用数据一个都传不出去。
二、 为什么会报错?致命的“采样点(Sample Point)”
既然代码没错,为什么节点会觉得波形有问题?罪魁祸首是物理延迟与时钟漂移。 在 STM32 配置 CAN 时,有很多让人头疼的参数:Prescaler、Time Quanta (Tq)、BS1、BS2。这些参数决定了一个极其关键的物理量——采样点位置。
菜鸟的配置(50% 采样点):很多同学随便填参数,导致单片机在一个 Bit 时间的正中间(50%)去读取电平。
物理真相:当你在总线上挂了越来越多的电机,线缆变长、寄生电容变大,方波信号会变得“圆滑”,上升沿爬坡需要更长的时间。再加上不同节点的晶振存在微小误差。
后果:信号的上升沿还没爬到稳定的高电平,或者因为时钟漂移导致电平还没稳定,单片机在 50% 处一刀切下去,刚好采到了一个正在跳变的错误电平。错误帧瞬间爆发!
三、 系统的自我毁灭:Bus Off 状态
CAN 节点内部有一个“错误计数器”。 如果它频繁发现错误,计数器就会飙升。当错误计数超过 127,它会进入“被动错误(Error Passive)”状态;如果环境极其恶劣,错误计数超过 255,硬件为了防止这个“疯掉”的节点继续破坏总线,会直接触发终极惩罚:Bus Off(离线)。 这时候,该节点的 CAN 外设会在物理层面上切断与总线的联系,软件怎么发数据都没用,机器人彻底瘫痪。
四、 老鸟的“定海神针”:重塑位定时(Bit Timing)
要解决挂载多节点时的雪崩问题,必须榨干 STM32 的时序配置:
推迟采样点:通过调整
BS1(把时间拉长)和BS2(把时间缩短),将采样点从 50% 强行推迟到80% ~ 87.5%的黄金位置。给信号留出充足的爬坡和稳定时间,再去读取!终端电阻不可乱加:一条 CAN 总线,物理上只能有两个 120 欧姆终端电阻放在最远的两端。中间挂载的电机节点绝对不能再并联电阻,否则总阻抗骤降,CAN 收发器根本驱动不动,直接导致波形崩溃。
五、 总结
在多节点的高速网络中,不要轻信理论上的 1Mbps。理解了 CAN 总线的仲裁机制、错误帧传播逻辑和物理采样点设定,你才能真正驯服这条工业界最强悍、但也最暴躁的神经总线。