首页 / 驱动算法 / CANopen专题

汇川 SV660 伺服控制:RS485 与 CANopen 通信实战

同一台 SV660,用 485 走 Modbus RTU、用 CAN 走 CANopen 是两种完全不同的"遥控方式":前者按 H 组寄存器逐个读写(参数表驱动),后者按 CiA 402 对象字典操作(状态机驱动)。本文从选型、接口接线讲到两种协议的参数配置、寄存器/对象字典与报文实例,配控制命令报文生成交互演示和可编译 C 代码。

1. SV660 系列与通信选型

汇川 SV660 系列是中小功率交流伺服(0.05~7.5kW,23 位编码器),同一系列按型号后缀区分主通信类型(部分型号同时支持多种协议),买驱动器时"先看后缀、再确认通信口":

型号后缀通信类型典型应用
SV660P脉冲型(内置 RS232 调试口 + RS485/CAN 通信口,支持 Modbus RTU / CANopen / CANlink 三协议)脉冲控制,或 485/CAN 总线连接 PLC、HMI
SV660CCANopen 专用变体(CiA 402 兼容)CANopen 主站(PLC/运动控制卡)带多轴总线控制
SV660ACANlink 专用变体(汇川私有总线)汇川 H5U/AM 系列生态内多轴联动
SV660NEtherCAT 型(CoE,125µs 同步)高端运动控制、多轴同步

容易混淆的一点:SV660P 的"P"是"脉冲型"定位,不等于"只能 485"——它的通信口同时支持 Modbus RTU、CANopen、CANlink 三种协议,SV660C/A 只是"以该协议为主"的专用变体,协议内容与 P 型共用同一套 H 组参数框架。本文聚焦最常见的两条控制链路:SV660P 走 RS485(Modbus RTU)SV660P/C 走 CANopen(C 型即以此为默认协议),具体参数以对应型号手册为准。

ℹ️ 与本站专题的衔接

本文的 CANopen 部分直接复用 CiA 402 伺服行规 的对象字典与状态机;Modbus 帧的 CRC16 校验与 Modbus 计算工具 一致。协议理论请回看对应章节,本文侧重"在 SV660 上怎么落地"。

2. 通信接口:RS485 与 CANopen 接线

两种协议对应两组不同的物理接口,接线规范也完全不同:

项目RS485(Modbus RTU)CANopen(CAN)
信号485+、485-(A/B 差分对)+ GNDCANH、CANL + CAN_GND
线缆屏蔽双绞线,屏蔽层单端接地屏蔽双绞线(120Ω 特性阻抗)
终端电阻总线两端各 1 只(120Ω 或 匹配 485 网络,视驱动能力)总线两端必须各 1 只 120Ω
拓扑菊花链(手拉手),支线尽量短菊花链,支线 ≤0.3m
最大节点标准 32 节点(加中继可扩展)标准 110 节点(每节点 ID 1~127)

两个最容易踩的接线坑:

ℹ️ SV660P 通信口(CN3/CN4,RJ45 网口)线序

SV660P 的 CN3/CN4 是 RJ45 网口形式,实际只用一对双绞线,按型号版本实现 RS485 或 CAN 物理层(有版本为 485 口、有版本为 CAN 口,选型与接线前务必确认手上型号的通信口类型)。汇川同族通信口(S6-L 伺服通讯线)引脚定义如下,水晶头按 T568B 线序压线:

针脚线色(T568B)RS485 模式CAN 模式
1白橙CANH
2CANL
3白绿CGND(隔离地)
4485+(A)
5蓝白485−(B)
6绿
7白棕
8GNDGND
屏蔽PE(单端接地)PE(单端接地)

自制转接线只接 4/5 芯(蓝/蓝白)即可走 485 通信(A=蓝、B=蓝白),但两芯不共地,长线或干扰场合必须把 8 芯 GND 和屏蔽层接上;CAN 变体用 1/2 芯(CANH/CANL)+ 3 芯 CGND。以上为汇川同族(IS620/SV660)通信口定义,具体以手上型号手册为准。

