1. 从站架构总览
一个 CANopen 从站的固件骨架就四层:
- CAN 驱动:收发报文、错误处理、波特率配置
- 协议核心:对象字典 + NMT/SDO/PDO/心跳/EMCY 处理
- 应用层:你的电机控制、IO、传感器逻辑,读写 OD
- 实时循环:SYNC 驱动的控制循环 / PDO 收发
通信协议部分尽量别手写——直接用成熟开源栈 CANopenNode,把精力放在应用层。
2. 硬件:MCU + 收发器
- MCU:带 CAN 控制器(STM32F1/F4/G4/H7、GD32、NXP S32K 等);G4 系列自带 TDC 和更好的 CAN FD 支持
- 收发器:TJA1050/1042、SN65HVD230(3.3V)等,把 CAN 控制器的 TTL 差分到 CANH/CANL
- 终端电阻:总线两端各 120Ω(可选内部使能)
- 波特率:常用 125k/250k/500k/1Mbps,整网必须一致
- 节点 ID:1~127(0 保留),拨码开关或 OD 配置
波特率要全网络一致,采样点(典型 75%~87.5%)影响长线缆下的鲁棒性。1Mbps 总线长度建议 ≤ 40m,125k 可到 500m 左右。位时间 = 同步段 + 传播段 + 相位段1 + 相位段2,改采样点要重算各段。
3. CANopenNode:别重复造轮子
CANopenNode 是 C 语言写的开源 CANopen 协议栈(含 CiA 301 + 部分 402),结构清晰,适合 STM32 移植。核心文件:
| 文件 | 职责 |
|---|---|
| CO_driver / CO_driver_target | 底层 CAN 收发封装(各平台移植点) |
| CO_OD.c / CO_OD.h | 对象字典(生成器产出,配 EDS) |
| CO_NMT_Heartbeat | NMT 状态机 + 心跳 + 节点守护 |
| CO_SDOserver | SDO 服务端(单帧/分段/块传输) |
| CO_PDO | PDO 通信/映射参数与收发 |
| CO_EMCY | 紧急报文 |
| CO_SYNC | 同步 |
| CO_GFC / CO_LSS | 网关 / 节点ID 配置(可选) |
开发流程通常是:用 EDS 编辑器(如 EDS Editor / 文本)写对象字典 → 生成 CO_OD.c/h → 移植 CO_driver_target → 在主循环/中断里周期调用 CO_CANopen_process 和 CO_... 各模块。
4. 节点初始化流程
- 读节点 ID 与波特率(拨码/EEPROM/OD)
- 初始化 CAN 外设、进入复位/预操作
- 配置 PDO 通信参数(COB-ID、传输类型)与映射(先禁后改再启)
- 配置心跳周期(OD 1017h,0=关闭)并启动心跳发送
- 启动 TPDO 触发(周期定时器或事件)
- 等待主站 NMT 命令进入 Operational
5. 交互式演示:总线负载率计算器
调整节点数、PDO 周期、心跳周期等,实时估算总线负载率。工程上建议把稳态负载控制在 30%~50% 以下,给 EMCY/突发 SDO 留裕量。
单帧位时间估算:标准帧 8 字节 ≈ 47 + 8·DLC + 填充裕量 ≈ 121 位。负载率 = Σ(每秒帧数 × 每帧位数) / 波特率。试想:8 个从站各 1ms 发一帧 8 字节,500k 下负载已到 19%——这就是为什么高节拍系统要用 1Mbps 或缩短数据。
6. 代码实现(C语言)
6.1 CANopenNode 初始化骨架
6.2 主循环:协议处理 + 周期任务
6.3 总线负载率估算
7. 工程要点与常见误区
要点 1:负载率留裕量
稳态周期报文控制在 30%~50% 以下,剩下的给 EMCY、SDO 配置和主站突发请求。CAN 满负载会大幅增加仲裁延迟和错误重发概率。
要点 2:采样点与线缆
高速率 + 长线缆要调采样点(75%~87.5%)、加终端电阻、注意地电位。CAN 是差分但不是隔离的,长距离或跨设备建议加隔离收发器。
要点 3:PDO 映射先禁后改
改映射前把 1F80h(节点保护)/通信参数有效位清 0,改完置 1,再进 Operational。现场"改了没生效"多半是没走这套流程。
要点 4:心跳是维护的命脉
主站通过心跳检测从站掉线;从站也要监控 SYNC 是否还在(同步超时),丢失同步要按配置安全停机,不能继续瞎跑。
误区 1:手写协议栈
CANopen 状态机+SDO 分段+块传输的坑远超想象。用成熟栈(CANopenNode、Canfestival)成熟可靠,把时间花在应用层。
误区 2:所有数据都走 SDO
SDO 只用于配置/诊断。周期性实时数据必须 PDO,否则延迟和总线占用不可控。
误区 3:波特率整网不一致也能凑合
CAN 波特率不一致整网无法通信;换从站、改线后要先核对波特率与采样点。
误区 4:只加 PDO 不算负载
每加一个周期 PDO 就占带宽。设计网络先算负载率(用上面的公式),再定节拍,别等现场堵车才回头。
8. 小结
- 从站 = CAN 驱动 + 协议核心 + 应用层 + 实时循环;协议栈用 CANopenNode 这类成熟开源实现
- 硬件三件套:CAN 控制器 + 收发器 + 终端电阻,波特率整网一致、采样点按线缆调
- 初始化流程:节点 ID/波特率 → 协议栈实例化 → PDO 配置 → 心跳 → 等 NMT 进 Operational
- 主循环里周期调 CO_CANopen_process + 各模块,Operational 后才跑应用
- 总线负载率要预算:8 字节帧 ≈121 位,稳态控制在 30%~50% 以下
至此 CANopen 专题三篇闭环:协议基础(字典与通信对象)→ CiA 402(状态机与模式)→ 从站实现与负载预算。回到 CANopen 专题目录,或继续 FOC 主线的其余高级篇。