跳到主要内容

TN0002 CANopen 通信功能扩展说明

项目信息
文档编号TN0002
文档版本Rev. 1.0
适用产品JxServo 模组 / 一体化通讯模组
适用场景CANopen 参数配置、恢复默认参数、电角度校准、版本读取、故障读取与故障项控制、节点复位
语言简体中文
最后更新2026-06-05

本文整理近期新增或扩展的 CANopen 通信功能,适用于产品交付、现场调试、系统集成和项目维护。除特别说明外,示例均以节点 ID 为 1 的设备为例。

注意

涉及恢复默认参数、故障屏蔽/使能、故障参数覆盖清除、通信速率修改、电角度校准和节点复位的操作会影响设备参数、保护能力、通信状态或电机动作。执行前请确认设备处于安全位置,伺服未使能,主站具备重新连接和断电恢复手段。

1. SDO 与 NMT 约定

CANopen SDO 示例统一采用以下 ID:

方向COB-ID说明
主站 -> 节点0x600 + NodeID节点 10x601
节点 -> 主站0x580 + NodeID节点 10x581

常用 SDO 命令字:

命令字方向含义
0x40主站 -> 节点SDO Upload,读取对象
0x23主站 -> 节点SDO Download,写入 4 字节对象
0x60节点 -> 主站SDO Download 成功响应
0x60主站 -> 节点分段上传续传请求
0x43节点 -> 主站SDO Upload 返回 4 字节数据
0x80节点 -> 主站SDO Abort,命令被拒绝

SDO 帧中的索引按小端顺序填写。例如对象 0x2540:00 的读取帧为:

CAN ID: 0x601
DLC: 8
DATA: 40 40 25 00 00 00 00 00

2. CAN 通信速率配置 0x2540

支持通过 CANopen SDO 修改 CAN 通信速率,使用厂家自定义对象 0x2540:00

2.1 速率取值

写入值通信模式
0Classic CAN 500K
1Classic CAN 1M
2CAN FD 1M/1M,不启用 BRS
3CAN FD 1M/2M,启用 BRS
4CAN FD 1M/5M,启用 BRS

2.2 读取与写入示例

读取当前速率:

CAN ID: 0x601
DLC: 8
DATA: 40 40 25 00 00 00 00 00

设置为 Classic CAN 500K

CAN ID: 0x601
DLC: 8
DATA: 23 40 25 00 00 00 00 00

设置为 CAN FD 1M/5M,启用 BRS:

CAN ID: 0x601
DLC: 8
DATA: 23 40 25 00 04 00 00 00

写入成功响应:

CAN ID: 0x581
DLC: 8
DATA: 60 40 25 00 00 00 00 00

2.3 生效条件

0x2540 配置会写入 BootPublic。设备不会在线热切换当前 CAN 通信速率,需要复位、重启或重新上电后生效。

执行前请注意:

  • 修改速率时建议保持伺服非使能状态。
  • 写入成功后,主站仍需继续使用旧速率完成当前通信。
  • 设备复位或重新上电后,主站应切换到新速率重新连接。

3. 恢复默认参数 0x1011:03

支持通过 CANopen 标准对象 0x1011:03 恢复应用默认参数。写入 32 位签名 0x64616F6C,也就是 ASCII 字符串 "load",即可触发恢复默认参数。

3.1 执行行为

该操作等价于巨蟹USB上位机中的“恢复系统默认 set_boot=1”功能:

  • 固定覆盖 DEFAULT(1) 参数组。
  • 设置启动参数组为 DEFAULT(1)
  • 不通过切换当前 active/staging 参数组完成;恢复后运行参数会直接切换到默认参数并立即生效。
  • 生效不需要重启。

3.2 门禁条件

  • 仅允许在伺服未使能状态下触发。
  • 如果伺服已使能,设备会直接返回 SDO abort。
  • 未使能状态下,设备会自动授予本次恢复所需的二级权限,不需要额外先发授权命令。

