嵌入式开发—CAN通信协议详解与应用(上)
文章目录
- 1.CAN简介
- CAN协议的诞生背景
- CAN协议的发展历程
- CAN协议的影响
- CAN通信的主要特点
- 2.CAN数据帧的帧格式
- CAN标准数据帧的帧格式
- CAN标准数据帧的帧格式结构图
- CAN扩展帧的帧格式
- CAN遥控帧的帧格式
- CAN错误帧的帧格式
- 3.CAN数据传输中的位填充
- 位填充的概念
- 位填充的作用
- 位填充的工作机制
- 位填充示例
1.CAN简介
CAN协议的诞生背景
在1980年代,汽车内部的电子控制单元(ECU)数量逐渐增加,传统的点对点电气通信方式已经难以满足需求。每一个电子控制单元与其他设备之间的点对点连接使得系统布线复杂、成本高、故障率高。汽车制造商希望有一种能够简化布线,同时满足车辆实时控制和高可靠性要求的通信方式。
CAN协议的发展历程
- 1983年:开发需求:
- 博世公司意识到,汽车内部的电子设备(如发动机管理、车身控制等)需要更可靠、更高效的通信网络。因此,博世公司开始着手开发一种专为车辆设计的通信系统。
- 1986年:CAN协议发布:
- 博世公司在1986年正式发布了CAN协议的初步规范,并在同年举行的**国际社会科学控制会议(SAE International Congress and Exposition)**上进行了展示。
- 1987年:第一款CAN控制器:
- 博世与英飞凌(当时为西门子半导体部)合作,推出了世界上第一个CAN控制器芯片,标志着CAN协议的实际应用开始进入汽车电子市场。
- 1991年:ISO标准化:
- CAN协议在1991年通过了国际标准化组织(ISO)的审核,成为ISO 11898标准。这一标准规范了CAN协议的物理层和数据链路层,进一步推动了CAN在工业界的应用。
- 1990年代:广泛应用:
- 随着汽车电子技术的发展,CAN协议迅速普及,成为大多数汽车制造商的标准通信协议。CAN网络在汽车中的应用从发动机控制单元(ECU)扩展到了防抱死刹车系统(ABS)、车身控制模块(BCM)、车载诊断系统(OBD)等。
- 后续发展:
- 在CAN的基础上,博世公司还开发了CAN FD(Flexible Data-rate CAN),旨在提高数据传输速度和帧容量,以满足汽车中更高带宽的需求。CAN FD协议于2012年正式发布,并在汽车和其他高需求的工业应用中得到推广。
CAN协议的影响
CAN协议的推出彻底改变了汽车电子系统的架构,极大地简化了车内电子设备之间的通信,使得汽车系统更加高效、可靠、可扩展。其低成本、高实时性、高可靠性的特点,使得CAN不仅在汽车工业中广泛应用,还逐渐推广到工业自动化、医疗设备、轨道交通等多个领域。
CAN通信的主要特点
- 多主结构:
- CAN采用多主架构,即多个节点可以同时发送消息,避免了单一主设备的瓶颈。
- 无中心控制器:
- 所有节点均可自主发送和接收消息,通信无主从之分,减少了中心节点的依赖。
- 消息优先级和仲裁机制:
- 每个CAN消息帧都有一个独特的标识符(ID),当多个节点同时发送数据时,标识符优先级较高的消息会获得总线访问权,而不会引起冲突。
- 快速错误检测与恢复:
- CAN具有CRC校验、错误帧检测、自动重发等机制,能够实时检测到错误并自动恢复通信,保证数据传输的高可靠性。
- 短数据帧结构:
- 单个CAN数据帧最多可包含8字节的数据,虽然帧结构较小,但可以确保高实时性和低延迟。
- 传输速率:
- CAN通信的传输速率从10 kbps到1 Mbps不等,具体速率取决于应用场景和总线长度。
2.CAN数据帧的帧格式
CAN标准数据帧的帧格式
CAN标准数据帧(CAN 2.0A,11位标识符)的帧格式由以下几部分组成,每个部分的作用不同,具体字段如下:
-
起始位(SOF,Start of Frame):
- 1位。
- 表示数据帧的开始,是一个显性位(逻辑低电平),它标志着总线空闲状态的结束和数据传输的开始。
-
标识符(Identifier)(有些资料中称为仲裁字段):
- 11位。
- 用于表示数据帧的优先级和来源。标识符的优先级由数值大小决定,数值越小,优先级越高。在总线仲裁时,通过标识符的优先级确定哪个节点可以发送数据。
-
远程传输请求(RTR,Remote Transmission Request):
- 1位。
- 标识帧类型:
- 数据帧:此位为显性位(0)。
- 远程帧:此位为隐性位(1),表示请求某个节点发送数据。
-
控制位(Control Field):
- 6位:
- IDE(Identifier Extension Bit):1位,区分标准帧(11位ID)和扩展帧(29位ID)。对于标准帧,IDE为显性位(0)。
- 保留位(Reserved Bit):2位,保留为未来使用,默认为显性位(0)。
- 数据长度码(DLC,Data Length Code):4位,表示数据段的字节数,范围为0-8字节。
- 6位:
-
数据字段(Data Field):
- 0到8字节。
- 包含实际传输的数据,长度由DLC字段决定,最多8个字节。CAN标准帧的每个数据帧最多可以传输8字节的数据。
-
循环冗余校验(CRC,Cyclic Redundancy Check):
- 15位CRC字段和1位CRC定界符。
- 用于检测数据传输中的错误。发送端根据数据帧计算CRC校验码,接收端进行同样的计算并比较,确保数据的完整性。
-
应答字段(ACK,Acknowledgement Field):
- 2位:
- 1位ACK槽位:发送端将此位设置为隐性位(1),接收端在成功接收并验证帧后,将其设置为显性位(0),表示接收成功。
- 1位ACK定界符:固定为隐性位(1),用于标识ACK槽位结束。
- 2位:
-
结束帧(EOF,End of Frame):
- 7位。
- 表示数据帧的结束,全部为隐性位(逻辑高电平)。
CAN标准数据帧的帧格式结构图
- 仲裁机制:CAN总线上的每个节点通过发送标识符进行仲裁,标识符越小,优先级越高。
- 高可靠性:通过CRC校验和ACK应答机制确保数据的正确传输和接收。
- 实时性:通过短帧设计(最多8字节数据)和仲裁机制,实现快速的数据传输,特别适合汽车和工业应用中要求低延迟的场景。
CAN扩展帧的帧格式
扩展数据帧(CAN 2.0B)和标准数据帧(CAN 2.0A)的主要区别在于标识符的长度以及相应的控制字段变化。扩展数据帧允许使用更长的标识符,用于更复杂的应用场景
标识符长度
- 标准数据帧:
- 标识符长度为11位。
- 11位标识符可以表示的范围是0x000到0x7FF(0到2047),共2048个不同的标识符。
- 扩展数据帧:
- 标识符长度为29位,由11位基标识符和18位扩展标识符组成。
- 29位标识符可以表示的范围是0x00000000到0x1FFFFFFF(0到536870911),共536870912个不同的标识符。
IDE位(Identifier Extension Bit)
- 标准数据帧:
- IDE位为显性位(0),表示这是一个标准帧。
- 扩展数据帧:
- IDE位为隐性位(1),表示这是一个扩展帧。
标识符的结构
- 标准数据帧:
- 只有一个11位标识符。
- 扩展数据帧:
- 包含一个11位的基标识符,加上18位的扩展标识符,总计29位标识符。
在仲裁过程中,标准数据帧的优先级高于扩展数据帧,因为在IDE位的比较中,显性位(0)比隐性位(1)优先。
CAN遥控帧的帧格式
遥控帧(Remote Frame)是CAN通信协议中的一种帧类型,用于请求其他节点发送指定标识符的数据帧。与数据帧不同,遥控帧不携带数据,它只包含发送方希望接收的数据类型的标识符。当一个节点发送遥控帧后,拥有相同标识符的节点会响应并发送相应的数据帧。
遥控帧的作用:
- 请求数据:某个节点通过发送遥控帧请求其他节点发送特定标识符的数据帧。
- 通信控制:用于控制特定标识符的数据传输,而无需占用过多带宽。
遥控帧和数据帧的区别:
- 数据帧:包含数据字段,并将实际数据传输给接收节点。
- 遥控帧:没有数据字段,仅用来请求特定标识符的数据。
遥控帧的帧格式:
遥控帧的帧结构与标准数据帧和扩展数据帧的格式基本相同,唯一的区别是遥控帧的RTR(Remote Transmission Request)位设为隐性位(1),表示这是一个遥控帧,而不是数据帧。
CAN错误帧的帧格式
错误帧是CAN总线中的一种特殊帧,用于标识和通知总线上的节点发生了传输错误。与普通的数据帧或遥控帧不同,错误帧不会携带数据,而是通过特定的信号让总线上的其他节点知道出现了错误。
错误帧与普通数据帧的区别
-
目的不同:
- 数据帧:用于在节点之间传递实际的数据。
- 错误帧:用于通知总线中的所有节点出现了传输错误,要求丢弃当前传输,触发重新传输。
-
帧结构不同:
错误帧与数据帧的结构完全不同,它包含以下两个主要部分:- 主动错误标志或被动错误标志
- 错误定界符
错误帧由两个部分组成:
-
错误标志(Error Flag):
- 分为主动错误标志和被动错误标志。
- 主动错误标志:发送方发送6个连续的显性位(逻辑0)。任何主动错误的节点都可以发送这个标志,用于通知错误发生。
- 被动错误标志:发送方发送6个连续的隐性位(逻辑1)。当节点进入被动错误状态时,会发送此标志,而不是显性位。
-
错误定界符(Error Delimiter):
- 8个隐性位(逻辑1)。
- 用于标识错误帧的结束,并确保错误帧与后续的数据帧之间有明确的分界。
-
主动错误帧(Active Error Frame):
当节点检测到错误并处于主动状态时,发送主动错误帧:
- 主动错误标志:由6个**显性位(0)**组成,用于通知总线有错误发生。
- 错误定界符:8个隐性位(1),用于标志错误帧结束。
主动错误帧格式:
| Active Error Flag (6显性位) | Error Delimiter (8隐性位) |
-
被动错误帧(Passive Error Frame):
当节点进入被动错误状态时,发送被动错误帧:
- 被动错误标志:由6个**隐性位(1)**组成,表示节点进入被动错误状态。
- 错误定界符:8个隐性位(1),与主动错误帧相同。
被动错误帧格式:
| Passive Error Flag (6隐性位) | Error Delimiter (8隐性位) |
错误帧的触发条件:
- 位错误(Bit Error):节点检测到在发送显性位(或隐性位)时总线状态与预期不符。
- 填充错误(Stuff Error):CAN总线规定,每连续5个相同的位后应插入一个相反的位作为填充位,如果填充位不正确,则触发错误。
- CRC错误(CRC Error):接收方计算的CRC校验码与数据帧中的CRC校验码不匹配。
- 帧格式错误(Form Error):帧的结构或定界符不符合CAN协议规定。
- 应答错误(ACK Error):发送方未检测到接收方的应答信号(ACK位没有被接收方拉低)。
3.CAN数据传输中的位填充
**位填充(Bit Stuffing)**是CAN(Controller Area Network)协议中的一种技术,用于确保总线上的同步性和避免长时间出现连续的相同电平,帮助接收方正确恢复时钟和位计时。
位填充的概念
- 在CAN通信中,每当发送方在数据流中检测到连续的5个相同的位(不论是显性位或隐性位),它会自动插入一个相反的位。
- 这个额外插入的位称为填充位(Stuff Bit)。
- 位填充适用于CAN帧的控制字段、数据字段、CRC字段等所有包含在帧中的位流,但不适用于固定长度的字段(例如帧的ACK、SOF、EOF等字段)。
示例:
假设在数据传输时,发送方发送的连续位流为11111
,在CAN总线上会自动插入一个填充位0
,传输的数据会变成111110
。如果发送的是00000
,则会插入一个1
,变成000001
。
位填充的作用
-
保持总线同步性:
- CAN总线使用的是非归零编码(NRZ,Non-Return to Zero),这种编码方式容易导致连续相同电平的位序列,进而使接收方无法检测位的边界,影响时钟同步。
- 通过位填充,CAN总线上可以定期产生电平变化,帮助接收节点正确同步时钟。
-
防止长时间的恒定电平:
- 如果CAN总线上的电平长时间保持不变,接收节点的时钟可能会失步,导致数据无法正确解析。
- 位填充强制在总线上插入反向电平,从而确保位流中的变化,增强信号可靠性。
-
错误检测:
- 接收方也按照同样的规则进行位填充判断,当接收到的数据中未按规则插入填充位,或者填充位错误时,接收方可以判定数据帧有错误,触发错误帧。
- 位填充错误是一种常见的CAN错误类型之一,被称为填充错误(Stuff Error)。
位填充的工作机制
-
发送过程:
- 发送方在发送帧时,自动检测每一段连续的5个相同的位。
- 如果连续5位相同,则在后面插入一个相反的位。
-
接收过程:
- 接收方接收到数据时,按照相同的规则检查填充位。
- 一旦检测到错误(如连续相同的位未插入反向位),则判定为填充错误。
位填充示例
假设发送方要发送一个二进制数据流01111110
,我们可以通过以下步骤看到位填充的过程:
发送前的数据:
01111110
位填充过程:
- 从左到右扫描位流,发现有连续5个1。
- 按照位填充规则,必须在
11111
后插入一个反向位0
。
发送后的数据:
0111110 0 10
这样,通过位填充,连续相同的位序列被打破,确保接收方能够保持同步。
位填充适用于CAN帧中的大多数部分,包括:
- 数据字段(实际数据位)
- CRC字段(校验位)
- 控制字段(例如标识符)
位填充不适用的部分:
- SOF(Start of Frame):帧的开始标志位,不进行位填充。
- ACK(Acknowledgment Field):用于确认接收到数据帧,也不进行填充。
- EOF(End of Frame):帧结束标志位,同样不进行位填充。