CAN通信简单使用
简介
控制器局域网(英语:Controller Area Network,简称CAN或者CAN bus),是一种面向消息、支持多节点竞争和错误检测的串行总线。它最早广泛应用于汽车电子,现在也常见于工业控制、电机驱动、传感器网络和分布式控制设备。
这里只解析下最简单的使用
码流解析
高速 CAN 通常使用 CAN_H 和 CAN_L 两根差分线。MCU 的 CAN 控制器不能直接驱动总线,需要经过 CAN 收发器,比如TJA1051这样的CAN驱动芯片,类似于SP3232的232驱动芯片,把 MCU 侧的逻辑信号转换成差分电压。
接收器主要判断两根线之间的电压差,因此外界同时耦合到两根线上的共模干扰,不容易直接改变接收结果。这也是 CAN 比普通单端信号更适合工业现场的重要原因之一。
参考下WIKI上面的CAN具体码流定义

从这个图中可以看出CAN_H 1,为CAN_L 为0的时候,表示输出0, CAN_H 0, CAN_L 1的时候输出1
当前这个图可以把常规的11位标准ID的码流格式。整条码流可以把CAN解析时的所有信息,都标识出来
它在总线上的主要组成如下:
SOF | Arbitration | Control | Data | CRC | ACK | EOF | Intermission
应用程序通常只配置 ID、帧类型和数据,SOF、CRC、ACK、位填充等工作由 CAN 外设自动完成。
SOF帧起始
总线空闲时处于隐性状态。发送节点用一个显性位作为 SOF,表示新的一帧开始。其他节点检测到这个边沿后开始同步接收。
Arbitration仲裁段
标准帧的仲裁段主要包含 11 位 ID 和 RTR 位。ID 从高位到低位依次发送。
如果多个节点同时开始发送,每个节点会一边发送、一边监听总线。某个节点发送隐性 1,却读回显性 0,说明另一个节点发送了优先级更高的内容。该节点会退出本轮发送,等待总线再次空闲。
这个过程不会破坏获胜节点的数据,所以称为无破坏仲裁。由此可以得到几个重要结论:
- 数值较小的 CAN ID 通常具有更高的仲裁优先级;
- ID 不只是设备或消息标识,也直接影响实时性;
- 紧急停止和严重故障报文应分配较高优先级;
- 高频状态报文不应占用过高优先级;
- 两个节点如果使用相同 ID 同时发送不同数据,会在数据段产生错误,不能依靠 CAN 自动区分。
帧格式相关字段
标准数据帧中,RTR 位位于仲裁段,IDE、保留位和 DLC 位于后续控制段。STM32 HAL 把这些信息集中放在收发帧头结构体中,所以软件开发时经常把它们放在一起检查。
| 字段 | 作用 |
|---|---|
IDE |
区分 11 位标准帧和 29 位扩展帧 |
RTR |
区分数据帧和远程帧,位于仲裁段 |
DLC |
描述数据段包含多少个字节 |
也就是 11 位标准数据帧,每帧固定传输 8 字节。IDE、RTR 和 DLC 是 CAN 帧级字段,不在 Byte0~Byte7 数据区内。
Data数据段
经典 CAN 一帧最多携带 8 字节数据。CAN 外设不知道这些字节的业务含义,必须由应用协议解释。
例如:
02 21 03 09 05 00 00 00
CRC校验
发送节点根据前面的帧内容计算 CRC,接收节点重新计算并比较。CRC 不一致时,接收节点会判断传输错误。
CRC 只能说明总线上传输的位是否出现错误,不能判断参数值是否合理。即使 CRC 正确,应用层仍可能返回“参数不存在”“数值超范围”或“当前状态不允许执行”。
ACK确认
发送节点在 ACK 槽发送隐性位,任何正确接收到该帧的节点都可以发送显性位作为确认。
CAN 硬件 ACK 仅表示至少有一个节点正确接收了该帧,不代表:
EOF和帧间隔
EOF 标识当前帧结束,帧间隔用于分隔连续报文。CAN 控制器自动处理这些位级时序。
位填充
这些是CAN编码的具体定义,如果是扩展帧数据码流的定义会有一些区别,上面的定义有一些了解就可以了,实际使用时候的MCU的等硬件会完成硬件层码流的解析,解析完之后的数据会放到相关寄存器中。
软件解析
对于标准帧来说,主要就是11位的识别ID,数据长度,以8个字节的数据,以这样的形式组成
11位标准ID定义
bit10 bit9 bit8 bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
可以根据作为从机地址来使用,也可以只用部分数据作为从机地址,
以当的从机地址设定范围1-100来说,从机地址的位数只要7位就够了
bit10 bit9 bit8 bit7 | bit6 bit5 bit4 bit3 bit2 bit1 bit0
FrameType | NodeId
前四位可以作为命令标识,解析数据的时候可以根据这个FrameType里面协议解析的不同逻辑分支跳转。
CAN总线有一个滤波的过滤,可以根据从机地址,屏蔽一些数据帧来降低软件处理的压力
一帧数据8个字节的数据可以进行自定义通信协议格式,添加自己的定义的通信协议
对比485
RS-485: 硬件层面对冲突无能为力,必须在软件协议(如 Modbus 协议)中严格规定通信时序来避免冲突。
CAN 总线: 拥有非破坏性仲裁技术。每个数据包都有一个 ID(代表优先级),当两个节点同时发送时,硬件会自动比较 ID,优先级高的节点继续发送,优先级低的节点自动闭嘴并转为接收状态,整个过程不会损坏任何数据,效率极高。
接线参考思路
菊花链拓扑(Daisy Chain Topology) 或 手拉手接线法。
信号走线从 A => B => C 依次串联极佳。这种方式使得主干线到每个板子芯片的“支路长度(Stub Length)几乎为 0,能够最大程度地减少信号反射,最后一个板子添加匹配电阻
总结
CAN也是一个很通用的通信接口
CAN相对于485也是一条总线带多个设备,但相对于485因为有硬件层的一些过滤与仲裁机制,软件层的相对简单一些。虽然理论上485的带宽要高一些,但由于多机后软件上会复杂,实际传递速度不会快很多,且多机同时上报数据,没有一个好的机制,485丢数据的概率比较大。

浙公网安备 33010602011771号