文章目录
背景
- 目前很多CANOpen介绍的文章比较繁琐,讲很多历史由来,虽然更方便读者了解原委,但对于快速上手是不合适的。
- 本文简单直接,默认大家都熟悉CAN协议,在此基础上快速对CANOpen协议进行学习。
协议介绍
CAN总线协议
- CAN是差分总线通信,包括H和L两根线,当二者电压相同时称为隐性表示数据1,电压不同时称为显性表示数据0。空闲状态时,总线上为隐性,只要有一个节点表现为显性,总线电平就会被拉到显性。
- CAN协议在通信时,采用数据帧的格式进行通信。帧格式有数据帧、遥控帧等类型,最常见的是数据帧。其格式如下:
- 在节点A向B发数据时,首先A发送0帧起始位SOF,表示自己要发送数据了。当数据发送完毕时,发送连续的7位1代表帧结束标志EOF。因此,节点的ID不能设置为高7位全是1,否则会被当做帧结束标志直接结束传输。
- 在CAN网络中,每个消息都有自己的地址,称为ID(注意:ID并不是说节点的地址,而是消息的ID,具体可以看附录内容)。ID不仅用于标识不同的消息内容,还牵扯到优先级,当多个节点同时发起SOF请求时,ID值越小的优先级越高,具体竞争原理参考本文后部分。
- 早期的CAN数据帧的ID为11位,后来不够用扩展到了29位,因此前者称为标准数据帧,后者称为扩展数据帧,其差别只有仲裁段的ID长度不同。
- 发送完ID之后,发送RTR位,用于分辨该帧是数据帧(RTR为0)还是遥控帧(RTR为1)。对于后来才提出来的扩展帧,由于想兼容老的标准帧格式,因此也发送数据帧和遥控帧标志,该位记为SRR,用于实现和RTR一样的功能。
- 扩展帧发送完SRR位之后,会多发一位IDE位,用于表示该帧是标准帧还是扩展帧。接收端不知道要接收的帧是标准帧还是扩展帧,在接收完11位ID和1位的RTR之后,会认为进入标准帧的控制段了,标准帧控制段第一位是IDE,如果该位为0,则认为是标准帧没错,后面跟着的就是r0保留位和数据长度标识DLC(4位)。
- 而如果接收到IDE位是1,接收端就知道接收的帧不是标准帧,而是扩展帧,接着就会再接收18位的扩展ID,接着再接收RTR,然后是2个保留位和4个DLC位。
- 在控制段接收完之后,开始接收数据段。数据段最长是8个字节。
- 接着就接收CRC校验段。CRC校验段会对从帧起始位到数据位的数据进行校验,结果为15位的CRC值,为了界定出CRC值所在地方,会在15位的CRC后追加1位CRC界定符逻辑1,最终一起组成16位的CRC校验位。
- 接着就是ACK段。ACK段时,发送方发送隐形电平1,如果接收方前面的信息接收正确,则需要在此期间发送线性电平0。这期间称为ACK槽,然后是1个隐形电平的ACK分界符。
- 最后,是帧结束标志,由7个隐形电平1组成,帧通信完成。
CANOpen协议介绍
CANOpen诞生背景
- 上述的CAN协议,定义了物理层的高低电平,也定义了数据链路层的帧结构,而直接通过总线连在了一起也不需要传输层和网络层,因此对于应用CAN协议时,只需要制定应用层协议就可以了。
- 由于不同家有不同的CAN应用层协议,而近年来的需求则是不同家的CAN设备可以有一个统一的协议,向USB那样接入就可以使用,因此诞生了CANOpen。
- CANopen是一种基于CAN(Controller Area Network,控制器局域网络)总线的高层协议,主要用于嵌入式系统的网络化通信。它最初由CiA(CAN in Automation)组织开发,广泛应用于工业自动化、医疗设备、建筑自动化和其他嵌入式系统领域。
- CANOpen主要通过对象字典和配置文件实现协议的通用性。
CANOpen的对象字典
- 对象字典(Object Dictionary)是CANopen协议中一个关键的概念。它是一个数据结构,用于描述和存储设备的所有通信和配置参数。每个CANopen设备都有一个独立的对象字典,在支持CANOpen的设备上,通过修改对象字典的参数,就可以对该设备进行配置,类似于常见的传感器中寄存器。
- 对象字典中的条目通过16位索引和8位子索引进行标识。如下是一个对象字典的实例:
bash
Index | Sub-Index | Name | Type | Value
-------------------------------------------------------------
1000h | 0 | Device Type | Unsigned32 | 0x00000001
1001h | 0 | Error Register | Unsigned8 | 0x00
1018h | 0 | Identity Object | |
| 1 | Vendor ID | Unsigned32 | 0x00000123
| 2 | Product Code | Unsigned32 | 0x00004567
| 3 | Revision Number | Unsigned32 | 0x00000001
| 4 | Serial Number | Unsigned32 | 0x00000000
- Index是索引,由2个字节组成。Sub-Index是子类型,由1个字节组成。
- 在上述实例中,索引1000h是设备类型。
- 索引1018h是身份对象,包含的子类型有:厂商ID、产品代码、版本号和序列号。
- 对象字典可以根据自己的设备需要进行自定义。CANopen协议定义了一组所有设备上标准化的对象字典条目,用于常见的设备功能。这些标准条目确保了不同设备之间的互操作性。以下是一些常见的标准对象字典条目:
bash
0x1000-0x1FFF:通信配置参数
0x1000:设备类型
0x1001:错误寄存器
0x1018:身份对象(包含厂商ID、产品代码等)
0x2000-0x5FFF:应用对象
0x2000-0x27FF:设备配置参数
0x2800-0x28FF:输入PDO映射
0x2900-0x29FF:输出PDO映射
- 除了标准条目,用户可以根据具体应用需求定义自定义对象字典条目。这些条目通常放在标准范围之外,以避免冲突。例如:
bash
0x6000-0x9FFF:用户自定义参数
0x6000:自定义传感器数据
0x7000:自定义控制参数
- 在CANOpen进行通信传输时,由专门的通信对象来访问和传输对象字典中的数据。通信对象包括服务数据对象(SDO)和过程数据对象(PDO)。
CANOpen的服务数据对象(SDO)
-
服务数据对象(Service Data Object,SDO)是CANOpen中用于在设备之间传输配置数据和参数的重要机制。SDO主要用于点对点的数据传输,允许设备请求和发送对象字典中的数据。它的关键特征包括:
用途:用于设备配置、参数设置和诊断。
单向和双向:可以是客户端-服务器模式的单向传输(SDO客户端请求数据或设置数据),
也可以是双向传输(SDO服务器响应请求或确认传输)。通信:通过CAN总线发送,使用11位的标准或29位的扩展帧格式。
-
SDO帧的格式规定如下:
-
1、SDO请求帧:
- CAN标识符:11位标识符,格式为0x600 + 节点ID。
- 数据字段:8字节数据字段,其中包含以下信息:
- 命令字节:指示SDO命令类型(如读取、写入等)。
- 索引:16位对象字典索引。
- 子索引:8位对象字典子索引。
- 数据:具体的数据内容(长度可变)。
-
2、SDO响应帧:
- CAN标识符:11位标识符,格式为0x580 + 节点ID。
- 数据字段:8字节数据字段,与SDO请求帧类似,但包含响应数据或确认信息。
-
-
例如,当需要修改或读取CANOpen设备中对象字典的某个条目时,我们可以通过SDO来实现。过程如下:
-
示例:以下是一个SDO读请求帧的示例,假设读取索引为0x1018(身份对象)子索引为0x01(厂商ID):
- CAN标识符:0x600 + 节点ID(假设节点ID为1,则标识符为0x601)。
- 数据字段:
- 命令字节:0x40(表示读取命令)。
- 索引:0x18 0x10(表示对象字典索引0x1018)。
- 子索引:0x01(表示子索引0x01)。
- 数据:0x00 0x00 0x00 0x00(保留字段)。
-
在上述SDO格式下,实际通过CAN协议发出去的8字节数据帧如下:
bashCAN帧: ID: 0x601 Data: 0x40 0x18 0x10 0x01 0x00 0x00 0x00 0x00
-
如果设备响应这个请求,响应帧可能如下:
- CAN标识符:0x580 + 节点ID(假设节点ID为1,则标识符为0x581)。
- 数据字段:
- 命令字节:0x43(表示读取响应)。
- 索引:0x18 0x10(表示对象字典索引0x1018)。
- 子索引:0x01(表示子索引0x01)。
- 数据:0x23 0x01 0x00 0x00(表示厂商ID为0x00000123)。
-
对应的响应CAN帧如下:
bashCAN帧: ID: 0x581 Data: 0x43 0x18 0x10 0x01 0x23 0x01 0x00 0x00
-
参考
附录问题
CAN总线竞争原理
- 在节点发送自己的ID时,会一边输出自己的ID到总线上,一边测量总线上的电平是不是自己输出的电平。如果不是,则认为此时有其他的节点也在竞争,且ID优先级比自己高,自己就立即停止发送。
- 过程如下:
- 当ID相同时,会继续比较RTR位。由于数据帧的RTR位为0,遥控帧的RTR位为1,因此ID相同的数据帧优先级高于遥控帧。
在CAN协议中,帧中的ID是发送者的ID还是接收者的ID?
- 在CAN(Controller Area Network)协议中,帧中的ID(标识符)既不是发送者的ID,也不是接收者的ID。
- 相反,ID表示的是消息的内容和优先级。CAN协议采用基于消息的通信方式,而不是基于节点的通信方式。
- ID用于标识消息的内容。每个消息类型都有一个唯一的ID,不同ID的消息表示不同的内容。例如,一个ID可以表示发动机转速,另一个ID可以表示温度传感器数据。