CANopen中SDO、PDO字典以及COB-ID理解

    CAN 总线是一种串行通信协议,具有较高的通信速率的和较强的抗干扰能力,可以作为现场总线应用于电磁噪声较大的场合。

     由于CAN 总线本身只定义ISO/OSI 模型中的第一层(物理层)和第二层(数据链路层),通常情况下 CAN 总线网络都是独立的网络,所以没有网络层。

    在实际使用中,用户还需要自己定义应用层的协议,因此在 CAN总线的发展过程中出现了各种版本的CAN应用层协议,现阶段最流行的CAN应用层协议:CANopen协议

   CANOpen用来收发数据的通信对象有 SDO(Service Data Object)和 PDO(Process Data Object)

一、协议报文结构

1.1 COB-ID(11/29位) 

COB-ID(11) = Function Code(4)  + Node ID(7) (或其他),如图所示:

Function Code二进制):
EMCY:0001;
PDO:0011, 0100, 0101, 0110, 0111, 1000, 1001, 1010;
SDOrx : 1011;
SDOtx : 1100;
NMT error control : 1110;
NMT : 0000;
SYNC : 0001;
TIME STAMP : 0010;

例子:182H=0001 1000 0010(B)
11bit为 0011 0000 010:前四位0011为功能码PDO,后四位为节点号,10=2即节点为2.

                                                          表 1    功能码

1.2 数据域 (0-8字节)

 1.3 CMD命令字(数据域1st字节)

 1.4 对象索引(数据域2nd-3rd字节)与子索引(数据域4th字节)

二、SDO和PDO的区别

    CANOpen包括多种通信方式:主从站方式、客户服务器方式以及生产者消费者模式。SDO使用客户服务器模式。其中PDO采用生产者消费者模式。

2.1 SDO

    SDO(Service Data Object)服务数据对象,用来传输非时间关键数据。服务确认是 SDO 的最大的特点,为每个消息都生成一个应答,确保数据传输的准确性。

    使用对象字典的 Index 和 SubIndex 来实现(客户端)节点访问CAN(服务端)节点的对象字典,可以读或者写。 Refer:CAN Open基础知识 (taodudu.cc)

    由于SDO(常规)需要用到 Index和 SubIndex,所以一次最多传输4个字节,而PDO一次最多可以传输8个字节。

    另外,SDO还有很多其它传输功能,这里就不细说了,有兴趣的可以看官方Spec。

2.2 PDO

    PDO(Process Data Object)过程数据对象,8字节全部用来传输实时数据,提供对设备应用对象的直接访问通道,它用来传输实时短帧数据,具有较高的优先权。PDO 传输的数据必须少于或等于 8 个字节,PDO 的 CAN 报文数据域中每个字节都用作数据传输,因此,在应用层上不包含传输控制信息,报文利用率极高。

     PDO 通信是基于生产者/消费者的通讯模式[13],如图 3-3 所示,每个 PDO 有一个唯一的标识符且可以通过一个节点发送,但有多个节点可以接收。由生产者发送的 PDO称为发送 PDO(TPDO),同样消费者接收的 PDO 称为接收 PDO(即 RPDO)。PDO 的接收不需要消费者的确认。

      而PDO则不使用Index和SubIndex,它是两个CAN(生产者、消费者)节点间约定好传输的数据内容对应哪些对象字典索引,收到数据后就直接读写相应的对象字典索引里的值。


    2.2.1 PDO传输与触发方式

PDO 的两种传输方式:同步传输异步传输。1、2为异步传输,3、4为同步传输。

    1) 异步传输(由特定事件触发)

其触发方式可有两种, 第一种是由设备子协议中规定的对象特定事件来触发(例如,定时传输,数据变化传输等)。第二种是通过发送与 PDO 的 COB-ID 相同的远程帧来触发 PDO的发送。 目前应用中的异步传输基本都采用第一种。

    2) 同步传输(通过接收同步对象实现同步)

