一、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通信在电机控制中不是「能不能用」的问题,而是「怎么用好」的问题。打好基础,后面才能玩得转。