CAN 总线是一种串行通信协议,具有较高的通信速率的和较强的抗干扰能力,可以作为现场总线应用于电磁噪声较大的场合。由于
CAN 总线本身只定义ISO/OSI 模型中的第一层(物理层)和第二层(数据链路层),通常情况下 CAN 总线网络都是独立的网络,所以
没有网络层。在实际使用中,用户还需要自己定义应用层的协议,因此在 CAN总线的发展过程中出现了各种版本的CAN应用层协议,
现阶段最流行的CAN应用层协议CANopen协议。
CANOpen用来收发数据的通信对象有SDO(Service Data Object)和PDO(Process Data Object)
1. 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.
2. 数据域 (0-8字节)
3. CMD命令字
4. 对象索引与子索引
一、SDO和PDO的区别
SDO使用对象字典的 Index 和 SubIndex 来访问CAN节点的对象字典,可以读或者写。
而PDO则不使用Index和SubIndex,它是两个CAN节点间约定好传输的数据内容对应哪些对象字典索引,收到数据后就直接读写相应的对象字典索引里的值。
由于SDO(常规)需要用到 Index和 SubIndex,所以一次最多传输4个字节,而PDO一次最多可以传输8个字节。
另外,SDO还有很多其它传输功能,这里就不细说了,有兴趣的可以看官方Spec。
二、PDO的COB-ID
PDO有2种,TPDO和RPDO,一个用来发送,一个用来接收。由生产者发送的 PDO称为发送 PDO(TPDO),同样消费者接收的 PDO 称为接收 PDO(即 RPDO)
PDO通信参数里需要设置COB-ID。
对于TPDO来说,其通信参数中的COB-ID是 自身 的COB-ID,当发送TPDO时用来表明这个TPDO是谁发出的。
对于RPDO来说,其通信参数的COB-ID是 发送方 的COB-ID,用来表示自己只接受某个CAN节点发过来的TPDO。
三、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了。