1、CANopen知识回顾
在上一讲中,已经对CANopen的基本结构和整体内容进行了一番梳理,本笔记主要整理了一下CANopen如何配置PDO,实现数据周期性自动上传和控制信号快速发送等操作。
CANopen协议开发梳理总结笔记教程-CSDN博客文章浏览阅读920次,点赞31次,收藏16次。CANOpen协议是一种架构在控制局域网络(Controller Area Network, CAN)上的高层通信协议,它广泛应用于工业自动化、机械工程和汽车电子等领域。CANOpen协议通过对象字典、服务数据对象(SDO)、过程数据对象(PDO)等机制,为机器人、运动控制、过程控制、楼宇自动化、交通运输等行业提供了一种标准化的通信解决方案。https://blog.csdn.net/weixin_49337111/article/details/140192162?spm=1001.2014.3001.5501
由于需要区分每个 CANopen 节点的输入和输出,所以 PDO 分为 TPDO(发送 PDO)和RPDO(接收 PDO),发送和接收是以 CANopen 从站节点为参考(如果 CAN 主站就相反)。TPDO和 RPDO 分别有 4 个数据对象,每种数据对象就是 1 条 CAN 报文封装。
如下是所使用的伺服电机控制器中实现 PDO 的传输的4 个 RPDO 和4 个 TPDO。注意,不同控制器的PDO数量可能不一致,需要根据实际产品进行手册参考。
PDO使用时,需要进行映射配置操作,如下所示为PDO映射操作的流程图。
PDO 和 SDO 的通讯区别在于,PDO 属于过程数据,即单向传输,无需接收节点回应CAN 报文来确认,从通讯术语上来说是属于“生产消费”模型。
接下来的部分,将具体讲解,如何实现上述PDO映射操作的实现。
2、NMT网络管理主机
网络管理主机 NMT-Master(Network Management-Master),就像一个指挥官,所有节点的启动、停止都是有他进行指挥NMT 主机和 NMT 从机之间通讯的报文就称为 NMT 网络管理报文。管理报文负责层管理、网络管理和 ID 分配服务。为了协调各个节点的同步、心跳、时间、错误提示等通讯控制,CANopen 还定义了一系列特殊协议(Special protocols)报文。
NMT 管理涉及到一个 CANopen 节点从上电开始的 6 种状态,包括:
初始化(Initializing):节点上电后对功能部件包括 CAN 控制器进行初始化;
应用层复位(Application Reset):节点中的应用程序复位(开始),比如开关量输出、模拟量输出的初始值;
通讯复位(Communication reset):节点中的CANopen通讯复位(开始),从这个时刻起,此节点就可以进行CANopen通讯了。
预操作状态(Pre-operational):节点的CANopen通讯处于操作就绪状态,此时此节点不能进行PDO通信,而可以进行SDO进行参数配置和NMT网络管理的操作;
操作状态(operational):节点收到NMT主机发来的启动命令后,CANopen通讯被激活,PDO通信启动后,按照对象字典里面规定的规则进行传输,同样SDO也可以对节点进行数据传输和参数修改;
停止状态(Stopped):节点收到NMT主机发来的停止命令后,节点的PDO通信被停止,但SDO和NMT网络管理依然可以对节点进行操作;
除初始状态外,NMT主机通过NMT命令可以让网络中任意一个的CANopen节点进行其他5种状态的切换。图中转换由 NMT 报文实现,且只有 NMT 主机能够发送 NMT 控制报文,消息报文格式如下所示:
为了方便讲解说明,接下来的部分,均是默认设备的节点ID为 1
3、PDO配置操作流程
在这一部分的内容中,以配置目标位置(0x607A)映射到PDO为例子进行笔记整理讲解。
①、节点预操作模式切换
在这一步中,需要先将该节点切换到预操作模式下。操作模式的切换均是由NMT进行管理的。
0x000 80 01
char data[8] = { 0 };
data[0] = 0x80;
data[1] = 0x01;
serve_motor_send_data(0x000, data);
//如果开启了设备心跳,会有类似的返回值:000 80 01
②、使PDO无效
使PDO无效,需要使用SDO发送数据。
//22 00 14 01 01 02 00 80
char data[8] = { 0 };
data[0] = 0x22;
//任意长度写入
data[1] = 0x1400 & 0xFF; //通信对象:0x1400
data[2] = 0x1400 >> 8 & 0xFF;
//通信对象:0x1400
data[3] = 0x01;
data[4] = (0x200 + 0x01) & 0xFF; //0x1400的COB-ID为0x200+节点ID
data[5] = (0x200 + 0x01) >> 8 & 0xFF;
//0x1400的COB-ID为0x200+节点ID
data[6] = 0x00;
data[7] = 0x80;
serve_motor_send_data(0x601, data);
③、清除PDO映射
清除PDO映射,也需在SDO发送数据。
//22 00 16 00 00 00 00 00
char data[8] = { 0 };
data[0] = 0x22;
//任意长度写入
data[1] = 0x1600 & 0xFF; //映射对象:0x1600
data[2] = 0x1600 >> 8 & 0xFF; //映射对象:0x1600
serve_motor_send_data(0x601, data);
④、写入PDO映射内容
写入PDO映射内容,也需在SDO发送数据。
//22 00 16 01 20 00 FF 60
char data[8] = { 0 };
data[0] = 0x22; //任意长度写入
data[1] = 0x1600 & 0xFF;
//映射对象:0x1600
data[2] = 0x1600 >> 8 & 0xFF; //映射对象:0x1600
data[3] = 0x01;
data[4] = 0x20;
//写入32位数据
data[5] = 0x00;
//子索引
data[6] = 0x607A & 0xFF;
//目标参数索引:目标地址0x607A
data[7] = 0x607A >> 8 & 0xFF; //目标参数索引:目标地址0x607A
serve_motor_send_data(0x601, data);
⑤、写入PDO映射对象个数
写入PDO映射对象个数,也需在SDO发送数据。
//22 00 16 00 01 00 00 00 写入1个参数
char data[8] = { 0 };
data[0] = 0x22;
//任意长度写入
data[1] = 0x1600 & 0xFF;
//映射对象:0x1600
data[2] = 0x1600 >> 8 & 0xFF;
//映射对象:0x1600
data[3] = 0x00;
data[4] = 0x01; //参数个数
serve_motor_send_data(0x601, data);
⑥、激活PDO
写入PDO映射对象个数,也需在SDO发送数据。
//22 00 14 01 01 02 00 00
char data[8] = { 0 };
data[0] = 0x22; //任意长度写入
data[1] = 0x1400 & 0xFF; //通信对象:0x1400
data[2] = 0x1400 >> 8 & 0xFF;
//通信对象:0x1400
data[3] = 0x01;
data[4] = (0x200 + 0x01) & 0xFF; //0x1400的COB-ID为0x200+节点ID
data[5] = (0x200 + 0x01) >> 8 & 0xFF; //0x1400的COB-ID为0x200+节点ID
data[6] = 0x00;
data[7] = 0x00;
serve_motor_send_data(0x601, data);
在上述步骤,全部正常发送和接收返回后,既完成了一套完整的PDO配置操作,如果需要一条PDO配置多个控制操作,进行适当的修改即可!