3.3 写入示例

节点 ID 为 1 时,主站发送:

CAN ID: 0x601
DLC: 8
DATA: 23 11 10 03 6C 6F 61 64

字段说明:

字节含义
23SDO expedited download,写 4 字节
11 10index = 0x1011,小端
03sub-index = 0x03
6C 6F 61 64value = 0x64616F6C,小端,即 "load"

成功返回:

CAN ID: 0x581
DLC: 8
DATA: 60 11 10 03 00 00 00 00

判断方式:

  • 0x581 = 0x580 + NodeID(1)
  • 首字节 0x60 表示 SDO download success。
  • 后面的 11 10 03 表示确认写入 0x1011:03

3.4 伺服已使能时的返回

如果设备仍处于伺服使能状态,返回:

CAN ID: 0x581
DLC: 8
DATA: 80 11 10 03 22 00 00 08

判断方式:

  • 首字节 0x80 表示 SDO abort。
  • abort code 为小端 22 00 00 08,即 0x08000022
  • 含义:当前设备状态不允许执行,需先失能伺服后再发送。

4. 启动电角度校准 0x2654:00

支持通过 CANopen SDO 对象 0x2654:00 启动电角度校准,并通过同一个对象读取校准状态。

4.1 启动命令格式

写入值为 uint32,字段定义如下:

bits 31..24 = 0xCA
bits 23..16 = mode
bits 15..0 = align_current_mA
字段含义
mode=0直接检出
mode=1双向拟合
align_current_mA=0使用固件内部默认校准电流
align_current_mA != 0指定 d 轴对齐电流,单位为 mA

4.2 启动示例

节点 ID 为 1,使用双向拟合、默认电流:

CAN ID: 0x601
DLC: 8
DATA: 23 54 26 00 00 00 01 CA

节点 ID 为 1,使用双向拟合、6 A 对齐电流:

CAN ID: 0x601
DLC: 8
DATA: 23 54 26 00 70 17 01 CA

写成功响应:

CAN ID: 0x581
DLC: 8
DATA: 60 54 26 00 00 00 00 00

4.3 读取校准结果

读取 0x2654:00

CAN ID: 0x601
DLC: 8
DATA: 40 54 26 00 00 00 00 00

返回值格式:

bits 31..24 = 0xAC
bits 23..16 = mode
bits 15..8 = status
bits 7..0 = error_code
字段含义
status=0校准失败
status=1校准成功
status=2校准中
error_code失败错误码,校准成功或校准中时通常为 0

返回示例:

校准中:

CAN ID: 0x581
DLC: 8
DATA: 43 54 26 00 00 02 01 AC

校准成功:

CAN ID: 0x581
DLC: 8
DATA: 43 54 26 00 00 01 01 AC

校准失败,错误码 0x03:

CAN ID: 0x581
DLC: 8
DATA: 43 54 26 00 03 00 01 AC

4.4 门禁与错误返回

条件返回
伺服已使能时启动SDO abort 0x08000022
mode 非法或命令标识非法SDO abort 0x06090030

说明:

  • 该功能只通过 0x2654:00 一个 SDO 对象完成启动和结果读取。
  • 校准模块本身不主动发送结果,主站应通过 SDO 读取 0x2654:00 获取状态。
  • 电角度校准可能驱动电机产生动作,执行前请确认设备固定可靠、运动空间安全。

5. 故障读取和故障项控制 0x4500

通过 CANopen SDO 访问 0x4500,可以实现故障读取、故障项屏蔽/使能、覆盖清除和持久化保存。

对象用途
0x4500:00读取历史报错码
0x4500:01写入故障控制命令
important

读取当前活跃/实际发送的报错码时使用 0x603F:000x4500:000x603F:00 的解析差异请参考 FC0001 V2.0报错代码&SDO读取

5.1 32 位命令格式

写入 0x4500:01 的控制命令为 32 位,小端放入 SDO 数据区;命令字段定义如下:

