致远电子 CANopen 轻松入门CANopen技术指导手册Canopen通信协议前言CANopen无非就是在折腾11位ID和8个字节数据的定义明明很简单不知道为啥目前没有找到简单的入门教程害笔者刚学习时浪费不少时间。本文把废话都去掉让你最简单无痛学会CANopen。简单无痛学会Modbus可以看我公众号文章Modbus通信协议从入门到精通CANopen是什么从 OSI 的 7 层网络模型的角度来看CANController Area Network现场总线仅仅定义了第 1 层物理层见 ISO11898-2 标准、第 2 层数据链路层见 ISO11898-1 标准。我们进行CAN通信的时候设置好ID、8个字节数据然后写给CAN就发送了CAN底层是怎么发送数据的我们并不关心。如果是自己的两台设备进行CAN通信那么ID和8字节数据的内容可以自己约定比如ID1就是发送软件版本、ID2就是发送位置命令。当我们需要跟其他人的设备通信时就需要一套大家公认的协议这个协议就规定好了ID和8个字节的内容格式。CANopen就是公认的一种协议。COB-IDCANopen通信中有1个主节点其他全都是从节点。CANopen只使用了标准帧因此数据帧ID只有11位。在CANopen中数据帧ID称为COB-ID。COB-ID分为两部分高4位是功能码低7位是节点ID就是从机地址。节点ID范围是1~1270不允许使用最多127个设备。COB-ID值越小报文优先级越高。CANopen报文分类NMT 网络管理报文作用是管理网络切换节点的状态。一般由主站发送NMT网络管理报文。SDO 服务数据对象报文作用是设置设备参数或者是一些关键数据的传输。一般由主站发起SDO报文从站应答SDO报文。从站也可以发起SDO主站响应比如关键数据的传输。PDO 过程数据对象报文作用是传输一些设备的过程数据比如传输温度速度等等。主站和从站都会发送。EMCY 紧急报文作用是传输设备的故障信息。主站和从站都会发送。SYNC 同步报文作用是同步数据用来同步从站的TPDO数据。一般由主站发送。比如从站的TPDO传输类型是在同步模式下当从站收到设定次数的SYNC报文后从站会发送TPDO。这个在后续的文章中详细阐述。NODE GUARDING 节点保护报文作用是主站请求从站的状态主站询问从站应答。这种模式逐渐已被淘汰因为太占CAN总线网络带宽。HeartBeat 心跳报文作用是设备主动发送心跳表示自己在线。主站和从站都可以发送。CANopen的状态机CANopen主机通过发送NMT报文控制从机在不同状态间切换。预操作状态节点的CANopen通讯处于操作就绪状态此时此节点不能进行PDO通信而可以进行SDO进行参数配置和NMT网络管理的操作操作状态节点收到NMT主机发来的启动命令后CANopen通讯被激活PDO通信启动后按照对象字典里面规定的规则进行传输同样SDO也可以对节点进行数据传输和参数修改停止状态Stopped 节点收到NMT主机发来的停止命令后节点的PDO通信被停止但SDO和NMT网络管理依然可以对节点进行操作NMT 网络管理报文报文定义如下COB-ID固定为0x0000数据内容2个字节第一个字节代表状态值第二个字节代表从机地址。比如0x80 0x01代表让地址为1的从机进入预操作状态。NODE GUARDING 节点保护报文、HeartBeat 心跳报文主机周期发送节点保护报文询问从机状态报文的COB-ID0x700从机地址无数据。从机回复1个字节bit7为触发位第1次为0第2次为1第3次又为0交替01变化。低6位表示从机状态。节点保护报文已经很少使用因为要获取从机状态需要一问一答两帧数据。现在都使用心跳报文从机周期性主动上报自己的状态。心跳报文COB-ID0x700从机地址数据有1个字节指示从机状态。BOOT-UP启动报文从机发送给主机告知主机自己已经从初始状态进入预操作状态。报文的COB-ID0x700从机地址数据有1个字节值固定为0。EMCY 紧急报文当设备出现故障时触发报文COB-ID0x080从机地址数据有8个字节指示故障代码。SDO 服务数据对象报文主机通过SDO报文对从机进行参数配置比如PLC通过SDO修改伺服器的PID参数。SDO是主机发送给从机从机必须要回应数据给主机一发一收。主机发送给从机时COB-ID0x600从机地址。从机应答时COB-ID0x580从机地址。数据长度8个字节。读报文主机读操作时发送的报文第1个字节是命令字值固定为0x40。第2到4个字节是参数地址。最后4个字节是0。从机回应的报文第1个字节是命令字指示参数数据长度。第2到4个字节是参数地址。最后4个字节是参数值。从机中的参数地址在CANopen中称为对象字典比如下表伺服器实际位置参数的地址由16位的Index和8位的sub-index组成。Index0x6063sub-index0。CANopen采用的小端模式低字节在前。写报文主机写操作时发送的报文第1个字节是命令字指示参数数据长度。第2到4个字节是参数地址。最后4个字节是参数值。从机回应的报文第1个字节是命令字指示是否写成功。第2到4个字节是参数地址。最后4个字节不关心。伺服器目标位置参数Index0x607Asub-index0。通信失败通信失败时从机回复的第1个字节值为0x80。最后4个字节是错误代码比如0602 0000代码表示参数不存在。PDO 过程数据对象报文PDO不需要回应类似UDP单向通信效率更高。PDO分为RXPDO接收PDO、TXPDO发送PDO 接收还是发送是相对于从机来说的。PDO的COB-ID中包含了接收方地址从机或主机根据COB-ID来判断接收的PDO是否是发送给自己。PDO报文的具体内容需要主机通过SDO报文来配置。PLC编程的时候把一条PDO定义好上电后与从机SDO通信时把PDO报文的定义发给从机。上面就定义了一条TXPDO、一条RXPDO。PDO传输类型分为同步和异步。同步就是此PDO报文需要配合同步报文来执行比如主机给每个从机发一个目标位置最后群发一条同步报文各从机接收到后才动作这样可以达到同时运动的目的。主机根据PDO的定义来装配PDO的数据内容。60630020表示Index0x6063sub-index0长度0x20 bit。60410010表示Index0x6041sub-index0长度0x10 bit。因此此报文前4个字节参数Index0x6063sub-index0。后面2个字节参数Index0x6041sub-index0。当开机预操作状态时主机通过SDO把上面的配置发给从机后进入操作状态进行PDO通信时从机接收到COB-ID0x181的帧就知道帧的前4个字节是参数Index0x6063/sub-index0的数据后面2个字节是参数Index0x6063/sub-index0的数据。RXPDO报文同理。事件时间就是定时周期通过设置此时间该PDO可以周期性自动发送。PDO传输类型分为同步和异步。同步就是通过SYNC同步报文来实现主从机同步同步又分为非周期性和周期性。非周期性由特定事件触发发送。周期性由多少个同步报文后触发发送。常用的传输类型有同步循环1-240、异步254、异步255。如果使用同步循环主机会周期性发送同步报文从机接收到多少个同步报文后就发送PDO报文。比如值为1代表从机接收到1个同步报文就发送。值为2就代表接收到2个同步报文才发送。异步254和异步255是最常用的普通的报文一般在数据修改后发送。SYNC 同步报文同步报文用于辅助PDO报文同步报文COB-ID0x08没有数据。配合传输类型为同步循环1-240的PDO报文。同步报文有两个相关的时间参数通讯循环周期同步报文发送周期比如值为4ms表示每隔4ms就发送一次。同步窗口时间从机收到主机发的同步报文后需要在此时间内发送PDO否则超出此时间主机会丢弃收到的PDO。此时间小于通讯循环周期。对象字典前面说了参数地址在CANopen中称为对象字典。参数地址有公认的规定不能随意用。通讯对象子协议区通讯对象子协议区Communication profile area定义了所有和通信有关的对象参数。标绿色底纹的索引范围 1000h to 1029h为通用通讯对象所有 CANopen 节点都必须具备这些索引否则将无法加入 CANopen 网络。其他索引根据实际情况进行分配与定义。通用通讯对象由于通用通讯对象十分重要NMT 主站CANopen 主站在启动时通常都全部或者部分读取所有从站中通用通讯对象中的索引所以所有的通用通讯对象都必须在CANopen 从站中实现使用者也必须熟知这些索引地址与其含义。制造商特定子协议对象字典索引 2000h to 5FFFh为制造商特定子协议通常是存放所应用子协议的应用数据。而上文所描述的通讯对象子协议区Communication profile area是存放这些应用数据的通信参数。比如广州致远电子的 XGate-COP10 从站模块规定了RPDO 的通讯参数存放在 1400h to 15FFh 映射参数存放在 1600h to 17FFh 数据存放为2000h 之后厂商自定义区TPDO 的通讯参数存放在 1800h to 19FFh 映射参数存放在 1A00h to 1BFFh 数据存放为2000h 之后厂商自定义区。对于在设备子协议中未定义的特殊功能制造商也可以在此区域根据需求定义对象字典对象。因此这个区域对于不同的厂商来说相同的对象字典项其定义不一定相同。标准化设备子协议标准化设备子协议为各种行业不同类型的标准设备定义对象字典中的对象。目前已有十几种为不同类型的设备定义的子协议例如 DS401、DS402、DS406 等其索引值范围为 0x60000x9FFF。同样这个区域对于不同的标准化设备子协议来说相同的对象字典项其定义不一定相同。总结正如前面所说对象字典中有些参数区域是公认的有些参数区域是厂商自定义的。比如伺服器这个品类一般对象字典分成三个部分分别为 CIA301 定义的 1000h~1FFFh 寄存器、厂家自定义的2000h~2FFFh 寄存器和 CIA402 定义的 6000h~6FFFh 寄存器。CIA301 和CIA402 是通用的协议参数都是定死的。2000h~2FFFh范围才是厂家可以自由发挥的部分。对象字典和 EDS 文件实例对于对象字典和 EDS 文件的实现需要使用专用的 EDS 生成工具并且能通过 CiA 的EDS 测试工具进行一致性测试。我们可以通过广州致远电子的CANopen从站协议栈模块XGate-COP10模块的对象字典和 EDS 文件来真实感受一下。如图为 XGate-COP10 的 EDS 文件导入到 USBCAN-E-P 主站卡管理软件CANManager for CANopen 中。配置从站框中可以观察到 XGate-COP10 的对象字典内容1008h的索引是这个设备的名称 XGate-COP101009h是硬件版本100Ah是软件版本1018h的索引为标示对象其下有若干个子索引其中 1008.01h 的子索引为厂商代码 0x2B6这是广州致远电子股份有限公司在 CiA 协会申请的厂商代码任何一个生产 CANopen 的厂家虽然不强制加入 CiA 协会但必须申请唯一的厂商代码。对象字典导出后就是所谓的 EDS 文件用于随着产品组态时使用。PDO的通信参数、映射参数上面讲了PDO报文的具体内容需要主机通过SDO报文来配置。PDO报文的属性、数据内容定义也是保存在对象字典中的。这样主机、从机随时读这里的数据就能知道PDO报文的格式。PDO的通信参数PDO 通信参数定义了该设备所使用的 COB-ID、传输类型、定时周期等。RPDO 通讯参数位于对象字典索引的 1400h to 15FFhTPDO 通讯参数位于对象字典索引的 1800h to 19FFh。每条索引代表一个 PDO 的通信参数集其中的子索引分别指向具体的各种参数。Number of entries 参数条目数量即本索引中有几条参数COB-ID即这个 PDO 发出或者接收的对应 CAN 帧 ID发送类型即这个 PDO 发送或者接收的传输形式通常使用循环同步和异步制造商特定事件较多Inhibit time 生产禁止约束时间(1/10ms)约束 PDO 发送的最小间隔避免导致总线负载剧烈增加比如数字量输入过快导致状态改变发送的 TPDO 频繁发送总线负载加大所以需要一个约束时间来进行“滤波”这个时间单位为 0.1msEvent timer 事件定时器触发的时间(单位 ms)定时发送的 PDO它的定时时间如果这个时间为 0则这个 PDO 为事件改变发送。SYNC start value 同步起始值同步传输的 PDO收到诺干个同步包后才进行发送这个同步起始值就是同步包数量。比如设置为 2即收到 2 个同步包后才进行发送。汇川伺服器PDOCOB-ID 位于通信参数 (RPDO1400h~1403hTPDO: 1800h~1803h) 的子索引 01 上最高位决定该 PDO是否有效。举例对于站号为 4 的节点TPDO3 在无效状态下其 COB-ID 应该为“80000384h”而对该 COB-ID 写入“384h”时表明激活该 PDO。通信参数 (RPDO1400h~1403hTPDO: 1800h~1803h) 子索引 02 不同的数值代表不同的传输类型定义了触发 TPDO 传输或处理收到的 RPDO 的方法具体对应关系如下表所示。当 TPDO 的传输类型为 0 时如果映射数据发生改变且接收到一个同步帧则发送该 TPDO当 TPDO 的传输类型为 1~240 时接收到相应个数的同步帧时发送该 TPDO。当 TPDO 的传输类型是 254 或 255 时映射数据发生改变或者事件计时器到达则发送该 TPDO。当 RPDO 的传输类型为 0~240 时只要接收到一个同步帧则将该 RPDO 最新的数据更新到应用当RPDO 的传输类型为 254 或者 255 时将接收到的数据直接更新到应用。针对 TPDO 设置了禁止时间存放在通信参数 (1800h~1803h) 的子索引 03 上防止 CAN 网络被优先级较低的 PDO 持续占有。该参数的单位是 100us设置数值后同一个 TPDO 传输间隔减不得小于该参数对应的时间。举例TPDO2 的禁止时间为 300则 TPDO 的传输间隔不会小于 30ms。针对异步传输 ( 传输类型为 254 或 255) 的 TPDO定义事件计时器位于通信参数 (1800h~1803h) 的子索引05 上。事件计时器也可以看做是一种触发事件它也会触发相应的 TPDO 传输。如果在计时器运行周期内出现了数据改变等其它事件TPDO 也会触发且事件计数器会被立即复位。PDO的映射参数上面只是定义了报文的参数比如条目数量、ID等还没有定义报文数据内容。RPDO报文的参数定义保存在对象字典1400h to 15FFh数据内容定义保存在1600h to 17FFh。地址区域都是1FFh刚好一一对应。TPDO报文的参数定义保存在对象字典1800h to 19FFh数据内容定义保存在1A00h to 1BFFh。比如我要定义一条TPDO 报文此报文的COB-ID值保存在Index0x1800/sub-index0x01的对象字典中。此报文的发送类型保存在sub-index0x02。此报文的生产禁止约束时间保存在sub-index0x03。此报文的数据内容包含多少个参数保存在sub-index0x00。我们设置Index0x1800/sub-index0x00的值为3即此报文包含3个参数。然后我们在Index0x1A00/sub-index0x01去定义第1个数据内容。在sub-index0x02去定义第2个数据。sub-index0x03去定义第3个数据。如上我们把值填进去就定义好一条TPDO 报文了。开机的时候主机和从机通过SDO通信会把Index0x1800、Index0x1A00等地址的参数同步这样主从机就都知道这条TPDO 报文的属性了后续发此条报文就不会鸡同鸭讲了。上面的表Index0x1A00/sub-index0x01值是20000108代表该TPDO报文的第一个数据内容是1个字节值从0x2000/sub-index0x01处获取。当从机发此条TPDO报文时报文COB-ID0x181。数据有4个字节第1个字节数据是Index0x2000/sub-index0x01参数的值。第2到3个字节数据是Index0x2003/sub-index0x03参数的值。第4个字节数据是Index0x2003/sub-index0x01参数的值。然后我们来看对象字典Index0x2003的值因此要发送一条TPDO报文需要去1800h获取报文的COB-ID等参数去1A00h获取报文的数据域定义最后去2000h获取到真正的数据。也就是RPDO 通讯参数 1400h to 15FFh映射参数 1600h to 17FFh数据存放为 2000h 之后厂商自定义区域TPDO 通讯参数 1800h to 19FFh映射参数 1A00h to 1BFFh数据存放为 2000h 之后厂商自定义区域。SDO分包报文当需要传输的值超过 32 位时就不能使用4字节的快速 SDO 传输。必须使用普通 SDO 进行分帧传输。在应用中较少用到一般用于 CANopen 节点的程序固件升级或者做网关转换MVB 总线之类数据最大可达 256 位的应用。前面介绍的SDO报文又称为快速SDO因为只有一问一答但是只能传输32位数据。如果超过就需要分包了。分包SDO的CAN帧ID与快速SDO相同依然发送方客户端发送的报文CAN-ID为 600hNode-ID接收方服务器成功接收后回应 CAN-ID 为 580hNode-ID 的报文。比如下载协议 download protocol上传协议 upload protocol 时间戳报文主机发送自身的时钟为网络各个节点提供公共的时间参考即网络对时。这在故障诊断中非常需要比如列车中火灾报警检修人员需要准确获知报警的时刻然后关联查看其它设备在这个时刻的工作状态。时间戳协议采用广播方式无需节点应答CAN-ID 为 100h数据长度为 6数据为当前时刻与 1984 年 1 月 1 日 0 时的时间差。节点将此时间存储在对象字典 1012h的索引中。心跳心跳模式采用的是生产者——消费者模型。CANopen设备可根据生产者心跳间隔对象1017h设置的周期来发送心跳报文单位为ms。网络中具有消费者心跳功能的节点根据对象1016h设置的消费者时间监视该生产者一旦在消费者心跳时间范围内未接收到相应节点的生产者心跳则认为该节点出现故障。配置生产者心跳时间间隔1017h后节点心跳功能激活开始产生心跳报文。配置消费者心跳1016h的有效子索引后接收到相应节点发出的一顿心跳即开始监视。主机按其生产者时间发送心跳报文监视主机的从机在1016h子索引时间内未接收到心跳报文则认为主机掉站。1016h某子索引时间≥主机生产者时间×1.8否则易误报从机认为主机掉站。从机每隔1017h时间发送心跳报文监视从机的主机或其他从机在消费者时间内未接收到心跳报文则认为该从机掉站。1017h×1.8≤监控该从机的主机或其他从机的消费者时间否则易误报从机掉站。IS620P伺服驱动器既是心跳生产者也是心跳消费者最多可以同时作为5个不同节点的心跳消费者。建议心跳生产者的时间不要低于20ms而消费者心跳时间不要低于40ms且为相应生产者心跳时间的1.8倍以上。给IS620P伺服器配置1017h的值后伺服器开始输出心跳报文。IS620P伺服器具有监视功能可以监视5个节点的心跳。需要配置被监视的节点地址、监视超时时间。COB-ID总表CiA301和CiA402CiA 301 是 CANopen 现场总线的核心通信与应用层协议CiA 402 是基于 CiA 301、专门用于运动控制设备伺服 / 步进 / 变频器的设备行规。CiA 301 定规矩怎么说话CiA 402 定动作怎么运动。开发伺服系统时先用 CiA 301 建立通信再用 CiA 402 控制电机。比如下面就是CiA 402中定义的常用对象字典0x6060/0x00是设置工作模式具体怎么定义的就可以查阅CiA 402协议手册可以知道模式有1 PP Profile Position 轮廓位置 3 PV Profile Velocity 轮廓速度 4 TQ Torque 转矩 6 HOM Homing 回零 8 CSP Cyclic Sync Pos 同步位置 9 CSS Cyclic Sync Vel 同步速度 10 CST Cyclic Sync Torque 同步转矩应用实例配置驱动器为速度模式,并通过PDO传输速度,让电机转动CanFestivalcanopen的实现有很多种方法,canfestival是一个较为全面的canopen开源协议.用c语言编写,适合嵌入式的应用.canfestival最主要的思想有两个.一个是字典思想,PDO,SDO,SYNC的一些设置,都会存入到字典中.另一个是软件定时器思想,程序中各种动作,都是由软件定时触发,在主函数中可以是一个空循环.如,循环发送PDO,canfestival会帮我们创建一个周期性的定时器.canfestival配置好字典,然后主函数中切换can总线的状态,进入主while就可以了.通信部分,是canfestival自动执行的.它把通信部分和应用部分隔离开来.这里并不是像串口等其他的函数一样,调用一次,就会发送一次.之所以没有这样做.可能作者是为了稳定性的考虑.(如果愿意,也可以直接调用底层去发送canopen的报文)