参数设置除了面板按键(四位数码管 + 按键编辑 H 组参数),也可以用汇川 AutoShop / InoComm 调试软件经 RS232 口读写,两种方式改的都是同一套 H 组参数。

3. RS485 / Modbus RTU:参数配置与报文

3.1 通信参数(H0C 组)

485 通信参数集中在 H0C 组,改完一般需要重启驱动器生效:

参数含义典型值
H0C.00伺服轴地址(站号)1~247(0 为广播地址),一台一个
H0C.01串口波特率2400~115200,常用 19200
H0C.02数据格式(校验/停止位)8-N-1 / 8-E-1 / 8-O-1,常用 8N1
⚠️ 上位机与驱动器参数必须一致

波特率、数据格式、站号任何一个不匹配都直接通信失败。站号是"地址唯一性"的基础——多台组网时重号会导致总线冲突,报文会被错误从站应答。

3.2 Modbus RTU 帧格式与功能码

SV660 的 Modbus 映射是 标准 RTU 帧 + H 组参数寄存器:功能码 03 读、06 写单个寄存器、10 写多个寄存器。帧结构(无校验位时 8N1):

RTU 帧

[站地址 1B] [功能码 1B] [寄存器地址 2B] [数据 nB] [CRC16 2B,低字节在前]

寄存器地址 = H 组 16 进制组号 + 组内偏移,例如 H31.00 → 0x3100;H06.04 → 0x0604

寄存器数据一律 大端(高字节在前);多寄存器(32 位数据)注意 SV660 的 CDAB 字序约定(见 3.4 报文实例)。CRC16-Modbus:初值 0xFFFF、多项式 0xA001,与本站 Modbus 工具一致。

3.3 控制寄存器:H31.00 虚拟 DI 方式

SV660 用 虚拟 DI(VDI) 把伺服使能、定位触发、点动等"硬接线输入"搬到寄存器里,上位机写寄存器即可替代端子信号。核心是 H31.00(VDI 状态寄存器,配合 H17 组把 VDI 映射为伺服使能等功能):

寄存器功能写法示例
0x3100(H31.00)VDI 虚拟输入:bit0 伺服使能、bit1 定位触发、bit2 正点动、bit3 负点动写 0x0001 使能 ON / 0x0000 断使能
0x0604(H06.04)速度指令(16 位)写 300 → 0x012C
0x110C(H11.0C)多段位置指令(32 位,CDAB 字序)写 100000 → 86 A0 00 01
ℹ️ 控制流程组合

典型动作是"先使能、后触发":写 H31.00=0x0001 使能 → 写位置/速度 → 写 H31.00=0x0003(bit0+bit1)触发定位。使能状态保持期间,bit0 一直为 1,触发位叠加在上面。

3.4 报文实例(站号 01)

动作功能码完整报文
伺服使能 ON06 写单01 06 31 00 00 01 46 F6
伺服断使能0601 06 31 00 00 00 87 36
定位触发0601 06 31 00 00 03 C7 37
正点动0601 06 31 00 00 05 47 35
写速度 3000601 06 06 04 01 2C C8 CE
写位置 10000010 写多01 10 11 0C 00 02 04 86 A0 00 01 DB 00

读回实际位置/速度/状态用功能码 03:01 03 寄存器 2B 数量 2B,应答帧带字节计数字段,32 位数据同样按 CDAB 字序拼装。位置指令的 CDAB 字序拆解:100000 = 0x0001_86A0,低 16 位字 0x86A0 在前(86 A0),高 16 位字 0x0001 在后(00 01)——与很多 PLC 的"高字在前"习惯相反,这是 485 定位最常见的出错点。

4. CANopen / CiA 402:参数配置与对象字典

4.1 通信参数(CANopen 模式)

SV660 进入 CANopen 控制模式与 485 的模式选择共用一套参数框架:

参数含义设置值
H02.00控制模式 / 通信协议选择8 = CANopen 通信控制
H0C.00CANopen 节点号(Node-ID)1~127,全网唯一,与主站组态一致
H0C.08CAN 波特率代码5 = 500kbps(常用),与主站一致
⚠️ 节点号与波特率必须与主站严格一致

CANopen 没有"自动发现":主站组态里配的节点号、波特率如果和驱动器不一致,SDO 直接无响应(COB-ID 对不上)。排查"发 6040 没反应"先查这两项,再看 6041 状态字回读。

4.2 对象字典:控制字、状态字与运动对象

SV660 的 CANopen 遵循 CiA 402 设备行规,核心对象(与 CiA 402 篇 完全一致):

索引名称方向说明
6040h控制字 ControlwordRPDO主站写,驱动状态机迁移(bit0~3/4/7)
6041h状态字 StatuswordTPDO驱动器回读,反映当前状态位
6060h / 6061h模式 / 模式显示RPDO/TPDO1=位置、3=速度、4=转矩
607Ah目标位置RPDO32 位位置指令(单位:编码器脉冲)
60FFh目标速度RPDO32 位速度指令
6064h实际位置TPDO32 位位置反馈

4.3 使能状态机:0x0006 → 0x0007 → 0x000F

与脉冲/485 方式不同,CANopen 控制不能直接写"使能位",必须按 CiA 402 状态机逐步迁移。控制字关键位:bit0 Switch On、bit1 Enable Voltage、bit2 Quick Stop、bit3 Enable Operation、bit4 New Setpoint、bit7 Fault Reset。最常用的三个控制字:

控制字 6040h作用状态字 6041h 期望反馈
0x0006(bit1+bit2)电压使能:预充电、功率电路就绪bit1=1 Voltage Enabled
0x0007(bit0+1+2)准备就绪:抱闸释放、初始化完成bit2=1 Ready to Switch On
0x000F(bit0+1+2+3)运行使能:电机励磁可动bit2=1 Operation Enabled

位置模式下启动一次定位的完整序列:

  1. SDO 写 6040h = 0x0006 → 0x0007 → 0x000F(使能完成)
  2. SDO 写 607Ah = 目标位置;写 60FFh = 运行速度(可选,取决于速度来源配置)
  3. SDO 写 6040h = 0x001F(0x000F + bit4 New Setpoint),触发本次位置有效
  4. 轮询 6041h,bit10(Target Reached)= 1 表示到位
  5. 到位后写 6040h = 0x000F 清除 bit4,等待下一条指令
⚠️ 别跳步写 0x000F

从掉电状态直接写 0x000F 会被驱动器拒绝(状态机不允许非法迁移)。严格按 0x0006 → 0x0007 → 0x000F 顺序,每一步可以轮询 6041h 确认后再写下一步——这是"写控制字被拒"最常见的原因。

故障时:读 6041h bit3=1 进入 Fault 态,先清除故障源,再写 6040h = 0x0080(bit7 Fault Reset)复位,状态机回到待机态重新走使能序列。故障明细读诊断对象(如 1003h 预定义故障字段),驱动器面板同时显示 Er.xxx 报警码。

5. 控制流程对比:485 vs CANopen

两种方式的差别本质是"寄存器 vs 对象字典"两种范式,落地到同一动作:

动作RS485 / Modbus RTUCANopen / CiA 402
使能写 0x3100 = 0x0001(bit0)6040h:0x0006 → 0x0007 → 0x000F
断使能写 0x3100 = 0x00006040h = 0x0000(或按状态机回退)
定位写 0x110C 位置 → 写 0x3100=0x0003 触发写 607Ah 位置 → 6040h |= bit4
点动写 0x3100 = 0x0005 / 0x0009(bit2/bit3)切换 6060h=3 速度模式,写 60FFh
回状态读 03 功能码轮询寄存器TPDO 主动上报 6041h/6064h(事件或周期)
定位精度依据H 组参数(H05 电子齿轮等)对象字典(6091h/6092h 齿轮比、608Fh 位置单位等)