[31:24] op
[23:16] flags
[15:0] fault code
字段含义
op=0x01屏蔽指定故障
op=0x02使能指定故障
op=0x03清除 Flash 中的故障参数覆盖,并重新加载程序默认保护参数到 RAM
op=0x04保存当前 RAM 故障表到 Flash 覆盖区
flags bit0=1屏蔽时同时清除该故障 runtime 状态
flags bit0=0屏蔽时不清 runtime

5.2 速度误差过大示例

速度误差过大的完整故障 ID 为:

0x02000507

SDO 命令中只使用低 16 位故障码:

code = 0x0507

通过 SDO 写 0x4500:01 的常用命令值:

写入值作用SDO 数据字节
0x01010507屏蔽速度误差过大,并清除该故障 runtime 状态07 05 01 01
0x01000507屏蔽速度误差过大,不清除 runtime07 05 00 01
0x02000507重新使能速度误差过大07 05 00 02
0x03000000清除 Flash 故障参数覆盖,并恢复程序默认保护参数到 RAM00 00 00 03
0x04000000保存当前 RAM 故障表到 Flash 覆盖区00 00 00 04

示例:屏蔽速度误差过大并清除 runtime 状态。

CAN ID: 0x601
DLC: 8
DATA: 23 00 45 01 07 05 01 01

写入成功响应:

CAN ID: 0x581
DLC: 8
DATA: 60 00 45 01 00 00 00 00

5.3 读取报错

读取历史报错码:

CAN ID: 0x601
DLC: 8
DATA: 40 00 45 00 00 00 00 00

读取当前活跃/实际发送的报错码:

CAN ID: 0x601
DLC: 8
DATA: 40 3F 60 00 00 00 00 00

5.4 执行说明

  • op=0x01/0x02/0x03/0x04 均要求伺服处于非使能状态。
  • 若伺服已使能,SDO 写入会被拒绝,不会修改 RAM 或 Flash。
  • 写入后设备会先校验 opcode,非法故障码不会访问故障表。
  • 屏蔽或使能会直接修改当前 RAM 故障表中的 enabled 字段。
  • 设置 flags bit0=1 时,只清除指定故障的 runtime 状态,不影响其他故障。
  • op=0x03 等同于巨蟹USB上位机“故障参数存/载”中的 P0=3 清除覆盖:清除 Flash 覆盖区并重新加载程序默认保护参数到 RAM。
  • op=0x04 保存的是当前 RAM 故障表,用于让屏蔽/使能结果掉电保持。
  • 屏蔽故障会降低保护能力,仅建议用于明确原因、明确风险边界的调试或项目配置场景。
周立功工具 .list 示例:故障读取/屏蔽/使能/清除覆盖/保存
<?xml version="1.0"?>
<SendList m_dwCycles="1">
<tagSendUint bIncreaseID="0" bIncreaseData="0" start_index="0" byte_length="0" iInterval="100" iTimes="1" len="1" szname="01_读取0x4500历史报错_确认节点1通讯" select="1" transmitas="2" e2e="0" e2eDataId="0" obj="010600000801000040004501000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" is_canfd="1"></tagSendUint>
<tagSendUint bIncreaseID="0" bIncreaseData="0" start_index="0" byte_length="0" iInterval="100" iTimes="1" len="1" szname="02_屏蔽速度误差过大_不清runtime_code0507" select="1" transmitas="2" e2e="0" e2eDataId="0" obj="010600000801000023004501070500010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" is_canfd="1"></tagSendUint>
<tagSendUint bIncreaseID="0" bIncreaseData="0" start_index="0" byte_length="0" iInterval="100" iTimes="1" len="1" szname="03_使能速度误差过大_code0507" select="1" transmitas="2" e2e="0" e2eDataId="0" obj="010600000801000023004501070500020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" is_canfd="1"></tagSendUint>
<tagSendUint bIncreaseID="0" bIncreaseData="0" start_index="0" byte_length="0" iInterval="100" iTimes="1" len="1" szname="04_屏蔽速度误差过大_并清runtime_code0507" select="1" transmitas="2" e2e="0" e2eDataId="0" obj="010600000801000023004501070501010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" is_canfd="1"></tagSendUint>
<tagSendUint bIncreaseID="0" bIncreaseData="0" start_index="0" byte_length="0" iInterval="300" iTimes="1" len="1" szname="05_清除Flash故障参数覆盖并恢复默认" select="1" transmitas="2" e2e="0" e2eDataId="0" obj="010600000801000023004501000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" is_canfd="1"></tagSendUint>
<tagSendUint bIncreaseID="0" bIncreaseData="0" start_index="0" byte_length="0" iInterval="300" iTimes="1" len="1" szname="06_保存当前RAM故障表到Flash覆盖区" select="1" transmitas="2" e2e="0" e2eDataId="0" obj="010600000801000023004501000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" is_canfd="1"></tagSendUint>
<tagSendUint bIncreaseID="0" bIncreaseData="0" start_index="0" byte_length="0" iInterval="100" iTimes="1" len="1" szname="07_重新读取0x4500历史报错_确认SDO正常" select="1" transmitas="2" e2e="0" e2eDataId="0" obj="010600000801000040004501000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" is_canfd="1"></tagSendUint>
</SendList>