同步传输就是通过同步报文让所有节点能在同一时刻进行上传数据或者执行下达的应用指令,可以有效避免异步传输导致的应用逻辑混乱和总线负载不平衡的问题。 一般发送同步报文的节点是 NMT 主机。

    PDO通讯具有三种触发模式:内部事件驱动或内部定时器触发、同步触发、远程请求触发

     1) 内部事件驱动或内部定时器触发。通讯由某一事件触发。例如数字 I/O 口状态改变,超过预先设定的值、定时器中断等都会触发节点发送一个 PDO。这种模式可使总线负载达到最小,在相对低的波特率下获得比较高的通讯特性。

    2)同步触发。同步触发 PDO 是指 CANopen 节点收到由管理节点发出的同步报文(同步对象 Sync)之后,根据触发报文条件向总线发出 PDO 报文。同步传输又分为周期性和非周期性,周期性是指 CANopen 节点接收到一定数量的同步报文之后才开始发送;非周期性 PDO 是指 PDO 触发条件成立之后,当收到下一个同步对象后马上发送PDO。

    3) 远程请求触发。PDO 消费者可以给 PDO 生产者发送远程 PDO 请求,相应 PDO 生产者将对远程帧做出响应,向总线上发送相应的 PDO 数据。

PDO 通讯时的触发模式由 PDO 通信参数中的传输类型来确定,传输类型是一个 8位无符号整数,这个传输类型值的大小与 PDO 触发方式的对应关系如下表所示。

    SYNC为同步帧,RTR为远程帧,Event为事件例如定时器或者值改变。其中B表示都需要,而O代表一个或者多个触发条件满足就发送。

 a) 00h:非循环同步
  只能异步发送(即接收到发送请求或者主动发送),接收到SYNC帧不会发送。
 b) 01h:循环同步
  根据TestSlave_obj1400_SYNC_start_value里面设置的值接收到SYNC的个数发送一次。
 c) FCh:远程同步  
  当收到PDO请求,若该PDO_status的状态位PDO_RTR_SYNC_READY置位(会在接收到SYNC信号调用的_sendPDOevent中BuildPDO并置该位),则直接发出PDO的最后一帧。
 d) FDh:远程异步  
  当收到PDO请求(SendPDORequest)后立即BuildPDO发送被请求的PDO帧(cob_id标示)。
 e) FEh:异步,制造商特定事件和 FFh:异步,设备子协议特定事件  
  调用sendPDOevent()(未被阻止inhibited)后建立PDO并检查其PDO帧与上一次发送(PDO_status.last_message)的PDO帧内容是否发生变化,若发生变化则发送,否则不发送。接收到SYNC帧不会发送该帧。但是若接收到PDO请求则强制建立并发送。

2.2.2 PDO描述

    每个 PDO 在对象字典中由两个对象描述:通信参数映射参数

    通信参数:定义了该设备所使用的COB-ID,传输类型,禁用时间和定时时间;决定该节点需要接收来自哪个节点的数据,或者将数据发送给哪个节点。对于从节点,由于发送数据桢是广播的,因此不需要设置该参数;对于主站的发送数据桢 Preq,需要设置该参数,来标示该数据桢是发送给哪个从节点的。
      RPDO通讯参数位于对象字典索引的1400h to 15FFh,TPDO通讯参数位于对象字典索引的1800h to 19FFh。 每条索引代表一个PDO的通信参数集,其中的子索引分别指向具体的各种参数。

    映射参数:映射参数包含了一个对象字典中的对象列表,其中包括数据的长度(单位,位),指定PDO传输数据在对象词典中的位置索引,也就是确定对象字典中的对象(Object)与数据包中数据(域)段的对应关系。决定该节点如何组成要发送的CAN报文或者如何解析收到的数据包。而不需要在 CAN 报文中增加额外的协议控制信息,使传输的效率达到最高。一个 PDO 最多可以映射 64 个对象。

注:PDO映射相当于定义该PDO的数据组成成分,相当于将各个映射到的索引所指示的内容拼接成一个PDO帧发送。