选型建议:单台、与触摸屏/HMI 或老式 PLC 对接 → 485 Modbus(实现简单、调试直观);多台组网、周期同步、总线负载敏感 → CANopen(PDO 周期映射 + 状态机语义,2M 高速总线可选)。

6. 交互式演示:SV660 控制命令与报文生成器

选择通信方式和命令,实时生成对应报文:Modbus RTU 模式逐字节标注字段并现场计算 CRC16;CANopen 模式生成 SDO 帧(COB-ID = 0x600+节点号)并高亮控制字置位。上方为帧结构,下方为控制字位图。

SV660 控制命令报文生成器(RS485 / CANopen)
选择命令后显示完整报文与字段解析。CRC16 实时计算;CANopen 帧首字节为 SDO 命令符(2B=写16位 / 23=写32位)。

观察要点:同一个"伺服使能"动作,485 是一条 8 字节 RTU 帧(6 字节数据 + CRC),CANopen 是 8 字节 SDO 帧(2B 命令符 + 索引 6040h + 控制字 0x000F)——前者靠 H31.00 的位定义,后者靠 6040h 状态机语义;对比位图可以看出两种协议的"控制字"设计差异。

7. 通信控制 C 代码(Modbus RTU + CANopen SDO)

下面是可直接编译的帧构建示例:Modbus 部分含 CRC16 与 SV660 常用命令封装;CANopen 部分按 CiA 402 SDO 客户端规范生成写入帧。串口/CAN 发送接口按你的平台实现(本站工具链可参考 Modbus 工具 的 CRC 与帧逻辑)。