6. CANopen 版本号读取

标准兼容版本对象保持不变,新增 Boot 和主线版本扩展在 0x3100 firmwareVersion 中读取。

6.1 读取对象

OD名称当前示例值
0x1008:00Device Name 设备名称JXZN
0x1009:00Hardware Version 硬件版本V2.0.0
0x100A:00Software Version 软件版本V2.0.1
0x3100:04Boot Version 启动版本V1.1.0
0x3100:05Mainline Version 主线版本V2.1.0

版本字符串按 ASCII 返回。长度超过 4 字节时,CANopen 会使用分段上传,主站需要在收到首段后继续发送 0x60 续传请求,直到字符串读取完成。

6.2 读取帧示例

读取设备名称 0x1008:00

CAN ID: 0x601
DLC: 8
DATA: 40 08 10 00 00 00 00 00

读取硬件版本 0x1009:00

CAN ID: 0x601
DLC: 8
DATA: 40 09 10 00 00 00 00 00

读取软件版本 0x100A:00

CAN ID: 0x601
DLC: 8
DATA: 40 0A 10 00 00 00 00 00

读取 Boot 版本 0x3100:04

CAN ID: 0x601
DLC: 8
DATA: 40 00 31 04 00 00 00 00

读取主线版本 0x3100:05

CAN ID: 0x601
DLC: 8
DATA: 40 00 31 05 00 00 00 00

分段上传续传请求:

CAN ID: 0x601
DLC: 8
DATA: 60 00 00 00 00 00 00 00
周立功工具 .list 示例:读取设备、硬件、软件、Boot 和主线版本
<?xml version="1.0" encoding="UTF-8"?>
<SendList m_dwCycles="1">
<tagSendUint bIncreaseID="0" bIncreaseData="0" start_index="0" byte_length="0" iInterval="50" iTimes="1" len="1" szname="01_读取厂家设备名_1008" select="1" transmitas="2" e2e="0" e2eDataId="0" obj="01060000080100004008100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" is_canfd="1"></tagSendUint>
<tagSendUint bIncreaseID="0" bIncreaseData="0" start_index="0" byte_length="0" iInterval="50" iTimes="1" len="1" szname="02_读取硬件版本_1009" select="1" transmitas="2" e2e="0" e2eDataId="0" obj="01060000080100004009100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" is_canfd="1"></tagSendUint>
<tagSendUint bIncreaseID="0" bIncreaseData="0" start_index="0" byte_length="0" iInterval="50" iTimes="1" len="1" szname="03_硬件版本续传请求" select="1" transmitas="2" e2e="0" e2eDataId="0" obj="01060000080100006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" is_canfd="1"></tagSendUint>
<tagSendUint bIncreaseID="0" bIncreaseData="0" start_index="0" byte_length="0" iInterval="50" iTimes="1" len="1" szname="04_读取软件版本_100A" select="1" transmitas="2" e2e="0" e2eDataId="0" obj="0106000008010000400A100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" is_canfd="1"></tagSendUint>
<tagSendUint bIncreaseID="0" bIncreaseData="0" start_index="0" byte_length="0" iInterval="50" iTimes="1" len="1" szname="05_软件版本续传请求" select="1" transmitas="2" e2e="0" e2eDataId="0" obj="01060000080100006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" is_canfd="1"></tagSendUint>
<tagSendUint bIncreaseID="0" bIncreaseData="0" start_index="0" byte_length="0" iInterval="50" iTimes="1" len="1" szname="06_读取Boot版本_3100_04" select="1" transmitas="2" e2e="0" e2eDataId="0" obj="01060000080100004000310400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" is_canfd="1"></tagSendUint>
<tagSendUint bIncreaseID="0" bIncreaseData="0" start_index="0" byte_length="0" iInterval="50" iTimes="1" len="1" szname="07_Boot版本续传请求" select="1" transmitas="2" e2e="0" e2eDataId="0" obj="01060000080100006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" is_canfd="1"></tagSendUint>
<tagSendUint bIncreaseID="0" bIncreaseData="0" start_index="0" byte_length="0" iInterval="50" iTimes="1" len="1" szname="08_读取主线版本_3100_05" select="1" transmitas="2" e2e="0" e2eDataId="0" obj="01060000080100004000310500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" is_canfd="1"></tagSendUint>
<tagSendUint bIncreaseID="0" bIncreaseData="0" start_index="0" byte_length="0" iInterval="50" iTimes="1" len="1" szname="09_主线版本续传请求" select="1" transmitas="2" e2e="0" e2eDataId="0" obj="01060000080100006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" is_canfd="1"></tagSendUint>
</SendList>

7. CANopen NMT 安全复位

支持通过标准 CANopen NMT 指令复位指定节点 MCU。复位请求会进入通用安全复位流程,不会在收到报文后立即重启。

7.1 复位帧格式

发送 11-bit 标准帧:

字段
CAN ID0x000
DLC2
Byte00x81,Reset Node
Byte1目标 Node ID,1..1270 表示广播

复位节点 1

CAN ID: 0x000
DLC: 2
DATA: 81 01

当前也支持:

CAN ID: 0x000
DLC: 2
DATA: 82 01

0x82 是 CANopen Reset Communication。目前该指令和 Reset Node 一样进入安全 MCU 软重启流程;“仅重启 CAN 通信栈”的行为后续再单独拆分。

7.2 复位门禁

复位请求的处理流程如下:

  1. 收到 NMT reset 指令。
  2. 判断当前是否处于 operation-enabled。
  3. 如果仍处于 operation-enabled,拒绝复位。
  4. 如果不是 operation-enabled,受理复位请求。
  5. 执行复位前准备:关闭 PWM;有抱闸配置时执行抱闸释放命令。
  6. 启动 100 ms 延迟复位任务。
  7. 100 ms 后再次检查 operation-enabled。
  8. 如果期间重新进入 operation-enabled,取消本次复位。
  9. 否则执行 MCU 软复位。

7.3 复位后确认

普通 CANopen 复位不会写备份域,不会进入 Bootloader。只有 Bootloader 复位 reason 才会在最终复位前写入备份域 magic。

节点复位后会重新启动,主站应等待 0x700 + NodeID 的 Boot-up heartbeat,数据字节为 00

节点 1 的 Boot-up heartbeat 为:

CAN ID: 0x701
DLC: 1
DATA: 00

默认上电后为 Pre-Operational。若需要 PDO 运行,主站再发送:

CAN ID: 0x000
DLC: 2
DATA: 01 01

该帧会让节点 1 进入 Operational。