3. 通信对象COB-ID与预定义连接集

在CANopen网络中,每一个通信对象都由一个唯一的COB-ID(Communication Object Identifier)来标识。COB-ID本质上就是CAN总线上的11位标准帧标识符,它同时承担两个职责:一是标识这条报文属于哪个通信对象,二是通过标识符数值的大小决定总线仲裁优先级。理解COB-ID的分配规则,是从站开发中配置对象字典、实现PDO/SDO通信、以及排查通信异常的基础。

11位标识符的优先级划分

CAN总线采用非破坏性逐位仲裁机制。当多个节点同时发送报文时,标识符数值越小,二进制高位越早出现显性位(0),该报文获得总线控制权的优先级越高。因此,COB-ID的数值大小直接决定了通信对象的实时性等级。CANopen正是利用这一特性,将功能优先级映射到标识符区间上:

  • 高优先级区间(0x000~0x07F):NMT网络管理报文(0x000)、SYNC同步报文(0x080)、EMCY紧急报文(0x081~0x0FF)等,这些报文对实时性和全局协调性要求最高。
  • 中优先级区间(0x180~0x57F):TPDO1~TPDO4、RPDO1~RPDO4、SDO等过程数据与服务数据,是周期性或事件驱动的常规通信。
  • 低优先级区间(0x580~0x77F):SDO响应、心跳/节点保护等,对实时性要求相对宽松。

这种划分不是随意的,而是CANopen协议预定义连接集(Predefined Connection Set)的核心设计。预定义连接集规定了一套默认的COB-ID分配方案,使得从站在上电后无需任何配置即可参与基本通信。

默认COB-ID分配规则

预定义连接集为每个通信对象分配了一个基础功能码(Function Code),再叠加节点号(Node-ID)构成完整的11位COB-ID。基础功能码占据标识符的高4位(bit 10~bit 7),节点号占据低7位(bit 6~bit 0)。节点号有效范围为1~127,0保留给主站或广播。

通信对象基础功能码COB-ID计算式节点号1的示例方向
NMT0x0000x0000x000主站→从站(广播)
SYNC0x0800x0800x080主站→从站(广播)
EMCY0x0800x080 + Node-ID0x081从站→主站
TPDO10x1800x180 + Node-ID0x181从站→主站
RPDO10x2000x200 + Node-ID0x201主站→从站
TPDO20x2800x280 + Node-ID0x281从站→主站
RPDO20x3000x300 + Node-ID0x301主站→从站
TPDO30x3800x380 + Node-ID0x381从站→主站
RPDO30x4000x400 + Node-ID0x401主站→从站
TPDO40x4800x480 + Node-ID0x481从站→主站
RPDO40x5000x500 + Node-ID0x501主站→从站
SDO Tx(响应)0x5800x580 + Node-ID0x581从站→主站
SDO Rx(请求)0x6000x600 + Node-ID0x601主站→从站
心跳/节点保护0x7000x700 + Node-ID0x701从站→主站

需要特别注意:NMT和SYNC使用固定COB-ID,不叠加节点号,因为它们是广播报文,所有从站都必须接收。而EMCY、PDO、SDO、心跳等均为点对点或按节点区分的通信对象,必须叠加节点号才能保证同一网络中多个从站的报文互不冲突。

广播与点对点通信的标识符规则

广播通信的特点是“一个发送者,多个接收者”,其COB-ID不包含节点号,所有节点都监听同一标识符。CANopen中典型的广播对象包括:

  • NMT模块控制:COB-ID固定为0x000,主站发送启动、停止、复位等命令,所有从站接收并执行。
  • SYNC同步报文:COB-ID固定为0x080,主站周期性发送,触发从站同步采样或发送PDO。
  • 时间戳报文:COB-ID固定为0x100,用于网络时间同步。

