03. CAN 是什么:先看懂一帧报文
这节课要完成什么
这一课只学习三个新概念:
- 总线和节点;
- CAN 的广播式通信;
- 一帧日志里的
CAN-ID、DLC和DATA。
学完后,你应该能独立拆开下面这帧报文:
0x123 [3] 11 22 33
1. “总线”是什么意思
假设一个系统里有控制器、传感器和执行器。如果每两个设备都单独拉一组通信线,设备越多,线路越复杂。
总线是一组被多个设备共同使用的通信线路。先用一根粗线表示共享通道:
控制器 A 传感器 B 执行器 C
| | |
+---------------------+--------------------+
共享总线
这张图只表达三个设备接在同一条主干上。真实 CAN 使用 CANH 和 CANL 两根信号线,下一课再展开。
“共享”有两个重要含义:
- 设备 B 不是中转站,A 的消息不需要由 B 转发给 C;
- 任意设备发送时,其他设备都能在总线上看到这帧报文。
2. 什么是 CAN 节点
连接到 CAN 总线、能够收发 CAN 报文的设备,称为 CAN 节点。
可以把这两个词分开理解:
- 总线说的是多个设备共同使用的通信线路;
- 节点说的是接到这组线路上、参与通信的设备。
控制器、传感器和电机驱动器都可以成为节点。“节点”描述的是设备在 CAN 总线上的通信角色,与设备的品牌和使用的芯片无关。
放到本教程的实物上看:

