13. TPDO 与 RPDO
上一课已经知道:PDO 报文不再重复携带对象地址,而是直接发送事先确定好的数据。
但程序接下来还不能直接写“接收 PDO”。它至少要知道:这条 PDO 是谁发出来的,以及它使用哪个 CAN-ID。
这一课只解决这两个问题。至于 DATA 中装了什么,留到下一课读取电机配置时再判断。
先站在电机这一边看发送和接收
CANopen 文档中经常出现两个名称:
| 缩写 | 英文 | 关键词 |
|---|---|---|
| TPDO | Transmit Process Data Object | 发送 |
| RPDO | Receive Process Data Object | 接收 |
Transmit 是发送,Receive 是接收。不过,这里的方向不是固定站在 ESP32 一边命名,而是站在拥有这组 PDO 配置的设备一边命名。
下一课读取的是电机对象字典中的 PDO 配置,所以现在先站在电机一边看:

从电机角度得到:
| 电机中的名称 | 电机做什么 | ESP32 做什么 |
|---|---|---|
| 电机 TPDO | 发送 | 接收 |
| 电机 RPDO | 接收 | 发送 |
例如,电机可以通过 TPDO 报告当前位置;控制器可以通过 RPDO 向电机发送目标值。这只是常见用途,不能据此断定每台设备的 DATA 内容。
换到 ESP32 一边,名称会怎样变化
假设电机发送一帧 PDO,ESP32 接收它:
| 观察位置 | 对这帧报文的理解 |
|---|---|
| 电机一侧 | 电机正在发送自己的 TPDO |
| ESP32 一侧 | ESP32 正在接收电机发来的数据 |
如果 ESP32 也作为一个完整 CANopen 节点,并为自己配置了接收这帧报文的 PDO,那么对应的是 ESP32 的 RPDO。
因此,T 和 R 不能脱离设备名称单独理解。看到资料写 TPDO1 时,先问一句:
这是哪台设备的 TPDO1?
本教程后面写“电机 TPDO1”或“ESP32 TPDO1”,避免只写一个没有观察角度的名称。
TPDO1 中的数字 1 表示什么
一台 CANopen 设备可以拥有多组 PDO 配置,因此会看到 TPDO1、TPDO2、TPDO3、TPDO4,以及对应的 RPDO1 到 RPDO4。
这里的数字表示该设备内部的第几组 PDO,不是 Node-ID,也不是总线上的第几台设备。
例如“电机 Node-ID 0x01 的 TPDO1”中,0x01 才是节点编号,TPDO1 中的 1 是第一组发送 PDO。两个数字碰巧相同,但含义完全不同。
第一组 PDO 的默认 CAN-ID 怎样计算
CiA 301 的预定义连接组给出了第一组 PDO 的默认基础编号:
| 第一组 PDO | 基础编号 |
|---|---|
| TPDO1 | 0x180 |
| RPDO1 | 0x200 |
使用默认编号时,再加上这台设备的 Node-ID。
本教程电机 Node-ID 为 0x01,因此:
| 电机的 PDO | 计算 | 默认 CAN-ID | 报文方向 |
|---|---|---|---|
| TPDO1 | 0x180 + 0x01 | 0x181 | 电机发送,ESP32 接收 |
| RPDO1 | 0x200 + 0x01 | 0x201 | ESP32 发送,电机接收 |
这里的 0x180 和 0x200 来自 CANopen 的预定义编号,不是 ESP32 的规定,也不是根据抓包结果猜出来的。
默认 CAN-ID 不等于总线上一定有这帧
算出 0x181 以后,只能说:
如果电机 TPDO1 使用 CiA 301 的默认编号,那么它的 CAN-ID 是
0x181。
这还不能证明以下任何一项:
- 电机一定实现了 TPDO1;
- TPDO1 一定已经启用;
- 总线上一定周期出现
0x181; 0x181的 DATA 一定是当前位置。
设备可能没有实现这组 PDO,也可能把它禁用、改成其他 CAN-ID,或者设置为收到特定触发后才发送。DATA 内容还取决于 PDO 映射配置。
这正是下一课需要读取电机对象字典的原因:计算给出规范中的默认值,读取配置才能知道这台真实电机当前怎么设置。
CAN-ID 仍然不是目标设备地址
0x181 虽然包含了 Node-ID 0x01,但不能简单理解为“寄给 1 号电机”。
这帧报文由 1 号电机发送到共享 CAN 总线上。ESP32、另一个控制器或 CAN 分析仪都能看到它,关心 0x181 的节点可以接收并处理,不关心的节点则忽略。
同样,控制器发送 0x201 时,默认配置下 1 号电机会把它当作自己的 RPDO1;其他节点仍然可以在总线上看到该帧,只是不会按自己的 RPDO 处理。
亲手算两个编号
假设总线上还有一个 Node-ID 为 0x20 的 CANopen 节点,并且使用第一组 PDO 的默认编号。
先自己计算它的 TPDO1 和 RPDO1 CAN-ID。
答案:
| ESP32 的 PDO | 计算 | CAN-ID | ESP32 的动作 |
|---|---|---|---|
| TPDO1 | 0x180 + 0x20 | 0x1A0 | 发送 |
| RPDO1 | 0x200 + 0x20 | 0x220 | 接收 |
计算过程只使用了默认规则。实际工程仍要查看节点配置,不能只靠公式断言报文一定存在。
这一课学会了什么
现在可以把电机的第一组 PDO 放在一起回顾:
| 名称 | 相对电机的方向 | 默认计算 | Node-ID 0x01 时 |
|---|---|---|---|
| 电机 TPDO1 | 电机发送 | 0x180 + Node-ID | 0x181 |
| 电机 RPDO1 | 电机接收 | 0x200 + Node-ID | 0x201 |
下一课会读取 0x1800 和 0x1A00。到那里再回答:电机 TPDO1 是否启用、实际 CAN-ID 是多少,以及 0x181 的每个 DATA 字节代表什么。
资料链接
- CAN in Automation:PDO protocol:TPDO、RPDO、通信参数和映射参数。
- CiA 301 CANopen 海报:默认 PDO CAN-ID 和对象索引速查。
- 第 12 课:SDO 查询与 PDO 传输:回顾为什么运行数据需要 PDO。