阜沙网站建设,便宜网站建设公司,叫别人做网站安全吗,高邑做网站本文的重点是对CANopen协议的理解#xff0c;不是编程实现 参考链接
canopen快速入门 1cia301协议介绍_哔哩哔哩_bilibili
CANopen是什么#xff1f; CANopen通讯基础#xff08;上#xff09;_哔哩哔哩_bilibili
CANopen概述 图1. CAN报文标准帧的格式
CAN的报文可简单… 本文的重点是对CANopen协议的理解不是编程实现 参考链接
canopen快速入门 1cia301协议介绍_哔哩哔哩_bilibili
CANopen是什么 CANopen通讯基础上_哔哩哔哩_bilibili
CANopen概述 图1. CAN报文标准帧的格式
CAN的报文可简单的被分为帧ID和数据部分由于其灵活性在CAN通讯刚出来时各个厂家一般根据自己的喜好进行编写协议这最终导致了很混乱的局面。因此诞生CANopen协议CANopen是由CIA组织提出的CAN的应用层协议包含CIA301、CIA401、CIA402…其中CIA301是CANopen中最基础的协议规定基于帧ID和报文的分类用法相当于定义了一个CAN报文框架。CIA401、CIA402…则是基于CIA301基础协议针对不同类型的通讯器件所制定的更具体的协议比如CIA402就是驱动器协议全球通用很多驱动器厂商都会支持CIA402这种协议。
注意CAN通信有标准帧和扩展帧的区别本文仅考虑标准帧的情况。
CIA301基于帧ID的功能划分
CAN报文主要分为帧ID和数据两部分CIA301协议对ID部分进行了划分把从低到高的各个ID划分成了不同区域每个区域实现不同功能根据ID的不同决定CAN报文的类型每种类型有不同的格式所以后面的数据会根据格式进行拆解。 图2. CIA301协议基于帧ID的功能划分
在CANopen协议中定义了一个概念通讯标识符 Communication Object Indentifier后续简写为COB_IDCOB_ID是CAN报文的唯一标识符COB_ID本质上就是CAN报文中的帧ID。根据图1可知标准帧的帧ID共有11位也就是COB_ID有11位。CANopen协议将COB_ID分成了功能码FUNCTION和NodeID两个部分。其中功能码占4位NodeID占7位如图3所示图2的第2列的功能码ID位搞错了应该是bits10~7 图3. COB_ID格式
功能码的作用就是字面意思不同的码值代表不同的功能而NodeID代表的是CAN网络中的各个网络节点的编号范围是1~127。这个NodeID号是设备自己定义的比如我是一个驱动器我可以给我自己定一个NodeID号比如1。甚至我可以提供上位机的配置接口去配置我的NodeID号。根据我的理解同一个CAN网络中所有设备NodeID号应不要重复。比如我是主控平台Master我要通过CAN网络分别去控制三个轴系的电机驱动器。那么这三个电机驱动器的NodeID不能一样否则主控平台根据NodeID发送的指令不知道最终发给了谁。NodeID是用来辨识从设备的。
下面根据功能码以从小到大的顺序对CANopen的报文做一个分类。 图4. 基于功能码的CANopen报文分类
基于图4的内容CANopen协议主要需要学习的报文为下表中的8种。 序号 报文分类 COD_ID 学习难度 简单 正常 地狱 是否重点学习 1 NMT 000H 简单 ☆ 2 SYNC 080H 正常 ☆ 3 EMCY 080HNodeID 简单 - 4 PDO 从节点发送 TxPDO1~TxPDO4 180HNodeID 280HNodeID 380HNodeID 480HNodeID 从节点接收 RxPDO1~RxPDO4 200HNodeID 300HNodeID 400HNodeID 500HNodeID 地狱 ☆ 5 SDO 主节点发送 600HNodeID 主接点接收 580HNodeID 正常 ☆ 6 节点保护报文 700HNodeID 简单 有的资料也把这3种节点状态监控相关的报文统一在NMT这类报文中本文也会 7 心跳报文 700HNodeID 简单 8 Boot-UP启动报文 700HNodeID 简单 CANopen协议报文详解 图5. CANopen协议报文的基本格式
图5是CANopen协议报文的基本格式主要包含COB_ID和最多8个字节的数据部分。下面根据前文的分类对每一种报文进行详解。 在CAN网络中存在主节点和从节点之分。在本文中我们以单片机通过CAN连接驱动器控制电机为例。单片机为主节点驱动器为从节点。
0 OD对象字典
在正式介绍CANopen协议报文之前我们需要了解一个CANopen中用到的极其重要的一个概念不得不吐槽网上很多资料对此部分不够重视。Object Dictionary对象字典本质上就是一个表格表格里面的内容都有其独特的含义和作用。在CANopen编程中我们大部分的时间都是在编写配置这个对象字典来达到我们的目的。
以单片机通过CANopen和驱动器通信来控制电机为例单片机是CAN网络的主节点它有它的对象字典。驱动器是CAN网络的从节点它也有它的对象字典。这两个对象字典都是需要编写配置的。
单片机的对象字典一般是使用开源的对象字典工具软件objdictedit生成我们需要学习该软件的使用同时还须学习移植CanFestival开源库到单片机CanFestival和objdictedit要配合起来使用。驱动器的对象字典一般驱动器厂商会默认配置好。然后局部的内容可以通过单片机通过SDO通信进行配置 或者 使用驱动器的上位机进行配置。
如果我们要读/写表格里面的内容是不是需要知道它在表格的第几行第几列啊。 对象字典里面是用索引index和子索引sub-index来唯一确定这个表格每个数据的地址的。 有时候你还会发现对象字典里面某个索引/子索引对应的数据竟然存放的是另外一个数据的索引/子索引。用C语言的话来说它存的是指针那存这个指针数据它本身的索引/子索引是什么指针的指针。指针、地址、索引/子索引含义是一样的。怎么说有没有被我成功的绕进去。 但对于对象字典的理解本就是这么绕的提前做好心理准备。 图6. 对象字典举例
图6所示是一个对象字典的局部内容。这里面有索引/子索引有名称有含义还有位宽和读写属性。这里所展示的对象字典的局部其实是CIA402协议里面所规定的内容也就是说所有使用CANopen协议的驱动器它的对象字典里面都是这样定义的。 图7. CANopen对象字典通用结构
图7所示为CANopen对象字典的通用结构其中特别填充的部分是我们用的最多的。
1000h-1FFFh这个索引段是用来配置通讯的。6000h-9FFFh这个索引段是标准设备字协议区。解释一下比如CIA401、CIA402…这些协议都是针对的是不同类型的设备。CIA402是针对驱动器设备的CIA406是针对编码器设备的。 什么叫做标准设备子协议区这个标准说明是意思就是固定。前面对图6的解释也讲过所有支持CIA402的驱动器的对象字典索引为6040h、6060 h、607A h都固定是这个含义。2000h-5FFFh这个索引段是制造商特定子协议区 从两个层面去理解 如果我是一个驱动器从节点这里面的内容由我驱动器的厂商自己去定义什么意思自己去定义怎么用。我们在做单片机开发的时候基本上不用管驱动器这部分的协议。如果我是一个单片机主节点这里面的内容也是由我单片机自己去定义。
这么说可能有点抽象比如我在配置PDO的时候我可以配置2000h-5FFFh这里面的某个地址里面存储的内容是目标速度。然后在配置PDO通讯参数的时候我把这个地址放在通讯参数里面这里就是刚刚提到的指针的指针了PDO后配置好之后就不用管了往从机发PDO的时候CANopen就会自动找到这个地址来把目标速度发送给驱动器。同时呢我单片机的主程序只需要修改这个地址里面的数据就可以就等价于修改了目标速度。 这部分内容会在后文中进一步详细讲如果没有理解透通读一遍全文后再来读这里。
1 NMT网络管理报文
在开始正式介绍NMT网络管理报文之前需要先介绍一个概念CANopen协议的状态机。 图8. CANopen协议的状态机
如图8所示CAN网络中的每一个从设备都有会有一个状态在不同状态下可以执行不同的操作有些操作比如e就只能在Operational这个状态才能执行。 下面我们来看abcdef分别代表什么。 a NMT 网络管理 b Node Guard 节点保护 c SDO 服务数据报文 d Emergency 紧急报文 e PDO 过程数据报文 f Boot-up 启动报文
另外图8中有1234566种状态转移
1: Start Remote node (0x01)
2:Stop Remote Node (0x02)
3:Enter Pre-Operational State (0x80)
4:Reset Node(0x81)
5:Reset Communication (0x82)
6:Boot up
1.1 NMT状态转移报文 [ COB_ID: 000H ]
其中1~5的NMT报文只能从主节点单片机发送所有从节点驱动器必须支持 NMT 服务。NMT报文不需要应答。NMT 报文格式如下: 图9 .NMT报文格式
其中CS是命令字不同命令字代表不同的含义Node-ID表示从节点的ID。 当Node-ID 0时则代表该指令是针对所有的从节点。 如果Node-ID≠0则该命令仅针对该Node-ID。CS的取值及含义如下 图10. NMT报文CS命令字的含义
1.2 NMT BOOT-UP报文 [ COB_ID: 700H NodeID ]
图8中的“6”状态转移是Boot-UP 是由从节点驱动发布Boot-UP报文通知主节点单片机它已经从initialising状态进入pre-operational状态。 图11. NMT Boot-UP报文
这个报文我们只需要做个了解在实际编程的过程中应该用不到。
1.3 NMT节点保护报文 [ COB_ID: 700H NodeID ]
NMT节点保护报文的机制是主节点单片机可以监视每个从节点驱动器的当前状态。主节点周期性的发送报文去询问从节点的状态从节点收到主节点的问询后将自己的状态回复给主节点在设定的时间内如果主节点没有收到从节点的信息或信息错误都会判断从节点通讯故障。下面给出主节点的询问报文和从节点的回复报文。 图12. NMT 节点保护报文
从图12中我们可以看出主节点的询问报文只有COB_ID没有数据 而从节点的回复报文是有一个字节的数据的。该字节又分成了Bit7 和 Bits6-0两个部分。 Bit7为触发位在每次节点保护应答中交替“0”和“1”在第一次节点保护时置0。下面给出Bit0 - Bit6状态表 图13. 节点保护报文从节点回复报文Bit0-Bit6的状态表
图13中有两个标记第一个0x0被划掉了因为这个状态0x0不会在NMT节点保护报文中出现从节点一般是自己初始化后发送Boot-UP报文到主节点它自己呢就会进入Pre-operational状态。 而不是我们通过NMT节点保护报文去询问得到。 第二个红色方框框住的是扩展帧才有的状态我们不必去关注。 最后只剩下0x4 0x5 0x7F即 Stoped / Operational / Pre-operational三个状态是我们需要关注的。 不过节点保护报文是一问一答效率不高下面介绍心跳报文。
1.4 NMT心跳报文 [ COB_ID: 700H NodeID ]
从节点还可被配置为产生周期性的被称作心跳报文(Heartbeat)的报文从节点周期将该报文为发送给主节点主节点可以通过报文中的状态值得知从节点的状态。 图14. 心跳报文的格式
其状态如下与NMT节点保护报文是一样的。 图15. 心跳报文的状态表
简单说就是主节点你不用发询问报文了我从节点直接周期性的发送状态过来显然心跳报文的效率更高但从节点应该需要做一个配置在后文中我们会讲SDO通信SDO通信主要就是用来配置从节点的。
2 SYNC同步报文 [ COB_ID: 080H ]
根据我的理解 SYNC同步报文应该是由主节点单片机发给从节点驱动器的是广播式的所有从节点都能收到同步报文且不需要应答。SYNC是由主节点周期性地发送每发送一个SYNC相当于一拍所以可以实现整个从节点网络一拍一拍的进行同步各个从节点的时钟。 图16. SYNC同步报文
如图16所示同步报文只有个COB_ID没有数据。
那么主节点单片机的同步报文是以什么样的周期发送给从节点驱动器呢 这个就需要对主节点单片机的对象字典进行配置了。
对象字典中有三个和同步报文相关的索引1005H、1006H、1007H
1005H索引规定了SYNC报文的COB-ID这个一般不需要更改。1006H索引规定了同步帧的循环周期注意单位是us1007H索引规定了约束了同步帧发送后从节点发送PDO的时效即在这个时间窗口内发送的PDO才有效超过时间的PDO将被丢弃。注意单位也是us
3 EMCY紧急报文 [ COB_ID: 080H NodeID ]
紧急报文一般来讲也是CAN网络中从节点发给主节点的比如从节点中驱动器有编码器当这些设备内部出现的致命错误的时候就会触发紧急报文的发送以最高优先级发送到主节点。适用于中断类型的错误报警信号。一个紧急报文包含8个字节报文格式如下 图17.EMCY紧急报文格式
紧急报文和同步报文的功能码都是080H但是他们的区别是很多的很容易区分。
同步报文一般是主节点发给从节点的紧急报文是从设备发给主节点的。同步报文没有NodeID而紧急报文有NodeID这个NodeID可以指示是哪一个从设备发生了故障。同步报文是不带数据的但是紧急报文是带8个字节的数据的8个字节拉满。其目的是通过这8个字节的信息让主节点能够分析出从设备到底发生了什么故障。
如图17所示紧急报文的8个字节数据被分为了3个部分
第一个部分包含两个字节Byte0-1表示应急错误代码。错误代码表格如下图所示。 图18.EMCY紧急报文的错误代码及含义
图18所示的错误代码及含义应该是由CANopen的基础协议CIA301所定义也就是是固定不变的。 另外错误代码中“XX”部分是由相应的标准设备子协议规定。 什么意思呢 就是如果我是一个驱动器那么“XX”部分是由CANopen中的CIA402协议去规定。如果我是个编码器呢那么“XX”部分是由CANopen中的CIA406协议去规定。总的来说呢就是这个错误代码及含义是固定不变的通过查询CIA301和CIA402/CIA406/其他设备子协议就可以查到错误代码的含义。
第二个部分包含1字节Byte2表示错误寄存器的数据。前面我们提到了OD对象字典。也提到过无论是主节点单片机还是从节点驱动器/编码器/其他类型的设备都有一个属于它们自己的对象字典。 那么在CIA301协议中我们规定索引1001H就是错误寄存器位宽为8位。 假设我们CAN网络中有个驱动器出问题了 那么驱动器它本身如果驱动器它自己实现了错误寄存器这部分协议的话有些驱动器不会实现完整的协议的它会自己判断到底是什么错误然后呢把这个错误信息写到它自己的对象字典的1001H索引里面。随后发送EMCY紧急报文到CAN网络中并且紧急报文中的第3个字节Byte2就会自动去拷贝对象字典里面索引为1001H里面的数据。当我们主节点收到这个报文的时候就可以做更细致的错误分析。如下图所示为错误寄存器1001H的8个位的数据每一位的含义。 图19.EMCY紧急报文的错误寄存器每个位的含义
第三个部分共5个字节Byte3-7制造商特定的错误区域这部分就不是标准的CIA301和CIA402/CIA406/其他设备子协议所规定的内容啦。 所以假设有两个驱动器的制造商那么这两个驱动器的制造商在Byte3-7的定义很大概率是不同的。这部分内容有驱动器制造商自己去定义错误区域的含义。这部分的定义呢应该出现在该驱动器的规格书里面以便于用户去查询/定位错误的具体信息。
在以下这个参考链接中有一个EMCY紧急报文的举例说明可以看看。
canopen快速入门10emcy_哔哩哔哩_bilibili
4 SDO服务数据报文 [COB_ID: 580HNodeID (RxSDO) | 600HNodeID (TxSDO)]
原本想着根据COB_ID的大小以从小到大的顺序来安排本文的内容然而我还是发现SDO的内容还是放在PDO的内容之前好一些PDO更难理解是一方面另外对于PDO通讯参数和映射参数的配置是需要使用SDO这部分内容的前置知识的所以我们先讲SDO再讲PDO。
如标题所示SDO报文有两种COB_ID一个发送一个接收。 SDO通讯是一种一问一答的方式一般是由主节点发起一个对从节点的对象字典的某个索引/子索引的读或写的操作然后从节点反馈主节点你的写操作是否成功或你要读的数据。这个RxSDO和TxSDO是我本人为了便于理解自己提的说法都是针对主节点而言。
我们来看SDO的COB_ID具体的定义规则 图20. SDO COB_ID的具体定义 图20的SDO COB_ID具体定义这里就不细讲了一目了然。 下面我们将SDO分为读操作和写操作分别展开具体的通讯协议。再次强调我们是主节点去读/写操作从节点对象字典主语是主节点
读操作 图21. SDO读操作主节点发送报文
由主节点发送给从节点 图22.SDO读操作从节点回应报文
由从节点发送给主节点 下面做一个举例说明 图23. 驱动器设备CIA402协议的对象字典的局部内容
图23中的数值都是十六进制注意一下081020分别表示8位16位32位。 图24.SDO读操作示例
如图24所示示例中是主节点现在先要读取驱动器1号NodeID1的伺服实际位置6063 00索引 子索引图23最后一行。CANopen是低字节在前高字节在后的小端格式所以图24中的6360实际上6063。
从节点回应的报文43代表我回的是4个字节图22有写63 60/00表示6063索引/00子索引。最后13 D1 FF FF就是具体的实际位置的数据啦。由于CANopen是小端格式所以反过来是FF FF FD 13转换成10进制为-12013。
写操作 图25. SDO写操作主节点发送报文
由主节点发送给从节点 图26.SDO写操作从节点回应报文
由从节点发送给主节点
同样的下面也给出一个SDO写操作的示例。 图27. SDO写操作示例写成功
如图27所示我们先看发送报文23H表示写4个字节7A 60 00表示607A索引/00子索引, 回顾刚才的图23607A/00表示的是目标位置。 A0 86 01 00 是 00 01 86 A0的小端格式 100000d。 再看回应报文60表示写操作成功了后面索引和数据回来的是一样的。说明我们把目标位置100000写到NodeID 1的驱动器的对象字典里面去啦。 如果驱动器正常工作的话 就会把电机转到100000这个位置去啦。
那么有成功也会有失败失败的报文是怎样的呢 图28. SDO通讯失败读/写操作
如图28所示无论的读还是写如果SDO通讯失败返回的命令字都是80。数据中最后4个字节表示错误代码。其定义如下 图29.SDO通讯失败错误代码
如图29所示红色框住的部分是比较常见的SDO通讯错误。第一个可能是索引搞错了大小端没注意。第二个可能是位宽搞错了比如往8位宽的字典里面写32位宽的数据。
5 PDO过程数据报文 [ COB_ID : 180HNodeID ~500HNodeID]
终于到达了地狱级难度的PDO啦哈哈其实也没有那么难如果前文的所有内容你都理解了那么PDO也不过是水到渠成的事情只不过就是步骤多一些多绕几个弯子。 PDO相比于SDO而言它的优势在于它不需要应答信号效率高因此用于传输实时性要去高的数据。但缺点也比较明显就是在运行PDO之前需要进行一些地狱级难度的配置工作。大家不必担心和心急请耐心的看后文我们一层一层的破开云雾见月明。遇到有疑惑的地方带着疑惑往下看你得疑惑应该都会对应的解答。
知识点1
下面讲第一个我认为在学习PDO的时候比较重要的事情我们在网上所看到的资料所说的TxPDO和RxPDO基本是都是针对从节点而言的。所谓的传输Tx是说从节点传输PDO报文到主节点。 所谓的接收Rx是说从节点接收主节点发过来的PDO报文。 每一个PDO都有两组参数要配置通讯参数和映射参数后面细讲说的也是去配置从节点的对象字典。SDO的读写操作是指主节点去读写操作从节点。 PDO的Tx和Rx指的是从节点的传输和接收。网上的资料很少去强调这个导致很多时候理解起来有点困难。
知识点2
第二个比较重要事情也需要进一步提前说明 之前我们也提到了无论主节点还是从节点都是存在一个对象字典的。PDO的通讯是需要提前进行一些配置工作的 网上很多资料的重点是去讲 如何利用SDO通讯去配置从节点的PDO的通讯参数和映射参数。但是忽略了主节点也需要配置PDO相关的对象字典我们主节点对于PDO参数的配置主要是用开源的对象字典工具软件objdictedit生成。但这也是一个重要的事情不能忽视。 可能这时候有点绕了 我们从节点是不是存在TxPDO和RxPDO。对于从节点的TxPDO和RxPDO都需要对他们的通讯参数和映射参数进行配置。 那么从节点的TxPDO配置完了是不是要发送报文给主节点。 那么主节点的RxPDO是不是也需要做一个对于的配置。有点像串口通信从节点的TxPDO对于主节点的RxPDO。从节点的RxPDO对于主节点的TxPDO。 总结来讲就是从节点的TxPDO和RxPDO主节点的TxPDO和RxPDO都需要进行配置。 从节点的PDO配置主要通过主节点发送SDO通讯去配置从节点PDO的通讯参数和映射参数的对应的对象字典。 主节点的PDO配置主要通过开源的objdictedit软件直接生成。
知识点3
是不是感觉上面两个比较重要的事情有点绕了 哈哈下面我讲第三个重要的事情前面我们提到无论是TxPDO和RxPDO每一个PDO都有两组参数要配置这两组参数分别叫做通讯参数和映射参数。注意一我的用词是两组参数。为什么用组而不用个。因为通讯参数和映射参数中包含的配置项都不止一项。举个例子从节点的第一个TPDO1它所对应的通讯参数和映射参数在其对象字典中的索引分别是1800H和1A00H。 好这还没完TPDO1的通讯参数包含7个配置项。其具体的实现方式就是子索引。之前大家可能对子索引还比较疑惑为什么索引下面还有个子索引呢其实就是有时候索引是不够用的因此同一功能的索引下面还包含很多个子索引。比如TPDO1的通讯参数索引是1800H它的子索引分别是00H 01H 02H…06H。每个子索引代表的含义位宽值的含义如图30所示。 图30. 从节点 – TxPDO1 – 通讯参数- 索引/子索引以及每个子索引的含义位宽值的含义 同理TPDO1的映射参数的1A00H对应的子索引也不止一个如图31所示。 图31.从节点-TPDO1-映射参数-索引/子索引以及每个子索引的含义位宽值的含义 映射参数的子索引还不是固定的个数这主要取决于第一个子索引00H它代表的映射参数数目。如图31所示当它的值为2的时候后面就还有01 02两个子索引。以此类推如果它的值是4呢后面可以有01 02 03 04四个子索引。 但是这里有一个约束就是你所有的映射参数的位宽加起来不能超过64位。可以这么说就是你后面可以最多8个子索引每个子索引的位宽都是8位8*864位。
知识点4
怎么样 信息量是不是上来了所以叫地狱难度。接下来我们说第四个重要的事情。一般标准的CANopen协议里面无论是从节点还是主节点。 它的TxPDO和RxPDO都是4个即TxPDO1、TxPDO2、TxPDO3、TxPDO4、RxPDO1、RxPDO2、RxPDO3、RxPDO4总共8个PDO。每个PDO都会有对应的通讯参数和映射参数。那就是16个索引不知道多少个子索引了。 那有的人就会觉得啊我配置从节点的一个TPDO1都费劲了我还要配从节点8个PDO主节点8个PDO那不是得废老大劲啦 这里给一个回答就是真实的使用场景这些PDO可能未必会全部使用。大家按照需要去配置。 下面给出从节点所有PDO的COB_ID和通讯参数/映射参数的索引子索引定义都一样的如图30和31所示 图32. 从节点 TPDO/RPDO的COB_ID以及通讯参数/映射参数索引 前面我们第二个重要的事情提到主节点是需要配置TPDO/RPDO的那主节点的COB_ID以及通讯/映射参数的索引是怎样的呢请看图33。 图33. 主/从节点的PDO COB_ID以及通讯/映射参数索引
注意到图33中主机的COB_ID是个大的范围是因为一个CAN网络中可以允许有127个从Node。这些Node的ID是不一样的。在一个有多个从节点的CAN网络中主节点的TPDO和RPDO的使用率应该是较大的甚至有可能8个都用完。而从节点的TPDO和RPDO有可能的只使用一组。从图33还有另外的关键信息即主机的TPDO/RPDO的COB_ID与从机相反
主机的TPDO和从机的RPDO的COB_ID号是一样的主机的RPDO和从机的TPDO的COB_ID号是一样的。
知识点5
紧接上文我们讲第5个重要的问题 想象一个场景如果CAN网络中有3个驱动器 我主机需要通过TPDO分别发送3个目标速度给3个驱动器。 由于驱动器的NodeID号不一样所以主机需要用3个TPDO配置3个不同的COB_ID。但在配置映射参数的时候问题来啦我这3个目标速度应该放在哪个索引里面。我主机的TPDO应该去哪些索引里面去取3个目标速度呢 有的熟悉CIA402协议的同学可以立马反应过来了马上举手站起来就回答。目标速度的索引/子索引是60 FF/00。 记忆力很好哈可惜这个不是老师要的答案哈秀儿你坐下。 对于驱动器而言它遵循CIA402协议目标速度的索引确实是在60 FF/00这个位置。 但对于CAN网络中的主机单片机而言它是不遵循CIA402协议这一点很重要。 如果目标速度是在索引60 FF/00这个地址那岂不是我主机发给3个驱动器的目标速度都是一样的值啦。 正确的做法应该是把的3个电机的目标速度的索引放在 2000H~5FFFH这个区域如图7所示这个索引区域是什么是制造商特定子协议区。换成大白话就是这部分索引我想怎么定义就怎么定义。这部分的配置还是在objdictedit工具里面配置。 请仔细阅读上述文字后再继续阅读下文。 通讯参数和映射参数的配置以及报文格式
随着信息量越来越大所产生的疑惑可能会越来越多主要的疑惑可能是我的通讯参数和映射参数具体应该怎么配置参数里面各个子索引分别的什么含义我们RxPDO报文和TxPDO报文它的格式到底是怎么样的 下面以配置主节点的TPDO和配置从节点的RPDO为例进行进一步的讲解。
例子假设现在我们要用主节点的TxPDO1给从节点驱动器发送目标速度从节点用RxPDO1来进行接收。
网上的资料经常会忽略或不重视主节点的TxPDO1的配置因为这步的操作是在objdictedit工具里面完成的。下面我们就先来讲主节点TxPDO1的配置。
主节点TxPDO1的配置
TxPDO1的需要配置三个东西 1、在制造商特定子协议区自己定义一个目标速度的索引 2、TxPDO1的通讯参数配置 3、TxPDO1的映射参数配置
我们先看第1点如何实现。 面我们来看第2点TPDO1的通讯参数配置 0x00 Highest Sublndex Supported
最大子索引支持个数只读的我们不需要配置。6就代表后面0x00子索引后面还有0x01、0x02、0x03、0x04、0x05、0x06 6个子索引。
0x01 COB_ID used by PDO
指的是主节点在发送TPDO报文的时候的COB_ID。 这里由0x180 NodeID组成。比如我主节点想通过TPDO1发送目标速度个驱动器驱动器的NodeID是1那么这里的COB_ID就要写0x1801 0x181。
0x02 Transmission Type
TPDO的传输类型这个子索引对于的数据位宽的8位 不同的值代表着TPDO不同的传输方式。如下图所示 当TPDO传输类型的值为0时代表同步/非循环模式如果映射数据发生改变且接收到一个同步帧则发送该TPDO。可是同步帧一般情况下都是由主节点发送给从节点的。所以在主节点用TPDO发送数据给从节点的时候我感觉一般不用这个类型。
当TPDO传输类型的值为1~240时代表同步/循环模式比如值为2那么该TPDO报文将在接收到两个同步帧之后但还是同样一个问题同步帧一般情况下都是由主节点发送给从节点的。主节点发送同步帧的时候不知道主节点会对同步帧计数吗
241~253这一段值保留暂时不管
当TPDO传输类型的值为为254、255时代表异步/制造商特定事件和设备子协议特定事件。 网上很多资料说当映射数据改变或事件计时器到就会发送PDO。但有人测试过254或者255的情况下如果映射数据改变的时候不会发送PDO只有事件计时器到才会发送PDO。 我的理解是254代表映射数据改变的触发TPDO这个不靠谱。所以这里可能靠谱的做法是选255然后配合0x05 Event Timer做事件定时触发。 0x03 Inhibit Time 禁止时间这一项对异步传输类型的TPDO才有用用来规定TPDO发送的最小时间间隔。这其实就是流量控制防止TPDO狂发占用大量CAN总线带宽。CIA301协议规定禁止时间的分辨率是100us精度是2毫秒。比如你要禁止1毫秒你这个数值得写10d。你要禁止2毫秒这个数值得写20。注意有些设备可能把这个分辨率改成1ms什么的使用的时候注意。
0x04 Compatibility Entry这个参数不管
0x05 Event Timer 事件定时器这个应该是和传输类型为 254/255的异步传输类型配合使用。 这个参数名很容易让人误解这里要这么去理解这个参数这个参数代表的是TPDO定时周期在移植CANopen协议开源库到单片机的时候它是需要实现带定时器功能也就是说CANopen协议内部是自带定时器的。 这就可以解释这个参数了。 这个参数的单位的1ms。 比如你填入一个1那么CANopen应该就会每隔1ms触发一次TPDO。 配合0x03禁止时间使用。 0x06 SYNC start value TPDO同步帧的起始值这个容易理解这个是配合传输类型为1~240使用比如传输类型值是2。 同步帧起始值这里我配置的是1那么我第一次出发TPDO报文应该是只需要收到1个同步帧就可以了。 后续第2帧开始以后的TPDO报文我猜测应该还是要接到2同步帧才能触发发送。目前来讲没什么卵用。 那么总结一下主机发送TPDO的方式无非就两种
一种是传输类型为1~240当收到从节点的n个同步帧之后触发TPDO。一种是传输类型为255结果0x05的Event Timer主机不需要接收从节点的同步帧而是采用自己内部的定时器进行周期性的触发。
具体选择哪一种呢 需要做一个验证我有一个设想如果主节点往从节点发送的同步帧也算是主机自己接到的同步帧的话也就是说主节点在发送同步的是同时也会触发自己的TPDO这样就美滋滋了。 这就果断选同步循环方式。 否则就选择第二种定时器触发方式。本文中稳妥起见我暂时认为我的设想是错误的即如果我配置主机的TPDO是同步循环模式则从节点必须发送同步帧到主机才能触发主机的TPDO。 所以我选择定时器触发。
那么我们通讯参数配置则如下 下面来看第3点 TxPDO1的映射参数配置 映射参数我们也简单来理解一下这个比通讯参数简单多了。 这里我认为这个软件少显示了一些信息这里只简化显示了变量名没有显示 子索引 和 位宽。不过生成对象字典的时候应该会自动生成标准的映射参数配置我们来看下图。 你看【值】的部分 是存在 7100H(索引) / 01H(子索引) / 10H16位宽3个部分的。
从节点RxPDO1的配置
前面提到了从节点比如说驱动器它的对象字典可能有两种配置方式一种是通过驱动器本身的上位机软件进行配置一种是通过主节点给从节点发送SDO指令来配置。 上位机配置的方式和上面主节点用objdictedit配置方式估计大同小异而有些驱动器是不支持上位机配置的方式的。所以关于从节点RxPDO1的配置我们用SDO指令的方式讲解而且里面还有一些其他的东西需要注意。 假设我们使用RPDO1来接收主机发过来的信息。那么我们需要配置RPDO1的通讯参数和映射参数。即1400H和1600H两个索引。RPDO1的通讯参数和映射参数的索引是1400H和1600H。 由于它一个索引号不止要配置一个参数。所以还有子索引。每个子索引呢代表不同的含义。 上面这两张图是有点不严谨的不必在意可以看到是抄了以前的图然后稍微改了改。
使用SDO的配置方式是由固定流程的。 SDO指令如果搞忘了可以倒回去看第4小节。
0x22是通用的写驱动器未必都支持这种协议建议还是使用下面这种方式。
2f:写入1个;
2b:写入2个;
27:写入3个;
23:写入4个 下面对上述指令进行一一解析。
第一条指令 第二条指令 第三条指令 注意一下这里追加映射参数的时候所有参数的总长度不能超过8个字节。
比如我01子索引映射参数长度20H32d位 02 子索引映射参数长度20H32d位
前面两个参数已经64位 8字节了 后面03 04就不能再加了。
第四条指令 第5条指令。 前面5条配置完RPDO1的配置就结束了但是它并不代表现在PDO就能运行了。 因为CANopen协议规定PDO服务必须只能在operational操作状态下在能运行。 另外驱动器本身还需要做一些设置也是通过SDO服务。
第6~9条命令 这时候我们可以用SDO发送速度也可以用PDO发送目标速度了。前面第1~5条指令就为了配置驱动器的RPDO1的。就是为了让主机通过PDO把目标速度发过去。 如果你不用PDO前面的配置反而没意义了。而且PDO发送效率更高不需要应答。
第10条指令
PDO的配置结束时候还需要发送应NMT网络管理指令。将从机驱动器NODE-ID假设0x01的CANopen状态机的状态切换成operational操作状态。 第11~∞条 大家有没有发现我们在配置从节点RxPDO的时候COB_ID配置的是201但是前面主节点TxPDO的配置却是配置的181。 这是objedit个坑它会提示你180NodeID我在截图的时候没注意就搞成181了。 前面知识点4提到过的。主节点的RxPDO和TxPDO的COB_ID和 从节点的COB_ID是反的。所以应该是这样 总结学习一个新东西最好还是要做一个笔记整理整理的过程中你会发现以前以为明白的地方其实并没有理解透彻这个时候能继续查漏补缺进一步完善。 下集预告CANopen开源库移植欢迎关注/阅订。