4. 通信对象概述:PDO、SDO、NMT、SYNC、EMCY、TIME、LSS等通信对象简介
好,咱们进入正题。CANopen 协议里,设备之间怎么说话?靠的就是这些通信对象。说白了,它们就是一套标准化的“信使”,每种信使干不同的活。
我个人习惯把 CANopen 的通信对象分成两类:一类是“实时数据”的搬运工,另一类是“管理控制”的传令兵。你想想看,一个电机驱动器,既要实时上报转速,又要能远程修改参数,这两件事对实时性的要求完全不同。所以协议把它们分开了。
4.1 PDO(过程数据对象)—— 快车道上的数据
PDO 是 Process Data Object 的缩写。它的特点就一个字:快。
为什么快? 因为 PDO 报文里没有协议索引,直接就是数据。一个 CAN 帧最多 8 个字节,PDO 可以塞满这 8 个字节,不浪费一点带宽。
我在项目中遇到过这样一个坑:有个同事把电机的位置、速度、电流三个值都映射到一个 PDO 里,结果发现数据更新频率上不去。后来一查,这三个值加起来超过 8 个字节了,被拆成了两个 PDO。嗯,这里要注意,PDO 的映射长度不能超过 8 字节。
PDO 的两种传输方式:
- 同步 PDO: 收到 SYNC 消息后,统一发送。适合需要严格同步的场景,比如多轴联动。
- 异步 PDO: 事件触发或定时发送。比如温度超过阈值就发,或者每 100ms 发一次。
我的小技巧: 调试阶段,我习惯把 PDO 设为事件触发模式,这样每次数据变化都能抓到。量产时再改成定时发送,减少总线负载。
4.2 SDO(服务数据对象)—— 慢车道上的配置
SDO 是 Service Data Object 的缩写。它跟 PDO 正好相反,特点是:慢,但可靠。
SDO 采用“请求-应答”模式。你发一个请求,设备回一个应答。如果没收到应答,主站会重发。这种机制保证了数据不会丢,但代价就是慢。
SDO 的典型应用场景:
- 设备上电后,通过 SDO 配置参数(比如 PID 系数、限位值)。
- 读取设备版本号、序列号等非实时信息。
- 修改对象字典里的任意条目。
我曾经犯过一个错误:在电机高速运转时,通过 SDO 修改了电流环的 PI 参数。结果电机当场抖动了一下,差点撞机。后来我学乖了,改参数前先让设备进入 Pre-Operational 状态。
警告: 不要在设备运行时频繁使用 SDO 修改关键参数。SDO 的响应时间不确定,可能造成系统不稳定。
4.3 NMT(网络管理)—— 设备的“生老病死”
NMT 是 Network Management 的缩写。它负责控制设备的状态机。
CANopen 设备有四个状态:
| 状态 | 说明 | 能干啥 |
|---|---|---|
| Initialisation | 初始化 | 上电后自动进入,完成后自动跳转 |
| Pre-Operational | 预运行 | 只能 SDO 通信,不能 PDO |
| Operational | 运行 | PDO 和 SDO 都可以用 |
| Stopped | 停止 | 只能响应 NMT 命令,其他都不行 |
NMT 命令由主站发出,从站必须响应。比如主站发一个“启动远程节点”的命令,从站就从 Pre-Operational 进入 Operational。
我记得有一次调试,设备怎么都进不了 Operational 状态。查了半天,发现是心跳报文没配置好,主站以为从站死了,一直不给启动命令。嗯,NMT 和心跳是绑定的,这个后面会细讲。
4.4 SYNC(同步对象)—— 大家一起动
SYNC 是一个特殊的 CAN 报文,它的 COB-ID 是 0x80。主站定期发送 SYNC,所有从站收到后,同时更新输出或采集输入。
为什么需要 SYNC? 你想想看,如果三个电机各自按自己的节奏发 PDO,那它们的位置数据就不是同一时刻的。用 SYNC 同步后,所有电机在同一时刻锁存数据,然后一起发上来。这样上位机拿到的就是“快照”。
我在做多轴同步控制时,SYNC 周期设成了 1ms。结果总线负载飙到了 80% 以上。后来把不重要的 PDO 改成异步发送,只让关键数据走同步,问题就解决了。
SYNC 的注意事项:
- SYNC 的发送周期要合理,太短会占用大量带宽。
- 所有从站的时钟偏差要尽量小,否则同步效果会打折扣。
- 如果某个从站没收到 SYNC,它会用上次的数据继续运行,直到超时。
4.5 EMCY(紧急对象)—— 出事了!
EMCY 是 Emergency 的缩写。当设备检测到严重错误时,它会主动发一个紧急报文。
紧急报文的格式很简单:
COB-ID: 0x80 + Node-ID
数据: 错误码 (2字节) + 错误寄存器 (1字节) + 制造商特定 (5字节)
比如电机过流了,错误码是 0x2310。主站收到后,可以立即采取行动,比如切断电源。
我曾经遇到过一个问题:设备频繁发 EMCY,但错误码是 0x0000(无错误)。后来发现是硬件干扰导致报文被误触发。嗯,EMCY 的触发条件一定要设置好,别让噪声也来凑热闹。
4.6 TIME(时间对象)—— 对表
TIME 对象用于同步所有设备的时间。它基于 CANopen 的时间戳协议,精度可以达到微秒级。
说实话,TIME 对象在工业现场用得不多。大多数应用靠 SYNC 就够了。但在一些需要精确时间戳的场景,比如数据采集系统,TIME 就派上用场了。
我记得有个项目,客户要求记录每个报警发生的时间,精度到 1ms。我们就是用 TIME 对象来同步所有从站的时钟,然后在报警时打上时间戳。
4.7 LSS(层设置服务)—— 改节点 ID 不求人
LSS 是 Layer Setting Services 的缩写。它的作用很简单:在线修改设备的节点 ID 和波特率。
你想想看,如果设备已经装到机柜里了,要改节点 ID 还得拆开外壳拨 DIP 开关,多麻烦。LSS 允许主站通过 CAN 总线直接修改这些参数。
LSS 的典型流程:
- 主站发送 LSS 请求,询问“谁是供应商 ID 为 0x123,产品代码为 0x456 的设备?”
- 匹配的设备应答。
- 主站发送“把你的节点 ID 改成 5”。
- 设备保存新 ID,然后重启。
避坑指南: 我曾经在批量配置设备时,忘了检查 LSS 的应答超时。结果有一台设备没收到命令,节点 ID 没改过来,导致总线冲突。后来我加了个重试机制,连续三次没应答就报错。
4.8 总结一下
这些通信对象各有各的用途:
- PDO: 快,用于实时数据交换。
- SDO: 慢但可靠,用于参数配置。
- NMT: 控制设备状态。
- SYNC: 同步所有设备。
- EMCY: 报告紧急错误。
- TIME: 时间同步。
- LSS: 在线修改节点参数。
实际项目中,PDO 和 SDO 用得最多,NMT 和 EMCY 是标配,SYNC 看需求,TIME 和 LSS 属于锦上添花。你根据应用场景选就行。
下一章,我会详细讲 PDO 的映射和配置,这是 CANopen 开发中最容易出问题的地方。到时候咱们再细聊。