3. CANopen协议概述:协议分层、对象字典、通信模型、设备模型与网络管理
CANopen是一种基于CAN总线的应用层协议,它并非简单地定义报文格式,而是构建了一套完整的设备互操作规范。理解CANopen,需要从五个维度切入:协议分层明确了数据从物理层到应用层的流转路径;对象字典(OD)是所有通信与功能的“寄存器地图”;通信模型定义了数据如何被封装与传递;设备模型规定了不同功能设备的内部结构;网络管理(NMT)则负责整个网络的启动、监控与故障恢复。这五个部分共同构成了CANopen的骨架,也是后续开发与调试的基础。
上图展示了CANopen各核心模块之间的逻辑关系。对象字典处于中心位置,所有通信行为(PDO/SDO)最终都映射到OD的条目上;设备模型则规定了OD中必须包含哪些标准对象;NMT负责控制设备在通信状态机中的迁移。下面逐一展开每个模块的工程实现要点。
3.1 协议分层:从CAN帧到应用对象的映射
CANopen协议栈在OSI模型中的位置横跨数据链路层与应用层。物理层和数据链路层由CAN控制器硬件实现,而CANopen规范(CiA 301)定义了应用层的对象字典、通信对象及网络管理规则。在实际开发中,工程师通常不需要关心CAN控制器内部的位时序或仲裁机制,但必须理解CAN帧的11位标识符(CAN 2.0A)如何被CANopen重新定义。
核心原理:CANopen将11位CAN-ID划分为功能码(4位)和节点ID(7位)。功能码决定了帧类型(如PDO1、SDOtx、NMT等),节点ID则唯一标识网络中的设备。例如,0x180 + NodeID 表示PDO1发送帧,0x580 + NodeID 表示SDO响应帧。这种编码方式使得报文过滤和优先级管理变得非常直接——功能码越小,优先级越高。
| 功能码范围 | 通信对象 | 默认优先级 | 典型用途 |
|---|---|---|---|
| 0x000-0x07F | NMT/同步/紧急 | 最高 | 网络管理、同步、错误报警 |
| 0x080-0x0FF | PDO1-PDO4 (发送) | 高 | 实时过程数据(如速度、位置) |
| 0x100-0x17F | PDO1-PDO4 (接收) | 中高 | 控制命令(如目标位置) |
| 0x180-0x1FF | SDO (发送/接收) | 中 | 对象字典读写(配置参数) |
| 0x200-0x2FF | 心跳/节点守护 | 低 | 节点状态监控 |
判断方法:在抓取CAN总线报文时,首先查看CAN-ID的高4位(二进制),即可快速判断该帧属于哪类通信对象。例如,ID=0x181(二进制0001 1000 0001)中,高4位为0001,表示PDO1发送帧,低7位为0000001,表示节点1。
3.2 对象字典:设备功能的“寄存器地图”
对象字典是CANopen设备的核心数据结构,它是一个16位索引的有序数组,每个索引下可包含多个子索引(0-255)。OD条目定义了数据类型(如UNSIGNED8、INTEGER32)、访问权限(只读/只写/读写)以及默认值。所有通信对象(PDO映射、SDO访问)最终都作用于OD条目。
核心原理:OD的索引空间被划分为多个区域:0x1000-0x1FFF为通信参数区(如设备类型、错误寄存器、PDO参数);0x2000-0x5FFF为制造商特定区;0x6000-0x9FFF为标准设备行规区(如CiA 402的0x6040控制字、0x6060模式选择)。这种划分保证了不同厂商的设备在标准对象上具有互操作性。
// 对象字典条目定义示例(C语言结构体)
typedef struct {
uint16_t index; // 索引号,如 0x6040
uint8_t subIndex; // 子索引,如 0x00
uint8_t dataType; // 数据类型,如 UNSIGNED16
uint8_t accessType; // 访问权限,如 RW
void* dataPtr; // 指向实际存储变量的指针
uint32_t dataSize; // 数据大小(字节)
} OD_Entry_t;
操作流程:在开发中,通常使用EDS(电子数据表)文件描述OD的静态结构。流程为:1)根据设备功能选择对应的CiA行规;2)在EDS中定义所有标准对象和制造商特定对象;3)在固件中实现OD存储区(RAM或Flash);4)通过SDO服务器处理读写请求。
| 索引范围 | 区域名称 | 内容示例 | 访问方式 |
|---|---|---|---|
| 0x1000-0x1FFF | 通信参数区 | 0x1000设备类型、0x1017心跳周期、0x1400-0x1BFF PDO参数 | SDO/部分PDO |
| 0x2000-0x5FFF | 制造商特定区 | 厂商自定义的校准参数、诊断信息 | SDO |
| 0x6000-0x9FFF | 行规区 | CiA 402: 0x6040控制字、0x6060模式、0x607A目标位置 | SDO/PDO |
3.3 通信模型:PDO、SDO与时间关键型数据
CANopen定义了四种核心通信对象:PDO(过程数据对象)、SDO(服务数据对象)、NMT(网络管理)和特殊对象(同步、心跳、紧急)。其中PDO和SDO是数据传输的主力,两者在设计哲学上截然不同。
核心原理:PDO是“生产者/消费者”模式,无确认机制,数据长度最多8字节,适合周期性或事件触发的高速数据交换(如位置、速度)。SDO是“客户端/服务器”模式,有确认机制,支持任意长度的数据分段传输,适合配置参数或非周期性数据。PDO的映射关系(即OD中哪些条目被映射到PDO)通过OD的0x1600-0x1BFF区域配置。
判断方法:选择PDO还是SDO,取决于数据更新频率和实时性要求。如果数据需要每个控制周期(如1ms)更新,且允许丢帧,则使用PDO;如果数据是偶发性的配置命令,且必须保证送达,则使用SDO。例如,伺服使能命令通常通过PDO发送(因为需要快速响应),而修改PID参数则通过SDO。
// PDO映射示例:将控制字(0x6040)和目标速度(0x60FF)映射到PDO1
// 映射参数对象 0x1600 子索引1: 映射条目1
// 子索引2: 映射条目2
0x1600, sub 0: 2 // 映射条目数量
0x1600, sub 1: 0x60400010 // 索引0x6040, 子索引0, 长度16位
0x1600, sub 2: 0x60FF0020 // 索引0x60FF, 子索引0, 长度32位
3.4 设备模型:CiA行规与设备子协议
设备模型定义了特定类型设备(如驱动器、I/O模块、编码器)必须实现的对象字典条目和状态机。CiA(CAN in Automation)组织发布了多个设备行规,其中CiA 401(I/O设备)和CiA 402(驱动设备)最为常用。
核心原理:CiA 402定义了驱动设备的“状态机”(如初始化、准备就绪、运行、故障),以及控制字(0x6040)和状态字(0x6041)的位定义。例如,控制字的Bit0为“使能”位,Bit3为“使能运行”位。设备模型还规定了必须支持的SDO服务(如读取设备类型)和可选功能(如插补模式)。
| 行规编号 | 设备类型 | 关键对象 | 典型应用 |
|---|---|---|---|
| CiA 401 | 数字/模拟I/O | 0x6000读输入、0x6200写输出 | PLC远程I/O、传感器模块 |
| CiA 402 | 驱动设备 | 0x6040控制字、0x6060模式、0x607A目标位置 | 伺服、变频器、步进电机 |
| CiA 406 | 编码器 | 0x6502位置值、0x6503增量计数 | 式编码器接口 |
操作流程:开发一个符合CiA 402的伺服驱动器,需要:1)实现状态机转换逻辑;2)定义0x6060(运行模式)支持的模式(如位置模式、速度模式);3)实现PDO映射以支持实时控制;4)通过SDO提供参数配置接口。在一致性测试中,使用CANopen测试工具(如CANopen Magic)验证所有强制对象是否可访问。
3.5 网络管理:节点生命周期与错误控制
网络管理(NMT)负责控制CANopen网络中每个节点的状态。NMT状态机包含四个主要状态:初始化(Initialization)、预操作(Pre-operational)、操作(Operational)和停止(Stopped)。节点上电后自动进入初始化,然后迁移到预操作状态,此时只能进行SDO通信;只有进入操作状态后,PDO通信才被允许。
核心原理:NMT报文是特殊格式的CAN帧,CAN-ID固定为0x000,数据域包含命令码和目标节点ID。例如,命令码0x01表示“启动节点”,0x02表示“停止节点”,0x80表示“进入预操作”。主站通过发送NMT报文控制所有节点或单个节点。心跳机制(Heartbeat)用于监控节点状态:每个节点以固定周期(由0x1017定义)发送心跳报文,主站通过超时检测判断节点是否离线。
// NMT报文示例:启动节点5
// CAN-ID: 0x000
// Data[0] = 0x01 (启动命令)
// Data[1] = 0x05 (目标节点ID)
// 广播命令:Data[1] = 0x00 表示所有节点
操作流程:网络启动流程通常为:1)主站发送“进入预操作”广播(0x80, 0x00);2)主站逐个发送“启动节点”命令(0x01, NodeID);3)节点进入操作状态并开始发送心跳;4)主站监控心跳超时。在调试阶段,可以使用“停止节点”命令(0x02)隔离故障设备。
| NMT命令 | 命令码 | 目标状态 | 典型场景 |
|---|---|---|---|
| 启动节点 | 0x01 | 操作 | 正常启动 |
| 停止节点 | 0x02 | 停止 | 紧急停机 |
| 进入预操作 | 0x80 | 预操作 | 配置阶段 |
| 复位节点 | 0x81 | 初始化 | 故障恢复 |
| 复位通信 | 0x82 | 初始化 | 通信参数重载 |