1. CANopen协议基础:协议栈概述、对象字典概念、PDO与SDO通信机制

各位同学,咱们今天正式开课。

做电机控制这些年,我接触过不少总线协议。Modbus、CANopen、EtherCAT都用过。但要说在工业现场用得最广、最成熟的,还得是CANopen。为什么?说白了,它把CAN总线那层硬件给包装好了,你不需要关心底层怎么发报文,只需要关心「我要读哪个参数」、「我要发什么指令」。嗯,这就是CANopen的魅力。

1.1 CANopen协议栈长什么样?

先说说协议栈。很多人一听到「协议栈」三个字就头大,觉得是特别复杂的东西。其实没那么玄乎。

CANopen协议栈,本质上就是一套软件代码。它帮你实现了CANopen协议规定的那些通信机制。你把它跑在MCU上,你的设备就能跟其他CANopen设备对话了。

我个人习惯把协议栈分成三层来看:

  • 底层驱动层:负责操作CAN控制器,收发报文。这部分跟硬件绑定。
  • 核心协议层:实现NMT、PDO、SDO、心跳等核心机制。这部分是协议栈的灵魂。
  • 应用层:你写的电机控制代码。通过对象字典跟协议栈交互。

我在项目中用过几个开源的协议栈。比如CANopenNode,这个用得最多。它代码结构清晰,移植起来也不费劲。你想想看,一个电机驱动器,跑个CANopenNode,再配上FOC算法,基本就是个标准的伺服驱动器了。

核心要点:协议栈不是魔法,它就是帮你把CANopen协议翻译成C代码。你调用它的API,它帮你发报文、收报文、处理心跳。

1.2 对象字典——CANopen的灵魂

好,接下来聊对象字典。这个概念,我刚开始学的时候也觉得抽象。后来做项目做多了,发现它其实就是一张「参数表」。

每个CANopen设备,内部都有一张对象字典。这张表里,每个条目都有一个16位的索引(Index)和8位的子索引(Subindex)。比如:

  • 0x1000:设备类型
  • 0x1001:错误寄存器
  • 0x1017:心跳生产者时间
  • 0x6040:控制字(电机启停用这个)
  • 0x6041:状态字(读电机当前状态)
  • 0x607A:目标位置(位置模式用)

你看,是不是很像一张寄存器表?

我记得第一次做CANopen电机驱动时,调试了半天电机就是不动。后来发现,原来是对象字典里0x6040控制字的定义没配对。嗯,这种坑踩过一次就记住了。

我的建议:做电机控制,先把CiA 402标准里的对象字典背熟。0x6040、0x6041、0x6060、0x6061这几个,闭着眼睛都得知道是干嘛的。

1.3 PDO——生产者和消费者的游戏

PDO,全称Process Data Object。说白了,就是用来传实时数据的。

PDO有两种:

  • TPDO(发送PDO):你的设备主动往外发数据
  • RPDO(接收PDO):你的设备接收别人发来的数据

PDO的传输方式有几种:

  • 事件触发:数据变了就发。比如电机转速变了,立刻发一帧PDO。
  • 定时触发:每隔固定时间发一次。比如每10ms发一次位置值。
  • 远程请求:别人问你要,你才发。
  • 同步触发:收到SYNC报文后统一发。这个在同步控制里很常用。

PDO的好处是什么?效率高。一帧CAN报文最多8字节,PDO直接往里塞数据,没有协议开销。你想想看,电机控制周期1ms,如果用SDO去读位置,那效率就太低了。

注意:PDO的映射关系需要在初始化阶段配好。我曾经遇到过一个问题:PDO配好了,但数据死活不对。查了半天,发现是映射的字节顺序搞反了。CAN报文是小端模式,这个别忘了。

1.4 SDO——点对点的配置通道

SDO,全称Service Data Object。跟PDO不同,SDO是用来配置参数的,不是用来传实时数据的。

SDO的通信机制是「请求-应答」模式:

  • 主站发一个SDO请求报文
  • 从站回复一个SDO应答报文

SDO报文格式是这样的:

// SDO请求报文(主站发给从站)
// 例如:读对象字典 0x6041(状态字)
// 报文:40 41 60 00 00 00 00 00
// 40 表示读请求
// 41 60 是索引(0x6041,注意字节顺序)
// 00 是子索引
// 后面4字节保留

// SDO应答报文(从站回复)
// 报文:43 41 60 00 06 00 00 00
// 43 表示读成功
// 41 60 是索引
// 00 是子索引
// 06 00 00 00 是读到的数据(0x0006,表示电机处于"准备就绪"状态)

你看,SDO的报文结构其实挺清晰的。但要注意,SDO是分段传输的。如果数据超过4字节,就要分多帧传。嗯,这个细节容易忽略。

我建议:调试阶段用SDO来读写参数。等参数配好了,运行阶段就用PDO。这样既灵活又高效。

1.5 PDO vs SDO——什么时候用哪个?

对比项 PDO SDO
用途 实时数据交换 参数配置
通信方式 生产者/消费者 请求/应答
数据长度 最多8字节 可传输大量数据
效率 高,无协议开销 低,有协议开销
典型应用 位置、速度、电流 增益参数、限位设置

说白了,跑控制周期用PDO,调参数用SDO。这个原则记住了,基本不会出错。

总结一下:CANopen协议栈是骨架,对象字典是血肉,PDO和SDO是血管。理解了这三者的关系,你就掌握了CANopen的精髓。

好,这一章就到这里。下一章咱们聊聊NMT状态机和心跳机制。这些东西在电机控制里也很关键,尤其是做多轴同步的时候。