CANopen是一种基于CAN(Controller Area Network)总线的高层通信协议,主要用于嵌入式系统中的设备之间的通信。它定义了一系列的标准通信对象和通信服务,使得不同厂商的设备可以相互通信和交换数据。
CANopen 通信的基本原理
-
通信对象:
- PDO (Process Data Object):用于实时数据传输,通常用于控制和状态信息的快速交换。
- SDO (Service Data Object):用于非实时数据传输,通常用于配置和参数的读写。
- NMT (Network Management):用于网络管理,例如启动、停止和复位节点。
- EMCY (Emergency):用于紧急消息的传输,报告错误和异常情况。
-
通信过程:
- 节点ID:每个设备(节点)在网络中都有一个唯一的标识符(Node ID)。
- CAN ID:CAN帧的标识符,用于区分不同的通信对象和消息类型。
- 数据帧:CAN帧包含标识符、数据长度码(DLC)和数据字节。
代码分析
例如:dealCanFrame
函数处理接收到的CAN帧,具体步骤如下:
-
获取索引:
std::uint16_t index = ((frm->data[2] << 8) | frm->data[1]);
这行代码将CAN帧中的第2和第1字节组合成一个16位的索引值。
-
计算节点ID:
auto node_id = frm->can_id - 0x580;
这行代码通过减去0x580来计算节点ID,0x580是CAN总线ID,用于接收命令字,修改参数时接收SDO报文。
-
更新时间:
if (node_id == (canid_t)m_node_id_ud) m_last_time = chrono::steady_clock::now(); else m_last_time_ro = chrono::steady_clock::now();
根据节点ID更新相应的时间戳。
示例代码中的CANopen通信
- CAN ID:
frm->can_id
是接收到的CAN帧的标识符。 - 数据字节:
frm->data
是CAN帧的数据部分。 - 索引:通过组合数据字节来获取索引值,用于进一步处理。
总结
CANopen通信通过定义不同的通信对象和通信服务,实现了设备之间的数据交换和控制。在你的代码中,通过解析CAN帧的标识符和数据字节,可以获取节点ID和索引值,从而进行相应的处理和操作。