先看与通信有关的部分:底板和电机之间通过 CANH、CANL 传递报文。因此,左边底板是一个 CAN 节点,右边电机内部的控制器是另一个 CAN 节点。图中的 VOUT 和 GND 负责供电和共地,不属于 CAN 总线的两根信号线。
底板上虽然有多颗芯片,但不是每颗芯片都要单独算作一个节点。判断时看的是接到总线上的完整通信设备:整套底板共同完成报文的发送和接收,所以它算一个节点。
现在,两个节点已经通过同一条 CAN 总线连接起来,可以互相传递报文。这样的通信系统通常称为 CAN 网络。这里的“网络”指这些节点和连接它们的总线,与互联网、Wi-Fi 没有关系。
3. CAN 是广播式通信
节点 A 发送一帧后,这帧报文会出现在共享总线上:
节点 A 发送
|
v
+-------------------+-------------------+
| CAN 总线 |
+-------------------+-------------------+
| |
v v
节点 B 看见 节点 C 看见
所有节点都能看见,不代表所有节点都必须处理。各节点可以根据报文标识符选择:
- 接收并处理;
- 看见但不使用;
- 通过硬件过滤器忽略。
因此 CAN 报文不像“只写给某个收件人的私信”,更像带有明确栏目编号的广播。
4. 看懂第一帧 CAN 报文
抓包工具和串口日志常把一帧 CAN 报文显示为:
0x123 [3] 11 22 33
从左到右拆成:
0x123 [3] 11 22 33
| | |
CAN-ID DLC DATA
CAN-ID:报文的标识符
0x123 是这帧报文的 CAN-ID。
0x 表示后面的数字使用十六进制书写。现在只需要把 0x123 看作一个完整编号,不要求立刻掌握十六进制换算。
协议或设备设计者会给不同 CAN-ID 约定不同含义。接收节点看到 0x123 后,可以根据这个编号判断自己是否需要处理这帧报文。
CAN-ID 还会影响报文的发送优先级。假设两个节点恰好同时开始发送:
节点 A 准备发送:0x123
节点 B 准备发送:0x321
对于本教程使用的标准 CAN 数据帧,数值较小的 0x123 优先继续发送,节点 B 会停止本次发送,等待总线空闲后再尝试。这个自动决定发送先后顺序的过程叫作仲裁。节点 B 只是暂时让出总线,并不表示通信出错。
仲裁过程怎样逐位比较,会在后面的课程中展开。现在只需要知道:CAN-ID 既是报文的标识符,也会影响报文占用总线的优先级。
CAN-ID 不应简单理解成“这帧只发给哪台设备的地址”。看一个例子:
传感器发送:CAN-ID 0x180(假设项目约定它表示温度消息)
CAN 总线
|
+--------------+--------------+
| | |
显示器 记录仪 电机
处理 0x180 处理 0x180 忽略 0x180
传感器只是把带有 0x180 标识符的报文放到共享总线上,并没有指定“只交给显示器”。显示器和记录仪可以同时关心 0x180,电机则可以忽略它。
从物理总线角度看,这些节点都能接收到总线上的信号。实际芯片还可以使用接收过滤器,让不关心的 CAN-ID 不必交给应用程序处理。
因此,CAN-ID 更像“消息类别编号”,而不是快递单上的唯一收件地址。后面学习 CANopen 时,会看到 CANopen 把功能类型和 Node-ID 编入一些 CAN-ID;那是 CANopen 对标识符的使用规则,底层报文仍然在共享 CAN 总线上发送。
DLC:数据区有多少字节
[3] 表示 DLC 为 3。DLC 是 Data Length Code 的缩写。
在本课程首先学习的 Classical CAN 数据帧中,可以先把它理解成数据区长度:
DLC = 3
DATA = 11 22 33
后面正好有 3 个数据字节。
DATA:报文携带的数据
11 22 33 是数据区。每两个十六进制字符表示一个字节:
第 0 字节:0x11
第 1 字节:0x22
第 2 字节:0x33
从第 0 字节开始编号,是因为 C 语言数组下标从 0 开始。数据具体代表温度、位置还是状态,CAN 本身并不知道。
5. CAN 负责“怎样传”,不负责“是什么意思”
CAN 控制器会参与处理:
- 报文格式;
- 总线仲裁;
- CRC 等错误检查;
- 接收确认 ACK;
- 通信错误和错误状态。
CAN 本身不规定:
0x123是否代表电机位置;- 某个数据字节使用什么单位;
- 怎样启动一台伺服电机;
- 设备多久报告一次状态。
可以先记成:
CAN 规定数据怎样在总线上可靠传输
上层协议 规定编号和数据应该怎样解释
CANopen 就是一种建立在 CAN 之上的上层协议。我们会先学会 CAN,再进入 CANopen。
6. 三分钟练习
练习一
0x321 [2] AA BB
尝试自己写答案,再往下看:
CAN-ID = 0x321
DLC = 2
DATA = AA BB
练习二
0x701 [1] 05
目前只拆结构,不猜业务含义:
CAN-ID = 0x701
DLC = 1
DATA = 05
练习三
0x601 [8] 40 41 60 00 00 00 00 00
结果:
CAN-ID = 0x601
DLC = 8
DATA = 40 41 60 00 00 00 00 00
0x701 和 0x601 的 CANopen 含义会在后面揭开。现在能正确数出数据字节就够了。
7. 四个常见误解
DLC 是 CAN-ID 的一部分吗
不是。0x123 [3] 中,CAN-ID 是 0x123,DLC 是 3。
DLC 自己占一个 DATA 字节吗
不占。DLC 用来描述长度,不是数据区的一部分。
A 发送后,只有指定的 B 能看见吗
不是。共享总线上的其他节点都能看到,再选择处理或忽略。
只看 DATA 就能知道电机动作吗
不能。还需要知道上层协议、报文标识符规则、数据类型和单位。
8. 对照一条真实格式日志
后续实验会看到类似输出:
CAN-ID 0x701 DLC 1 DATA 05
它和简写形式完全对应:
0x701 [1] 05
日志格式不同,组成部分没有改变。
这节课只记住三句话
- CAN 总线是多个节点共享的通信主干。
- CAN 报文会广播到总线,各节点自己决定是否处理。
- 常见日志可以拆成
CAN-ID + DLC + DATA。
完成检查
不看前文,回答:
0x456 [3] 10 20 30的 CAN-ID 是什么?- DLC 是多少?
- DATA 有哪些字节?
- CAN 是否规定
0x20一定表示速度? - 为什么不能把 CAN-ID 简单看成收件人地址?
答案:
0x456。- 3。
0x10、0x20、0x30。- 不规定,含义由上层协议或项目约定决定。
- 因为报文会广播给总线上的节点,CAN-ID 更接近消息标识符。