2.2.1.1 TPDO通讯参数

0x1800-0x1807

TPDO映射参数

0x1A00-0x1A07

2.2.2.2 RPDO通讯参数

0x1400-0x1407

RPDO映射参数

0x1600-0x1607

2.2.3 对象字典:通信参数、映射参数、数据区

       

上图,这就是PDO的配置过程:
0x1402(接收PDO通讯参数),PDO使用的cob-id,传输类型,Inhibit time,EventTimer。
0x1602(映射对象),上例中映射为Controlword,Target position。

2.2.3.1 字典编辑器Objdictedit 实例如下图:

A 通信定义

帧定义(帧ID与数据格式):  
487中的7,  指定了只接收发送方ID为7的这个PDO。

B 映射(字典与帧ID)

C 数据定义

2.3 PDO的COB-ID

    PDO有2种,TPDO和RPDO,一个用来发送,一个用来接收。由生产者定义并发送的 PDO称为发送 PDO(TPDO),同样消费者定义并接收的 PDO 称为接收 PDO(即 RPDO)

    注意:PDO通信参数里需要设置COB-ID。发送方与接收方,双(或多)方是通过COB-ID, 来匹配的,而不是对象字典的 索引Index 和 子索引SubIndex。

    对于TPDO来说,其通信参数中的COB-ID是 自身 的COB-ID,当发送TPDO时用来表明这个TPDO是谁发出的。
    对于RPDO来说,其通信参数的COB-ID是 发送方 的COB-ID,用来表示自己只接受某个CAN节点发过来的TPDO。

2.4 SDO的COB-ID

SDO中的COB-ID有2个,分为:

Client ==> Server
Server ==> Client
乍一看有点晕,如果我们换个角度思考下就容易理解了,假如CAN节点A通过SDO去访问CAN节点B,那么A就是Client,B就是Server。

类似于平时上网时去打开百度,需要在浏览器的地址栏里输入百度的地址,然后就可以打开百度了。网民是Client,百度是Server,百度的网址就是Client==>Server的COB-ID。

这样在A的对象字典里,设置 Client==>Server的COB-ID为B的COB-ID

而A的Server==>Client的COB-ID怎么设置呢?当A发送SDO给B时,B收到SDO后会回传一个SDO给A来表示应答。之前说了,A访问B,A是Client,B是Server,现在B回传一个应答SDO给A,那么路径就是Server==>Client,这样对于A来说,其 Server==>Client的COB-ID还是B的COB-ID,用来表示收到的应答SDO是来自Server的。

可能会想到B的这两个COB-ID干嘛去了呢,对于B来说,只有B是Client时才会用到这2个COB-ID,如果B通过SDO去访问A,那么B的Client==>Server和Server==>Client的COB-ID就是A的COB-ID了。


三、发送方具体实现例

3.1 发送方变量实现:

变量代码: au_slave3.h
extern UNS8 Reagent_RLState;        /* Mapped at index 0x2015, subindex 0x08 */

3.2 发送方数据字典定义

0x2015--0x08

3.3 发送方通信帧定义

帧ID: 284,  其中 4 为发送方ID。

3.4 发送方映射(字典与帧ID)

帧ID-284, 映射字典2015。

四、接收方具体实现例

4.1 接收方回调实现:

变量代码:au_master.c :: 
UNS8 Reagent_RLState = 0x0;        /* Mapped at index 0x2015, subindex 0x08 */

变量变化,回调注册:
RegisterSetODentryCallBack(&au_master_Data,0x2015,0x08, _cb_RPDO_MC3_RL);

4.2 接收方数据字典定义

0x2015--0x08

4.3 接收方通信帧定义

帧ID: 284,  其中 4 为发送方ID。
 

    unsigned char nodeID = 0x01; //节点ID
    setNodeId(&au_master_Data, nodeID);

4.4 接收方映射(字典与帧ID)

帧ID-284, 映射字典2015。

  • 16
    点赞
  • 128
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值