点对点通信则要求每个从站拥有独立的COB-ID,通过叠加节点号实现。例如节点号为5的从站,其TPDO1的COB-ID为0x180+5=0x185,SDO请求COB-ID为0x600+5=0x605。主站根据目标节点号选择对应的COB-ID发送,只有该节点会响应。

在同一个CANopen网络中,节点号必须唯一。如果两个从站配置了相同的节点号,它们的PDO、SDO、心跳等COB-ID将完全重叠,导致总线仲裁混乱、数据错乱,这是现场调试中最常见的故障之一。

从站如何根据节点号计算自身COB-ID

从站在上电初始化阶段,需要根据自身配置的节点号,计算出所有通信对象的默认COB-ID,并写入对象字典中对应的通信参数条目。以节点号Node-ID=3为例,计算过程如下:

Node-ID = 3

NMT        COB-ID = 0x000              (固定,不叠加)
SYNC       COB-ID = 0x080              (固定,不叠加)
EMCY       COB-ID = 0x080 + 3 = 0x083
TPDO1      COB-ID = 0x180 + 3 = 0x183
RPDO1      COB-ID = 0x200 + 3 = 0x203
TPDO2      COB-ID = 0x280 + 3 = 0x283
RPDO2      COB-ID = 0x300 + 3 = 0x303
TPDO3      COB-ID = 0x380 + 3 = 0x383
RPDO3      COB-ID = 0x400 + 3 = 0x403
TPDO4      COB-ID = 0x480 + 3 = 0x483
RPDO4      COB-ID = 0x500 + 3 = 0x503
SDO Tx     COB-ID = 0x580 + 3 = 0x583
SDO Rx     COB-ID = 0x600 + 3 = 0x603
心跳       COB-ID = 0x700 + 3 = 0x703

这些计算值需要写入对象字典的通信参数子索引中。例如TPDO1的COB-ID存放在索引0x1800子索引0x01中,RPDO1的COB-ID存放在索引0x1400子索引0x01中,SDO请求COB-ID存放在索引0x1200子索引0x01中。从站固件通常在初始化函数中完成这一批量赋值,之后通信栈便依据这些值进行报文过滤和发送。

如果应用需要自定义COB-ID(例如避开网络中其他设备的标识符),可以在对象字典中修改这些条目,但必须保证修改后的COB-ID不与网络中其他节点冲突,且符合11位标准帧格式(0x000~0x7FF)。修改后通常需要重新初始化通信栈或复位节点才能生效。

COB-ID 预定义连接集与节点号叠加关系 节点号 Node-ID 示例:3(范围1~127) 基础功能码 高4位固定,低7位叠加 COB-ID = 功能码 + Node-ID 11位标准帧,0x000~0x7FF 写入对象字典 通信参数子索引 广播通信(COB-ID固定,不叠加节点号) NMT 0x000 SYNC 0x080 TIME 0x100 所有从站监听同一标识符,主站发送,从站接收 点对点通信(COB-ID = 功能码 + Node-ID) TPDO1 0x180+3=0x183 SDO Rx 0x600+3=0x603 心跳 0x700+3=0x703 每个从站拥有独立标识符,主站按目标节点号寻址 11位标识符优先级分布(数值越小优先级越高) 高优先级 0x000~0x0FF 中优先级 0x180~0x57F(PDO/SDO) 低优先级 0x580~0x77F(SDO响应/心跳) 关键规则 ① 广播对象COB-ID固定,不叠加节点号;② 点对点对象COB-ID = 基础功能码 + Node-ID; ③ 节点号1~127唯一,0保留;④ 自定义COB-ID需避免冲突且不超过0x7FF

在实际从站开发中,建议将上述计算封装为一个初始化函数,在节点号确定后统一计算并写入对象字典。这样既保证了默认连接集的一致性,也为后续通过SDO或配置文件修改COB-ID留出了清晰的接口。理解COB-ID的分配逻辑,是读懂CANopen通信行为、分析总线报文和定位通信故障的第一步。