## CAN总线 ### 1. 什么是CAN总线? CAN - 英文Controller Area Network(控制器局域网)的缩写,是一种串行的车辆总线标准,旨在允许微控制器和设备在没有主机的情况下与彼此的应用程序进行通信。它专为比较恶劣的环境下还能够保持可靠且灵活的性能而设计,比较适合于工业和汽车领域。 CAN总线最早是由Bosch发明,后成了标准ISO11898-1,它定义了开放系统互联模型(OSI)中的数据链路和物理层,为高速车内通信提供了一种底层的网络方案。值得一提的是,CAN被设计为减少电缆的连线,因此车内不同的电气控制单元(ECUs)可以通过只有一对电缆进行通信。 {{ ::can-subnetwork.png |}} 车载诊断 (OBD) 是车辆的诊断和报告系统,帮助技术人员通过诊断故障代码 (DTC) 排除问题。 当“检查发动机”灯亮起时,技术人员通常会使用手持设备读取车辆的发动机代码。 在最低层,该数据通过信令协议传输,大多数情况下是使用CAN总线。 DeviceNet是工业应用中使用的高级网络协议。 它大大减少了控制系统和I/O设备之间所需的接线。 设备可以通过四线连接器连接在一起并连接到 PLC 上的网络扫描仪,而不是将每个设备连接到 PLC I/O 模块上的单独输入/输出。 在最低层,我们发现CAN在DeviceNet协议中发挥着其魔力。 图 2 显示了PLC扫描通过DeviceNet进行通信的工业设备网络。 {{ ::can11.png?800 |}} {{ :f31de3f79dde8fa51181c78b18d77c04.jpg |}} CAN总线采用双绞线提供抗共模干扰能力强的差分信号传输,线的两端分别接有120欧的电阻,每个模块都有两个脚分别连在这两根线上,对于每个模块的内部,都包含一个CAN收发器。 CAN总线一般分为低速和高速,低速CAN传输速率<125kbps, 高速CAN传输速率<1Mbps,目前还有一种CAN FD可以视为CAN的升级版,传输速率<5Mbps。 {{ ::can10.png?800 |}} {{ ::can13.png?800 |}} ### 2. CAN消息帧 那么CAN消息实际上是什么样子的呢? 最初的ISO标准制定了所谓的标准CAN。 标准CAN对不同的报文使用11位标识符,总共有211个,即2048个不同的报文ID。 CAN后来做了修改,标识符扩展为29位,得到229个标识符。 这称为扩展 CAN。 CAN使用多主总线,所有消息都在整个网络上广播。 标识符提供仲裁的消息优先级。 {{ :can_packetstructureframes_1.png |}} CAN使用具有两种逻辑状态的差分信号,称为隐性和主导。 隐性状态表示差分电压小于最小阈值电压。 主导状态指示差分电压大于此最小阈值。 有趣的是,主导状态是通过将逻辑“0”驱动到总线上来实现的,而隐性状态是通过逻辑“1”来实现的。 这与大多数系统中使用的传统高和低相反。 重要的是,在仲裁过程中,主导状态优先于隐性状态。 #### 标准CAN 标准CAN消息帧由许多位字段组成。 这些如图3所示。 {{ ::can3.png?800 |}} 第一位是帧开始 (SOF)。 该主导位代表CAN消息的开始。 接下来是11位标识符,它确定CAN消息的优先级。 标识符越小,消息的优先级越高。 远程传输请求(RTR)位通常为主导位,但当一个节点向另一节点请求数据时,该位会变为隐性。 当发送标准CAN帧而非扩展帧时,标识符扩展(IDE)位占主导地位。 r0 位被保留,当前未使用。 数据长度代码 (DLC) 半字节表示此消息中有多少个数据字节。 接下来是数据本身,其字节数与 DLC 位中表示的字节数相同。 循环冗余校验 (CRC) 是一个 16 位校验和,用于检测传输数据中的错误。 如果消息被正确接收,接收节点将用显性位覆盖隐性确认位 (ACK)。 ACK 还包含一个分隔符位以保持同步。 帧结束 (EOF) 表示 CAN 消息的结束,为 7 位宽,用于检测位填充错误。 CAN 消息的最后一部分是帧间空间 (IFS),用作时间延迟。 该时间延迟正是 CAN 控制器将接收到的消息移至缓冲区以进行进一步处理所需的时间量。 #### 扩展CAN 扩展CAN使用29位标识符以及一些附加位。 扩展消息在11位标识符后面有一个替代远程请求 (SRR) 位,它充当占位符以保持与标准CAN相同的结构。 这次标识符扩展(IDE)应该是隐性的,表示后面跟着扩展标识符。 RTR 位位于 18 位 ID 之后,后面是第二个保留位 r1。 消息的其余部分保持不变。 {{ ::can4.png?800 |}} FlexCAN是一种CAN总线的扩展,它是一种嵌入式网络架构,由凯特林大学的胡安·皮门特尔博士设计的,它的灵感来自于FlexRay以及通过CAN网络提供更具确定性行为的需求。 其重点是硬件级别的冗余以及协议级别基于时间的优先通信。 关于FlexCAN参见文章FlexCAN: [[https://paws.kettering.edu/~jpimente/flexcan/FlexCAN-architecture.pdf|A Flexible Architecture for Highly Dependable Embedded Application]] #### CAN消息类型 CAN允许四种不同的消息类型。 它们是数据帧、远程帧、过载帧和错误帧。 标准CAN数据帧使用标识符、数据和数据长度代码、循环冗余校验和确认位。 RTR和IDE位在数据帧中均占主导地位。 如果接收端的隐性确认位被显性位覆盖,则发送器和接收器都认为这是成功的传输。 CAN远程帧看起来与数据帧类似,只是它不包含任何数据。 发送时RTR位处于隐性状态,这表明它是一个远程帧。 远程帧用于从节点请求数据。 当节点检测到CAN总线上的消息中存在错误时,它会发送错误帧。 这会导致所有其他节点发送错误帧。 此后,发生错误的节点重新传输该消息。 过载帧的工作原理类似,但当节点接收帧的速度快于处理帧的速度时使用。 该帧提供了时间缓冲区,以便节点可以赶上。 ### 3. 总线仲裁及信令 CAN 是一种 CSMA/CD 协议,这意味着总线上的每个节点都可以检测冲突并在尝试重新传输之前后退一定时间。 这种冲突检测是通过基于消息标识符的优先级仲裁来实现的。 在讨论仲裁之前,让我们仔细看看 CAN 总线上使用的显性位和隐性位。 #### 反相逻辑 CAN 总线的一个有趣的方面是它使用具有两种状态(显性状态和隐性状态)的反转逻辑形式。 下面的图 5 显示了 CAN 收发器输出和输入的简化版本。 “101”比特流来自/去往 CAN 控制器和/或微控制器。 请注意,当控制器发送位流时,这些位流会被补充并放置在 CANH 线上。 CANL 线始终是 CANH 的补充。 为了使仲裁正常工作,CAN 设备必须监控它正在发送的内容以及当前总线上的内容,即它正在接收的内容。 {{ ::can5.png?800 |}} 图 6 同时显示了 CANH 和 CANL 信号,以便您可以看到 CAN 总线的运行情况。 总线信号下方绘制的是与 CAN 信号的显性和隐性状态相对应的差分电压。 时间上的前三个段 t1–t3 被绘制为与图 5 中所示的三个位相匹配。我们将从输出驱动器的角度来看待这一点。 驱动器的输入最初看到“1”,并将其补为零,然后将其放置在 CANH 上。 CANL 看到 CANH 的补码并走高。 这如图 6 中的 t1 所示。请注意,CANH 和 CANL 电压彼此偏移。 在时间 t1 期间,CANH – CANL 非常接近于零,因为 CANH 和 CANL 的电压几乎相同。 驱动器发送逻辑“1”导致 CANH 和 CANL 接近相同电压的这段时期,就是我们所说的 CAN 隐性状态。 发送的下一位是“0”。 CANH 得到其补码,CANL 再次得到 CANH 的补码。 请注意,这次 CANH 和 CANL 电压并不接近。 因此,差分电压(VDIFF)较大。 这是 CAN 主导状态。 我们说逻辑是颠倒的,因为“1”使总线处于低电平,而“0”则使总线处于高电平。 输入接收器以类似的方式工作。 {{ ::can6.png?500 |}} #### 优先级仲裁 正如前面提到的,11 位标识符越小,消息的优先级就越高。 节点传输的每一位都会受到监控。 这就是节点检测总线上正在放置更高优先级消息的方式。 当节点发送隐性位但在总线上检测到显性位时,它就会后退。 这称为非破坏性仲裁,因为胜出的消息将继续传输,没有任何问题。 请注意,隐性逻辑“1”输给了显性逻辑“0”。 这是有道理的,因为较低的标识符值代表较高的优先级。 为了更好地了解这意味着什么,请查看图 7,其中显示了 CAN 总线上尝试控制的三个节点。 请务必记住,每次显示隐性位时,控制器都会发送“1”,而显性位对应于发送“0”。 节点 1-3 都在发送比特流。 该位流代表消息标识符及其优先级。 首先,所有三个节点均发送“1”,该值在 CAN 总线上表示为隐性位。 接下来,每个节点发送“0”或显性位。 总线上放置的第三位是另一个“1”,或隐性位。 此时,没有一个节点检测到与总线上的另一个节点有任何冲突,因此它们继续传输。 对于第四位,节点 1 发送“0”或显性位。 节点 2 传输隐性位,但检测总线上的显性位。 它立即后退,知道当前正在发送更高优先级的消息。 节点 3 继续发送,因为它读回了与发送的相同的显性位。 当第五位被放置在总线上时,节点 3 就会识别出它的优先级较低并停止传输。 节点 2 和节点 3 都会等待一定时间,然后再次尝试。 如图 7 的右半部分所示,节点 3 赢得了仲裁。 正如您所看到的,与较低消息标识符相对应的逻辑“0”显性位允许进行仲裁。 {{ ::can7.png?800 |}} ### 4. CAN总线控制器和收发器 #### CAN控制器 CAN控制器用于将欲收发的消息(报文),转换为符合CAN规范的CAN帧,通过CAN收发器,在CAN-bus上交换信息。 CAN控制器芯片分为两类: * 独立的控制器芯片,如SJA1000 * CAN控制器集成在微控制器中,如NXP半导体公司的Cortex-M0内核LPC11Cxx系列微控制器、LPC2000系列32位ARM微控制器。 CAN控制器工作原理图 - 接口管理逻辑: 用于连接外部主控制器,解释来自主控制器的命令,控制CAN控制器寄存器的寻址,并向主控制器提供中断信息和状态信息。 - CAN核心模块:收到一个报文时,CAN核心模块根据CAN规范将串行位流转换成用于接收的并行数据,发送一个报文时则相反。 - 发送缓冲器:用于存储一个完整的报文,当CAN控制器发送初始化时,接口管理逻辑会使CAN核心模块从发送缓冲器读CAN报文。 - 验收滤波器:可以根据用户的编程设置,过滤掉无须接收的报文。 - 接收FIFO:是验收滤波器和主控制器之间的接口,用于存储从CAN 总线上接收的所有报文。 - 工作模式:CAN控制器可以有两种工作模式(BasicCAN和PeliCAN)。BasicCAN仅支持标准模式,PeliCAN支持CAN2.0B的标准模式和扩展模式 #### CAN收发器 CAN收发器是CAN控制器和物理总线之间的接口,将CAN控制器的逻辑电平转换为CAN总线的差分电平,在两条有差分电压的总线电缆上传输数据。 CAN收发器的类型 汽车车载网络CAN收发器也分为独立型与组合型两大类。由于前者应用灵活,可以与多种CAN控制器进行连接使用,故应用最广泛。后者通常与CAN控制器组合在一起,形成一个具有CAN收发功能的CAN控制器组件。 ### 5. 总结 CAN是一种强大的串行通信总线,主要用于汽车和工业环境。 它使用差分信号,具有更强的抗噪声能力,并采用优先仲裁方案来实现无损消息传输。 CAN非常适合处于危险环境或存在大量电磁干扰的区域的嵌入式应用。 {{ ::can8.png?800 |}} {{ ::can9.png?800 |}} {{ ::can12.png?800 |}} {{ ::can14.png?800 |}}