/* sv660_ctrl.c —— 汇川 SV660 通信控制帧构建示例 * Modbus RTU(RS485) + CANopen(CiA 402 SDO 客户端) * 编译:gcc -o sv660_ctrl sv660_ctrl.c * 运行:./sv660_ctrl * 说明:serial_send()/can_send() 为平台发送接口,按需实现;帧数据已验证 CRC16。 */ #include <stdio.h> #include <stdint.h> #include <string.h> /* ========== Modbus RTU ========== */ /* CRC16-Modbus:初值 0xFFFF,多项式 0xA001,输出低字节在前 */ uint16_t crc16_modbus(const uint8_t *buf, size_t len) { uint16_t crc = 0xFFFF; for (size_t i = 0; i < len; i++) { crc ^= buf[i]; for (int b = 0; b < 8; b++) crc = (crc & 1) ? (crc >> 1) ^ 0xA001 : crc >> 1; } return crc; } /* 功能码 06:写单个寄存器(寄存器数据大端) */ size_t modbus_write_u16(uint8_t *out, uint8_t addr, uint16_t reg, uint16_t val) { size_t n = 0; out[n++] = addr; out[n++] = 0x06; out[n++] = reg >> 8; out[n++] = reg & 0xFF; out[n++] = val >> 8; out[n++] = val & 0xFF; uint16_t crc = crc16_modbus(out, n); out[n++] = crc & 0xFF; /* CRC 低字节在前 */ out[n++] = crc >> 8; return n; } /* 功能码 10:写多个寄存器(count 个寄存器 = count*2 字节数据) */ size_t modbus_write_multi(uint8_t *out, uint8_t addr, uint16_t reg, uint16_t count, const uint8_t *data) { size_t n = 0; out[n++] = addr; out[n++] = 0x10; out[n++] = reg >> 8; out[n++] = reg & 0xFF; out[n++] = count >> 8; out[n++] = count & 0xFF; out[n++] = (uint8_t)(count * 2); for (int i = 0; i < count * 2; i++) out[n++] = data[i]; uint16_t crc = crc16_modbus(out, n); out[n++] = crc & 0xFF; out[n++] = crc >> 8; return n; } /* SV660:伺服使能/断使能(H31.00 bit0) */ size_t sv660_enable(uint8_t *out, uint8_t addr, int on) { return modbus_write_u16(out, addr, 0x3100, on ? 0x0001 : 0x0000); } /* SV660:定位触发(H31.00 = bit0 使能 + bit1 触发) */ size_t sv660_move(uint8_t *out, uint8_t addr) { return modbus_write_u16(out, addr, 0x3100, 0x0003); } /* SV660:写多段位置 H11.0C(32 位,CDAB 字序:低字在前) */ size_t sv660_pos(uint8_t *out, uint8_t addr, int32_t pos) { uint16_t lo = (uint16_t)(pos & 0xFFFF); uint16_t hi = (uint16_t)((uint32_t)pos >> 16); uint8_t d[4] = { lo >> 8, lo & 0xFF, hi >> 8, hi & 0xFF }; return modbus_write_multi(out, addr, 0x110C, 2, d); } /* ========== CANopen / CiA 402 ========== */ /* SDO 下载写 16 位对象(2B 命令符):6040h 控制字等 * CAN 数据帧:COB-ID=0x600+node,8 字节数据 */ size_t sdo_write_u16(uint8_t *data, uint16_t idx, uint8_t sub, uint16_t val) { data[0] = 0x2B; /* 写 16 位(4 字节数据段) */ data[1] = idx & 0xFF; /* 索引低字节在前 */ data[2] = idx >> 8; data[3] = sub; /* 子索引 */ data[4] = val & 0xFF; /* 数据小端 */ data[5] = val >> 8; return 6; } /* SDO 下载写 32 位对象(23 命令符):607Ah 目标位置等 */ size_t sdo_write_u32(uint8_t *data, uint16_t idx, uint8_t sub, uint32_t val) { data[0] = 0x23; data[1] = idx & 0xFF; data[2] = idx >> 8; data[3] = sub; data[4] = val & 0xFF; data[5] = (val >> 8) & 0xFF; data[6] = (val >> 16) & 0xFF; data[7] = (val >> 24) & 0xFF; return 8; } /* 使能序列封装:0x0006 → 0x0007 → 0x000F,依次 SDO 写 6040h */ void sv660_canopen_enable(uint8_t node, uint8_t *buf, size_t *len) { uint16_t seq[3] = { 0x0006, 0x0007, 0x000F }; for (int i = 0; i < 3; i++) { *len = sdo_write_u16(buf + i * 8, 0x6040, 0x00, seq[i]); can_send((uint32_t)0x600 + node, buf + i * 8, *len); /* 平台实现 */ } } /* 打印帧辅助函数 */ void dump(const char *name, const uint8_t *f, size_t n) { printf("%-22s ", name); for (size_t i = 0; i < n; i++) printf("%02X ", f[i]); printf("\n"); } int main(void) { uint8_t f[32]; size_t n; /* Modbus RTU:站号 01 */ n = sv660_enable(f, 0x01, 1); dump("使能 ON", f, n); n = sv660_move(f, 0x01); dump("定位触发", f, n); n = sv660_pos(f, 0x01, 100000); dump("写位置 100000", f, n); /* CANopen:节点 01,SDO 写 6040h=0x000F、607Ah=100000 */ n = sdo_write_u16(f, 0x6040, 0, 0x000F); dump("CANopen 运行使能", f, n); n = sdo_write_u32(f, 0x607A, 0, 100000); dump("CANopen 目标位置", f, n); return 0; }

8. 工程要点与误区

9. 小结

SV660 一机两协议,本质是"参数表驱动"与"状态机驱动"两种控制范式的分水岭:RS485/Modbus 把伺服当作一组 H 寄存器读写,简单直接,适合单机与 HMI/老 PLC;CANopen 把伺服当作 CiA 402 节点,靠对象字典与状态机语义,适合多轴组网与周期同步。选型时按"需要几台、要不要同步、上位机是什么"定,接线和参数按本文两套清单对照配置,大部分通信问题都能在报错前避免。

至此 CAN 板块从 CAN 帧(04)、双波特率(05)到 CANopen 行规(01/02)与从站实现(03),再到本文的真实驱动器落地,形成"协议 → 行规 → 设备"完整链路。