项目简介
本项目是一个基于C++14编写的CANopen从站库,依据官方的CIA 301 CANopen应用层和通信配置文件文档开发。该库能够根据设备的EDS文件自动生成对象字典的头文件,并且支持对象字典的非易失性存储,拥有多种CANopen协议相关功能。
项目的主要特性和功能
- 对象字典生成:可依据设备的EDS文件自动生成对象字典头文件,对象字典为静态分配,其大小在编译时即可确定。
- 存储功能:支持对象字典的非易失性存储。
- 网络管理:包含可由主站或应用程序控制的NMT从站。
- 服务数据对象:具备支持常规和块事务的SDO服务器。
- 过程数据对象:支持传输和接收PDO,支持动态PDO映射和RTR。
- 心跳和同步:有心跳生产者和触发TPDO传输的同步消费者。
- 错误处理:支持带管理错误寄存器和预定义错误字段的紧急生产者。
安装使用步骤
生成对象字典头文件
在编译前,需使用Python脚本生成对象字典头文件,步骤如下:
1. 安装依赖包:进入/generator
文件夹,执行pip3 -r requirements.txt
。
2. 运行脚本:执行python3 generator.py example.eds 1
,其中example.eds
是EDS文件路径,1
是节点ID。脚本会进行基本验证,成功后会创建od.hpp
文件。
实现硬件接口
本库与设备无关,用户需实现库与设备的接口,编写以下类方法的函数定义:
- Node::sendFrame
:向CAN网络发送帧。
- Node::getTime_us
:用于内部计时。
- ObjectDictionnary::saveData
:将对象字典数据保存到非易失性存储器。
- ObjectDictionnary::loadData
:从非易失性存储器加载对象字典数据。
- ObjectDictionnary::restoreData
:将对象字典数据重置为默认值。
使用库
库的使用通过Node
对象完成,使用时需注意:
1. 每个程序建议只使用一个Node
对象。
2. 库无内置并发保护,需用户自行处理。
3. 节点必须在循环中更新,同时能异步接收消息。
示例代码
以下是一些使用示例: ```cpp // 获取和更改NMT状态 if (node.nmt().getState() == NMTState_PreOperational) { node.nmt().setTransition(NMTServiceCommand_Start); cout << "Entered operationnal state" << endl; }
// 订阅RPDO事件 node.pdo().onTimeout( { cout << "Timeout occured on RPDO" << index << endl; }); node.pdo().onReceive( { cout << "Received RPDO" << index << endl; });
// 发送TPDO node.od()[OD_OBJECT_6048]->setValue(0, (float)49.3); node.od()[OD_OBJECT_6048]->setValue(1, (float)420.42); node.pdo().transmitTPDO(0);
// 发送紧急消息 if(voltage < MIN_VOLTAGE) { node.emcy().raiseError(EMCYErrorCode_Voltage); throw "Error: Voltage too low!"; }
// 清除错误 node.emcy().clearErrorBit(ErrorRegisterBit_Voltage); node.emcy().clearErrorBit(ErrorRegisterBit_Generic); if(node.emcy().getErrorRegister() == 0) { cout << "All errors cleared, clearing history" << endl; node.emcy().clearHistory(); }
// 访问对象字典数据 float value; Object *obj = node.od()[OD_OBJECT_6048]; if (!obj->getValue(0, &value)) throw "Error: Could not read value from entry. Invalid size?"; cout << "Value: " << value << endl; if (!obj->setValue(0, (float)64.23)) throw "Error: Could not write value to entry. Invalid size?"; ```
添加对象
若需添加特殊对象,需按以下步骤操作:
1. 创建Python类:在generator/objects
文件夹中创建新的Python类,继承VarObject
、ArrayObject
或RecordObject
类。
2. 修改generator.py
文件:导入新类,并在toCANopenObject
函数中添加相应条件。
3. 创建C++类:在src/objects
文件夹中创建object_XXXX.hpp
和object_XXXX.cpp
文件,继承Object
类。
4. 包含头文件:在src/od_include.hpp
文件中包含新创建的头文件。
下载地址
点击下载 【提取码: 4003】【解压密码: www.makuang.net】