一、CAN通信基础:从入门到实战

1.1 CAN总线起源:为什么会有这个东西?

说起CAN总线,得回到上世纪80年代。那时候汽车越来越智能,各种电子控制器(ECU)越来越多。你想想看,一个发动机ECU、一个ABS控制器、一个变速箱控制器……它们之间要互相通信,怎么办?

传统的做法是用一堆点对点的线。结果呢?一辆车里的线束比蜘蛛网还复杂。我记得有个老工程师跟我吐槽过,说那时候修车光理线就得半天。

所以,1983年,德国博世公司开始搞事情了。他们想设计一种总线——只用两根线,就能让所有节点互相通信。这就是CAN(Controller Area Network)的由来。1986年正式发布,后来成了ISO 11898标准。

说白了,CAN总线就是为工业现场和汽车电子量身定做的。它要解决的核心问题就三个:可靠、实时、低成本

核心要点:CAN总线最初是为了解决汽车内部ECU之间的通信问题而设计的,后来扩展到工业自动化、医疗设备、机器人等领域。

1.2 CAN与RS485对比:谁更适合电机控制?

很多初学者会问:RS485也能做多机通信,为什么非要用CAN?

嗯,这个问题我在项目里也纠结过。咱们直接上对比表:

对比项 CAN总线 RS485
通信方式 多主从,任意节点可主动发 一主多从,主机轮询
仲裁机制 硬件自动仲裁,无损 无仲裁,需软件处理冲突
实时性 高,优先级高的帧先发 低,依赖主机轮询周期
错误处理 硬件自动重发,错误检测强 需软件实现,容易丢帧
最大节点数 理论110个(实际建议≤32) 理论256个
传输距离 40m@1Mbps,1km@50kbps 1200m@115.2kbps
成本 稍高(需要CAN控制器) 低(UART转485即可)

我个人习惯是:电机控制这种对实时性要求高的场合,闭着眼睛选CAN。为什么?因为RS485是主从结构,主机要一个一个轮询从机。你想想看,如果电机突然需要紧急停止,还得等主机轮询到它?黄花菜都凉了。

CAN就不一样了。每个节点都能主动发数据,而且硬件自动仲裁——优先级高的帧先发,优先级低的自动退让。这在电机控制里太重要了。

我的经验:曾经在一个伺服驱动器项目中,客户坚持用RS485做多轴同步。结果调试时发现,当轴数超过6个,轮询周期就超过10ms,同步精度根本达不到要求。后来换成CAN,1ms内所有轴都能收到同步指令。所以,别在实时性上省钱。

1.3 CAN物理层特性:两根线怎么传数据?

CAN总线物理层,说白了就是两根线:CAN_H和CAN_L。它用的是差分信号传输。

什么叫差分信号?就是两根线上的电压差来表示逻辑状态。具体来说:

  • 显性电平(逻辑0):CAN_H比CAN_L高2V左右(CAN_H≈3.5V,CAN_L≈1.5V)
  • 隐性电平(逻辑1):CAN_H和CAN_L都是2.5V左右(电压差≈0V)

这里有个关键点:显性电平会覆盖隐性电平。也就是说,只要有一个节点发显性电平,总线上就是显性。这就是CAN仲裁的基础。

注意:CAN总线两端必须各接一个120Ω的终端电阻。我见过太多新手忘了接电阻,结果通信时好时坏。曾经有个同事调试了两天,最后发现是终端电阻没焊上……

物理层的其他参数:

  • 总线电平:5V(标准CAN)或3.3V(CAN-FD部分实现)
  • 共模电压范围:-2V ~ +7V(ISO 11898标准)
  • 最大传输距离:与波特率成反比

1.4 CAN2.0A/B协议帧结构:数据到底怎么装?

CAN协议定义了四种帧类型:

  • 数据帧:发送数据的
  • 远程帧:请求数据的
  • 错误帧:报告错误的
  • 过载帧:延迟下一帧的

咱们最常用的是数据帧。CAN2.0A是标准帧(11位ID),CAN2.0B是扩展帧(29位ID)。

一个标准数据帧的结构是这样的:

帧起始(1bit) + 仲裁场(12bit) + 控制场(6bit) + 数据场(0~8字节) + CRC场(16bit) + 应答场(2bit) + 帧结束(7bit)

我来拆开讲讲:

  • 帧起始:1个显性位,告诉所有节点「我要发数据了」
  • 仲裁场:11位ID + 1位RTR(远程帧标志)。ID越小,优先级越高
  • 控制场:IDE位 + 保留位 + DLC(数据长度,0~8)
  • 数据场:0~8字节,你想传啥就传啥
  • CRC场:15位CRC校验 + 1位定界符
  • 应答场:接收节点在应答间隙拉低总线,告诉发送方「我收到了」
  • 帧结束:7个隐性位

重点:CAN的ID不只是地址,它还决定了优先级。ID值越小,优先级越高。在电机控制中,我们通常把紧急停止、故障报警这类高优先级消息分配小ID。

扩展帧(CAN2.0B)和标准帧的区别主要在仲裁场:

  • 标准帧:11位ID + RTR位
  • 扩展帧:11位基ID + SRR位 + IDE位 + 18位扩展ID + RTR位

说白了,扩展帧就是多了18位ID,总共29位。但要注意:扩展帧的优先级比标准帧低。因为标准帧的IDE位是显性,扩展帧的IDE位是隐性。

避坑指南:我曾经在一个项目中,把电机控制器的CAN ID设成了0x7FF(标准帧最大ID)。结果发现它总是抢不到总线,因为其他节点的ID都更小。后来我把紧急停止的ID改成0x001,故障报警改成0x002,普通控制命令用0x100以后。这样优先级就合理了。

1.5 小结:CAN通信在电机控制中的定位

好了,这一章咱们把CAN的基础讲完了。总结一下:

  • CAN总线是为实时控制而生的,不是通用通信
  • 物理层用差分信号,抗干扰能力强
  • 帧结构里ID决定优先级,这是电机控制的关键
  • 标准帧和扩展帧,根据节点数量选

下一章,咱们会深入讲CAN控制器和收发器的选型,以及怎么在STM32上配置CAN外设。到时候我会拿实际项目中的电路图和代码来演示。

记住一句话:CAN通信在电机控制中不是「能不能用」的问题,而是「怎么用好」的问题。打好基础,后面才能玩得转。