CAN 总线舵机通讯协议
1. 简介
本文档介绍 Fashion Star CAN 总线舵机的数据区应用层通讯协议。该协议用于主控设备与舵机之间的参数读写、状态查询和运动控制,并定义响应封包、连续写入、缓存提交、公开内存表、字节序及响应匹配规则。
1.1 适用范围
本文档适用于 Fashion Star CAN 总线舵机的主控开发、上位机开发、系统集成和通讯测试。
协议版本
本文基于协议版本 0.2.0.04172025 整理。不同型号或固件版本可能增删地址,或调整参数语义;集成前应确认目标舵机的型号和固件版本。
- 未列出的地址属于未定义地址,不应访问。
- 产品集成前,应确认目标舵机型号、固件版本、CAN 链路层配置以及所有使用参数的单位和范围。
1.2 协议边界
本文档仅定义 CAN 数据帧的数据区内容,不定义 CAN 仲裁 ID、标准帧或扩展帧、数据帧或远程帧、物理层初始波特率、终端电阻、节点数量上限及 CAN-FD 使用方式。
Warning
CAN 链路层配置应以具体产品规格书或整机接口规范为准。未明确公开的配置不得自行推定。
2. 通用约定
2.1 字节编号与封包长度
- 原始协议的
Byte1对应本文的Data[0],其余字节依次类推。 - DLC 表示应用层封包实际使用的数据字节数。发送方应按命令规定设置 DLC;接收方应先校验 DLC,再解析数据。
- 本协议封包最长为 8 byte。
2.2 命令标识符
Data[0] 为单字节 ASCII 命令标识符。例如,字符 r 的字节值为 0x72,字符 R 的字节值为 0x52。命令标识符区分大小写。
2.3 舵机 ID
Data[1] 为单字节 ServoID。普通单播通讯所允许的编号范围由具体产品配置约束决定,参考文件未给出完整范围。
ServoID = 0xFF 仅在连续写入的同步运动场景中被明确用于广播已缓存舵机。除该场景外,不应假定所有固件或所有命令都支持 0xFF 广播。会产生响应的命令不应广播,以免多个节点同时发送响应。
2.4 参数宽度与字节序
除 5.4 节特别说明的源表异常项外,内存表中的单个参数长度均为 2 byte。封包采用低字节在前、高字节在后的顺序:
Value = Value_L | (Value_H << 8)
名称带 (L) 和 (H) 的相邻地址共同构成 32 bit 数据,其中 (L) 地址存放低 16 bit,(H) 地址存放高 16 bit:
Value32 = Word_L | (Word_H << 16)
小端字节序
多字节数据采用小端字节序,即低位字节在前、高位字节在后。除非具体参数另有说明,不得自行推定参数的有符号性、工程单位、比例系数或物理量换算关系。
2.5 校验、错误与超时
- 参考文件未定义应用层校验和或 CRC 字段;CAN 链路层仍使用 CAN 自身的错误检测机制。
- 参考文件未定义非法命令、非法地址、只读地址写入或参数越界时的错误响应。
- 参考文件未规定响应超时、重试次数和重复命令处理策略,应由主控结合目标产品和总线负载确定。
- 写后响应返回设备写入后对应地址的当前值。主控应比较请求值和响应值,不应仅凭收到响应就认定请求值已被原样接受。
3. 控制指令
下表汇总 CAN 总线舵机的应用层控制指令。命令标识符区分大小写。
| CMD | Hex | 方向 | 功能 | DLC | 响应 |
|---|---|---|---|---|---|
r |
0x72 |
主控 -> 舵机 | 读取一个参数 | 3 | v,DLC = 5 |
R |
0x52 |
主控 -> 舵机 | 读取两个参数 | 4 | V,DLC = 8 |
w |
0x77 |
主控 -> 舵机 | 写入一个参数 | 5 | 无响应 |
W |
0x57 |
主控 -> 舵机 | 写入两个参数 | 8 | 无响应 |
x |
0x78 |
主控 -> 舵机 | 写入一个参数并响应 | 5 | v,DLC = 5 |
X |
0x58 |
主控 -> 舵机 | 写入两个参数并响应 | 8 | V,DLC = 8 |
Q |
0x51 |
主控 -> 舵机 | 开始连续写入 | 2 | 无响应 |
q |
0x71 |
主控 -> 舵机 | 结束连续写入并提交 | 2 | 无响应 |
v |
0x76 |
舵机 -> 主控 | 单参数响应 | 5 | 由 r 或 x 触发 |
V |
0x56 |
舵机 -> 主控 | 双参数响应 | 8 | 由 R 或 X 触发 |
4. 封包结构
4.1 读取一个参数
- 请求命令:
r(0x72) - 响应命令:
v(0x76)
4.1.1 请求封包
| 字节 | 字段 | 说明 |
|---|---|---|
Data[0] |
CMD |
固定为 r (0x72) |
Data[1] |
ServoID |
目标舵机编号 |
Data[2] |
Addr |
参数地址 |
4.1.2 响应封包
| 字节 | 字段 | 说明 |
|---|---|---|
Data[0] |
CMD |
固定为 v (0x76) |
Data[1] |
ServoID |
响应舵机编号 |
Data[2] |
Addr |
参数地址,应与请求一致 |
Data[3] |
Value_L |
参数低字节 |
Data[4] |
Value_H |
参数高字节 |
4.2 读取两个参数
- 请求命令:
R(0x52) - 响应命令:
V(0x56)
4.2.1 请求封包
| 字节 | 字段 | 说明 |
|---|---|---|
Data[0] |
CMD |
固定为 R (0x52) |
Data[1] |
ServoID |
目标舵机编号 |
Data[2] |
Addr_A |
参数 A 地址 |
Data[3] |
Addr_B |
参数 B 地址 |
4.2.2 响应封包
| 字节 | 字段 | 说明 |
|---|---|---|
Data[0] |
CMD |
固定为 V (0x56) |
Data[1] |
ServoID |
响应舵机编号 |
Data[2] |
Addr_A |
参数 A 地址,应与请求一致 |
Data[3] |
Value_A_L |
参数 A 低字节 |
Data[4] |
Value_A_H |
参数 A 高字节 |
Data[5] |
Addr_B |
参数 B 地址,应与请求一致 |
Data[6] |
Value_B_L |
参数 B 低字节 |
Data[7] |
Value_B_H |
参数 B 高字节 |
4.3 写入一个参数
- 无响应写入命令:
w(0x77) - 有响应写入命令:
x(0x78)
4.3.1 指令封包
| 字节 | 字段 | 说明 |
|---|---|---|
Data[0] |
CMD |
w (0x77) 或 x (0x78) |
Data[1] |
ServoID |
目标舵机编号 |
Data[2] |
Addr |
参数地址 |
Data[3] |
Value_L |
参数低字节 |
Data[4] |
Value_H |
参数高字节 |
响应规则
w 写入后不响应;x 写入后使用 5 byte 的 v 封包返回对应地址的当前值。主控应比较请求值和响应值,不应仅凭收到响应就认定请求值已被原样接受。
4.4 写入两个参数
- 无响应写入命令:
W(0x57) - 有响应写入命令:
X(0x58)
4.4.1 指令封包
| 字节 | 字段 | 说明 |
|---|---|---|
Data[0] |
CMD |
W (0x57) 或 X (0x58) |
Data[1] |
ServoID |
目标舵机编号 |
Data[2] |
Addr_A |
参数 A 地址 |
Data[3] |
Value_A_L |
参数 A 低字节 |
Data[4] |
Value_A_H |
参数 A 高字节 |
Data[5] |
Addr_B |
参数 B 地址 |
Data[6] |
Value_B_L |
参数 B 低字节 |
Data[7] |
Value_B_H |
参数 B 高字节 |
响应规则
W 写入后不响应;X 写入后使用 8 byte 的 V 封包返回两个对应地址的当前值。主控应同时核对两个地址、地址顺序和实际响应值。
4.5 连续写入
4.5.1 开始连续写入
| 字节 | 字段 | 说明 |
|---|---|---|
Data[0] |
CMD |
固定为 Q (0x51) |
Data[1] |
ServoID |
目标舵机编号 |
4.5.2 结束并提交
| 字节 | 字段 | 说明 |
|---|---|---|
Data[0] |
CMD |
固定为 q (0x71) |
Data[1] |
ServoID |
目标舵机编号 |
4.5.3 连续写入规则
- 舵机收到
Q后,后续写入参数先进入缓存区。 - 缓存区最多接收 8 组
w或W封包;收到第 8 组后,设备自动执行一次写入。 - 连续写入期间,
x和X分别按w和W处理,不发送响应。 - 连续写入期间收到
r或R,不会改变连续写入行为。 - 收到
q后,设备停止接收连续写入参数,并将缓存区参数一次写入。 - 参考文件未说明第 8 组自动写入后是否自动退出缓存状态。主控不应依赖未定义行为,应显式发送
q完成流程。
同步运动
可在缓存状态内写入地址 0x50-0x58 的运动参数,再向地址 0x59 写入 0x0001。该触发可使用指定 ServoID,也可使用 ServoID = 0xFF 广播已缓存舵机。广播触发不应等待设备响应。
5. 内存表
5.1 表格说明
- “长度”单位为 byte。
- “-”表示参考文件未规定,不表示数值为 0。
- “未公开”表示该访问属性没有对外公开。
- 未给出单位、缩放或范围的参数只能按原始值访问,不应擅自换算成工程量。
5.2 设备信息与实时状态
| 地址 | 参数 | 长度 | 可读 | 可写 | 默认值 | 范围/枚举 | 单位 | 说明 |
|---|---|---|---|---|---|---|---|---|
0x01 |
舵机型号 | 2 | 是 | 未公开 | - | - | - | - |
0x02 |
固件版本 | 2 | 是 | 未公开 | - | - | - | - |
0x03 |
舵机序号 (L) | 2 | 是 | 未公开 | - | - | - | 序号低 16 bit |
0x04 |
舵机序号 (H) | 2 | 是 | 未公开 | - | - | - | 序号高 16 bit |
0x10 |
舵机电压 | 2 | 是 | 否 | - | - | 未规定 | - |
0x11 |
舵机电流 | 2 | 是 | 否 | - | - | 未规定 | - |
0x12 |
舵机功率 | 2 | 是 | 否 | - | - | 未规定 | - |
0x13 |
舵机温度 | 2 | 是 | 否 | - | - | 未规定 | - |
0x14 |
舵机状态 | 2 | 是 | 否 | - | - | - | - |
0x15 |
多圈模式当前角度 (L) | 2 | 是 | 否 | - | - | 未规定 | 当前角度低 16 bit |
0x16 |
多圈模式当前角度 (H) | 2 | 是 | 否 | - | - | 未规定 | 当前角度高 16 bit |
0x17 |
圈数 | 2 | 是 | 否 | - | - | 圈 | - |
0x18 |
当前角度(单圈模式) | 2 | 是 | 否 | - | - | 未规定 | - |
5.3 运动控制
| 地址 | 参数 | 长度 | 可读 | 可写 | 默认值 | 范围/枚举 | 单位 | 说明 |
|---|---|---|---|---|---|---|---|---|
0x28 |
阻尼模式功率 | 2 | 是 | 是 | - | - | mW | 写入后进入阻尼模式 |
0x50 |
到目标角度时间 (L) | 2 | 是 | 是 | - | - | ms | 时间低 16 bit |
0x51 |
到目标角度时间 (H) | 2 | 是 | 是 | - | - | ms | 时间高 16 bit |
0x52 |
角度模式选择 | 2 | 是 | 是 | - | 0:默认;1:基于加减速;2:基于速率 |
- | - |
0x53 |
指定角度 (L) | 2 | 是 | 是 | - | - | 0.1° | 指定角度低 16 bit |
0x54 |
指定角度 (H) | 2 | 是 | 是 | - | - | 0.1° | 指定角度高 16 bit |
0x55 |
角度模式执行功率 | 2 | 是 | 是 | - | - | mW | - |
0x56 |
启动时加速段时间 | 2 | 是 | 是 | - | - | ms | - |
0x57 |
接近目标时减速段时间 | 2 | 是 | 是 | - | - | ms | - |
0x58 |
到目标角度的最大速度 | 2 | 是 | 是 | - | - | 0.1°/s | - |
0x59 |
执行角度运动 | 2 | 是 | 是 | - | 0:默认,不动作;1:执行 |
- | 执行已写入 0x50-0x58 的运动参数 |
5.4 控制与复位
| 地址 | 参数 | 长度 | 可读 | 可写 | 默认值 | 范围/枚举 | 单位 | 说明 |
|---|---|---|---|---|---|---|---|---|
0x78 |
用户数据复位 | 2 | 否 | 是 | 0 |
0-65535 |
- | 复位用户数据区为出厂默认值 |
0x79 |
清除当前圈数 | 2 | 否 | 是 | - | 0:默认;1:清除圈数 |
- | - |
0x7A |
原点设置 | 2 | 否 | 是 | - | 0:将当前舵机角度设为 0°;非零值:恢复出厂设置 |
- | - |
0x7B |
控制模式停止 | 2 | 否 | 是 | - | 0x10:停止后卸力(失锁);0x11:停止后保持锁力;0x12:停止后进入阻尼状态 |
- |
Note
0x78 的源表将最大值写为 0、最小值写为 65535,本文按有效 16 bit 无符号原始值更正为 0-65535。
5.5 通讯与保护配置
| 地址 | 参数 | 长度 | 可读 | 可写 | 默认值 | 范围/枚举 | 单位 | 说明 |
|---|---|---|---|---|---|---|---|---|
0x80 |
控制回应 | 2 | 是 | 是 | - | 未规定 | - | - |
0x81 |
舵机编号 | 2 | 是 | 是 | - | 0-254 | - | - |
0x82 |
波特率 | 2 | 是 | 是 | 6 |
见 5.6 节 | - | 默认 500 kbps |
0x83 |
堵转失锁保护 | 2 | 是 | 是 | - | 未规定 | - | - |
0x84 |
堵转功率上限 | 2 | 是 | 是 | - | 未规定 | mW | - |
0x85 |
低压保护电压 | 2 | 是 | 是 | - | 未规定 | mV | - |
0x86 |
高压保护电压 | 2 | 是 | 是 | - | 未规定 | mV | - |
0x87 |
温度保护值 | 2 | 是 | 是 | - | 未规定 | - | - |
0x88 |
功率保护值 | 2 | 是 | 是 | - | 未规定 | mW | - |
0x89 |
电流保护值 | 2 | 是 | 是 | - | 未规定 | mA | - |
0x8A |
加速度 | 2 | 是 | 是 | - | 未规定 | 未规定 | - |
0x8B |
功率保护迟滞参数 | 2 | 是 | 是 | - | 未规定 | 未规定 | - |
0x8C |
上电锁力开关 | 2 | 是 | 是 | - | 未规定 | - | - |
0x8D |
轮式模式刹车开关 | 2 | 是 | 是 | - | 未规定 | - | - |
0x8E |
角度限制开关 | 2 | 是 | 是 | - | 未规定 | - | - |
0x8F |
上电缓启动开关 | 2 | 是 | 是 | - | 未规定 | - | - |
0x90 |
上电缓启动时间 | 2 | 是 | 是 | - | 未规定 | ms | - |
0x91 |
角度上限 | 2 | 是 | 是 | - | 未规定 | 0.1° | - |
0x92 |
角度下限 | 2 | 是 | 是 | - | 未规定 | 0.1° | - |
0x93 |
中点偏移 | 2 | 是 | 是 | - | 未规定 | 0.1° | - |
5.6 波特率枚举
| 参数值 | CAN 波特率 |
|---|---|
0 |
50 kbps |
1 |
100 kbps |
2 |
125 kbps |
3 |
200 kbps |
4 |
250 kbps |
5 |
400 kbps |
6 |
500 kbps(默认) |
7 |
750 kbps |
8 |
800 kbps |
9 |
1 Mbps |
6. 通讯示例
以下示例仅说明应用层数据区,不包含 CAN 仲裁 ID 等链路层配置。所有字节均以十六进制表示。
6.1 读取单圈当前角度原始值
请求:72 01 18
响应:76 01 18 34 12
响应原始值为 0x1234。
6.2 写入单个参数并校验
示例:向 ServoID = 0x01 的地址 0x85 写入数值 0x0520。
请求数据:
78 01 85 20 05
若写入成功,设备应返回:
76 01 85 20 05
6.3 缓存运动参数后提交
51 01 # Q:开始连续写入
77 01 52 01 00 # w:角度模式选择 = 1
77 01 59 01 00 # w:执行角度运动 = 1,先进入缓存
71 01 # q:提交缓存并结束连续写入
7. 主控实现要求
- 命令标识符必须区分大小写。
- 多字节参数必须按低字节在前的顺序编码和解析。
- 接收响应时至少核对 DLC、命令、
ServoID和地址;双参数响应还应核对两个地址及顺序。 - 对
x和X的响应,应比较实际响应值和请求值。 - 连续写入期间不得等待
x或X响应。 - 对只写参数,应依据具体功能结果或产品定义验证。
- 对单位、缩放、有符号性、状态位和生效时机未公开的参数,不应在对外接口中自行定义含义。
- 修改舵机编号或波特率前,应设计通讯恢复和设备识别流程。