1. 目的 本文主要介绍一部分 CAN 协议层 。 2. CAN 简介 这里的内容参考的是 1991.9 的 2.0 版本的官方 CAN 规格书 。 2.1 概述 CAN (控制器局域网) 是一种串行通讯协议 ,传输速度可达 1Mbit/s 。总线由单一可双向信号传送的通道组成 ,但此通道的物理层在协议层中未定义 ,可使用诸如差分线 、光缆等实现通信 ,其是多主机控制 。 CAN 的地址范围由识别符定义 ,标准格式有 11 个识别符 ,扩展格式有 29 个识别符 。 总线有两种逻辑值 :"显性”和“隐性”。这两种同时传送时 ,总线传送的是 “显性”,通常我们用逻辑 0 代表 “显性”,逻辑 1 代表 “隐性”。 对于 CAN ,报文传输由以下 4 种帧类型表示和控制 : (1) 数据帧 :将数据从发送器发至接收器 ,数据帧优先级高于远程帧 (2) 远程帧 :发至总线 ,请求具有同一识别符的数据帧 (3) 错误帧 :任何单元检测到错误就发出错误帧 (4) 过载帧 :为前后的数据帧 / 远程帧之间提供一附加延时 2.2 数据帧 图 1 CAN 数据帧 如图 ,这是一帧数据帧 ,包含了帧起始 、仲裁域 、控制域 、数据域 、CRC 域 、应答域和帧结束 。 2.2.1 帧起始 (SOF) 由一个单独的“显性”位组成 。注意 :只有总线空闲才允许发送此信号 。 2.2.2 仲裁域 仲裁域包括识别符和远程发送请求位 (RTR) 。 (1) 标准格式中 :仲裁域由 11 位识别符和 RTR 位组成 。识别符位由 ID28~ID18 。如图2 。 (2) 扩展格式中 :仲裁域包括 29 位识别符 、SRR 位 、IDE 位 RTR 位 。识别符由 ID28~ID0 。 如图 3 。 这些识别符中最高七位必须不能全是 “隐性”。 RTR 位为远程发送请求位 ,在数据帧里为 “显性”,远程帧里为 “隐性”。 SRR 位为替代远程请求位 ,是一个 “隐性”位 。代替标准帧 RTR 位 (标准帧优先于扩展帧) 。 IDE 位为识别符扩展位 ,在标准帧里为 “显性”(此时在控制域) ,在扩展帧里为 “隐性”。 图 2 标准帧的仲裁域和控制域 图 3 扩展帧的仲裁域和控制域 2.2.3 控制域 由 6 位组成 ,如图 3 ,DLC 为数据长度 。其余皆为 “显性”。 2.2.4 数据域 数据帧允许 0~8 Byte ,最小单位为 Byte 。 2.2.5 CRC 域 由 CRC 序列与 CRC 界定符组成 ,如图 4 。 CRC 序列 15 位 ,CRC 界定符是一单独的 “隐性”位 。 图 4 CRC 域 2.2.6 应答域 (ACK 域) 由 2 个位组成 ,分别为应答间隙 (ACK SLOT) 和应答界定符 (ACK DELIMITER) 。在应答域里 ,发送端发送两个 “隐性”位 。 当接收端接收到有效报文 ,接收端就会在应答间隙 (ACK SLOT) 期间向发送端发送一 “显性”位以示应答 (即发送 ACK 信号) 。 图 5 应答域 应答间隙 :所有接收到匹配 CRC 序列的接收端会在应答间隙期间用一 “显性”的位写入发送端的 “隐性”位来做出应答 。 应答界定符 :必定为一 “隐性”位 。 2.2.7 帧结束 由7个 “隐性”位组成 。 2.3 远程帧 远程帧由帧起始 、仲裁域 、控制域 、CRC 域 、应答域 、帧结尾 。 远程帧与数据帧不同之处在于 :远程帧 RTR 位是 “隐性”的 ,且没有数据域故此数据长度代码 DLC 数值可为 0~8 ,因为其无意义 。 2.4 错误帧 由两个不同的域组成 ,第一个域是用不同节点提供的错误标志 (ERROR FLAG) 的叠加 。第二个域是错误界定符 ,如图 6 。 图 6 错误帧格式 为了正确终止错误帧 ,“错误被动”的节点要求总线至少有长度为 3 个位时间的总线空闲 。 有两种形式错误标志 ,如下 : (1) 主动错误标志 :由 6 个连续的 “显性”位组成 。 (2) 被动错误标志 :由 6 个连续的 “隐性”位组成 ,除非被其他节点 “显性”位重写 。 检测到错误条件的主动错误节点通过发送主动错误标志指示错误 ,错误标志的形式破坏了从帧起始到 CRC 界定符的位填充规则 ,或者破坏了 ACK 域或帧结尾场的固定形式 。所有其他节点由此检测到错误条件并同时其中一部分发送错误标志 。“显性”位的序列由此导致了个别节点发送的不同的错误标志叠加在一起 。这个序列的总长度最小为 6 位 ,最长为 12 位 。 检测到错误的被动错误节点尝试发送被动错误标志指示错误 。开始被动错误标志后 ,“被动错误”的节点等待 6 个相同极性的连续位 。当此 6 个相同的位被检测到 ,被动错误标志发送完成 。 错误界定符 :包括 8 个 “隐性”位 。错误标志传送以后 ,节点就发送 “隐性”位并一直监视总线出现 “隐性”位 ,然后发送其他 7 个 “隐性”位 。 2.5 过载帧 由两个域组成 :过载标志和过载界定符 。 有三种情况会引发过载标志传送 : (1) 接收端内部情况 (此接收端对下一个数据帧或远程帧要有一延时) 。 (2) 在间歇的第一和第二字节检测到一个 “显性”位 。 (3) 如果 CAN 节点在错误界定符或过载界定符的第 8 位 (最后一位) ,采样到一 “显性”位 ,节点会发送一个过载帧 ,错误计数器不增加 。 情况 1 引发的过载帧只允许起始于所期望的间歇的第一个位时间 ,情况 2 和情况 3 引发的过载帧应起始于所检测到 “显性”位之后的位 。 过载标志 :由 6 个 “显性”的位组成 。其所有形式与主动错误标志一样 。 过载界定符 :与错误界定符一样 。 图 7 过载帧格式 2.6 帧间空间 数据帧 / 远程帧与先行帧 (无论那种帧类型) 的隔离是通过帧间空间实现的 。 帧间空间包括间歇 、总线空闲这两个域 。如果 “被动错误”的节点已作为前一报文的发送端 ,帧空间还包括了挂起传送的域 ,如图 8 和图 9 。 图 8 帧间空间 (无挂起传送) 图 9 帧间空间 (有挂起传送) 间歇 :包括 3 个 “隐性”位 。间歇期间 ,所有节点不可传送数据帧或远程帧 (过载帧需注意第二种情况) 。如果有报文等待发送且节点在间歇第三位采集到 “显性”位 ,则此位被解释为帧的起始 。 总线空闲 :总线空闲是阿金任意 。若在其他报文发送期间 ,有报文被挂起 ,则会在间歇之后第一位发送 。 挂起传送 :在下一个报文开始传送或者总线空闲之前发出 8 个 “隐性”的位跟随在间歇的后面 。 2.7 仲裁与优先权 总线空闲时 ,任何节点都可以传送报文 ,任何节点都可以接收报文 (多播) ,具有较高优先权的报文可获得总线访问权 。(注意 :由于有报文滤波 ,即对于识别符有掩码 ,) 仲裁即在多个节点同时传送报文时 ,针对总线访问冲突的解决方法 。仲裁期间 ,每一个节点都对发送位的电平与被监控的总线电平进行比较 ,电平相同 ,则这个单元可以继续发送 ,如果不一致 ,则该节点仲裁失败 ,必须退出发送状态 。 2.8 编码 位流编码 :数据帧与远程帧的帧起始 、仲裁域 、控制域 、数据域 、CRC 序列 ,发送端只要检测到位流里有 5 个连续相同值的位 ,便自动在位流里插入一互补位 (即与连续相同值反相的逻辑电平) ,其余的 CRC 界定符 、 应答域和帧结尾还有错误帧和过载帧都不填充 。要注意 :填充的位在解析时要去掉 。 2.9 错误处理 有以下五种错误类型 (不会相互排斥) : (1) 位错误 :除了在仲裁域的填充位流期间 (即等仲裁域结束) 或应答域的应答间隙期间发送 “隐 性”位和发送被动错误标志期间 ,其余时间如果发送值与监视值不一致时 ,则此位时间检测到一个位错误 。 (2) 填充错误 :如果需要位填充的信息中检测到连续 6 个相同的值 ,则出现填充错误 。 (3) CRC 错误 :如果接收端计算的 CRC 序列与发送端发送的 CRC 序列不符合 ,发生 CRC 错误 (4) 形式错误 :当一个固定形式的位域含有 1 或多个非法位,检测到形式错误 (5) 应答错误 :只要应答域应答间隙不为 “显性”,检测到应答错误 2.9.1 故障界定 每个节点状态可能为以下三个状态 : (1) 错误主动 :正常参与总线通讯并可发出主动错误标注 (2) 错误被动 :可参与总线通讯 ,但只能发送被动错误标志 ,发送后 ,在下一次发送前处于等待 状态 (见挂起发送) 。 (3) 总线关闭 :不允许对总线有任何影响 界定节点是哪种状态 ,用到了以下两种计数 : (1) 发送错误计数 (2) 接收错误计数 这两个按照以下规则改变 : (1) 接收端检测到一个错误 ,接收错误计数加一 。发送主动错误标志或过载标志期间的位错误 ,接 收错误计数器值不加一 (2) 错误标志发送后 ,接收端检测到第一位为 “显性”时 ,接收错误计数值加 8 (3) 发送端发送错误标志时 ,发送错误计数值加 8 ,以下为例外情况 : 例外情况一 : 发送端为 “被动错误”,并检测到应答错误 (注 :此应答错误由检测不到“显性”应答和发送被动错误标志是检测不到“显性”位引起) 例外情况二 : 发送端因为填充错误而发送错误标志 (注 :此填充错误发生于仲裁期间 ,引起填充错误是由于 填充位位于 RTR 之前 ,并已经作为 “隐性”发送 ,但监视总线为 “显性”) (4) 发送主动错误标志或过载标志时 ,如果发送端检测到位错误 ,发送错误计数加 8 (5) 发送主动错误标志或过载标志时 ,如果接收端检测到位错误 ,接收错误计数加 8 (6) 在发送主动错误标志 、被动错误标志或过载标志后 ,任何节点最多容许 7 个连续的 “显性” 位 。以下情况 ,每一发送端的发送错误计数加 8 ,每一接收端错误计数加 8 : 当检测到第 14 个连续的 “显性”位之后 (在发生主动错误标志或过载标志的情况下) 被动错误标志之后检测到第 8 个连续的 “显性”之后 每一个补充的 8 个连续 “显性”位序列之后 (7) 报文传输成功 ,应答无错 ,帧结束无措 ,发送错误计数器减一 ,除非其为零 (8) 如果接收错误计数介于 1 和127 之间 ,成功接收到报文后 ,及时发送出应答 ,接收错误计 数减一 ,为零则继续为零 ,如果超过 127 ,则设置为一个在 119~127 间的一个值 (9) 发送 / 接收错误计数等于或大于 128 ,节点变为被动错误节点 。造成节点这种转变的错误条 件发出主动错误标志 (10) 发送错误计数等于或大于 256 ,节点为总线关闭 (11) 发送 / 接收错误计数小于 128 ,节点重新变为错误主动节点 (12) 总线监视到 128 次有 11 个连续 “隐性”位之后 ,总线关闭节点转为错误主动节点 ,错误 计数设为 0 2.10 位时间 标称比特率 :标称比特率是理想发送端在没有重新同步的情况下每秒传输的位数。 标称位时间 := 1 / 标称比特率 ,即位的持续时间 ,如位时间是 0.2 μs ,则这个时间段内全是这个位所代表的电平 (全是 “隐性”或 “显性”) 可以将标称位时间视为划分为单独的非重叠时间段。 这些划分 : (1) 同步段 (SYNC_SEG) :同步总线不同节点 ,这一段有个跳边沿 (2) 传播时间段 (PROP_SEG) :补偿网络内物理延时时间 ,是总线上输入比较器延时和输出驱动器 延时综合的两倍 (3) 相位缓冲段 1 (PHASE_SEG1) :用于补偿边沿阶段误差 ,可通过重新同步加长或缩短 (4) 相位缓冲段 2 (PHASE_SEG2) :用于补偿边沿阶段误差 ,可通过重新同步加长或缩短 图 10 位时间 采样点 :读总线电平并认为是每个位的值的一个时间点 信息处理时间 :以采样点位起始时间段 ,采样点用于计算后续位的位电平 时间份额 :派生于振荡器周期的固定时间单元 。存在一个可编程预比例因子 ,整体数值范围为 1~32 。时间份额 = m * 最小时间份额 (m 为预比例因子) 时间段长度 :同步段为 1 个时间份额 ,传播段长度可设置为 1~8 个时间份额 ,相位缓冲段 1 长度可设置为 1~8 个时间份额 ,相位缓冲段 2 为相位缓冲段 1 和信息处理时间之间最大值 ;信息处理时间小于或等于 2 个时间份额 。即一个位时间总时间份额可设置为 8~25 的范围 。 2.11 同步 2.11.1 硬同步 硬同步后 ,接收端的内部位时间从同步段重新开始 ,即跳变沿处于重新开始的位时间同步段之内 。 2.11.2 重新同步 位时间相位误差 : 一个沿的相位误差由相对于同步段的跳边沿出现的位置给出 ,以时间份额量度 。相位误差定义如下 : e=0 跳边沿处于同步段里 e>0 跳边沿处于同步段之后 ,采集点之前 e<0 跳边沿处于同步段之前 ,上一个采集点之后
图 11 接收端位定时与同步
(注 :S 是同步段 ,P 是传播时间段 ,P1 是相位缓冲段 1 ,P2 是相位缓冲段 2) 重新同步结果 ,可能引起当前位相位缓冲段 1 增长或相位缓冲段 2 缩短 ,但这个增量有一个上限 ,就是由重新同步跳转宽度 (SJW)给出 。SJW 应设置在 1 和最小值 (4 和 相位缓冲段1中的最小值) 之间 。 当前位定时出现 e≠0 时 ,若相位误差不大于 SJW ,则 e>0 ,当前位时间的相位缓冲段 1 增加相位误差的绝对值个时间份额 e<0 ,当前位时间的相位缓冲段 2 减少相位误差的绝对值个时间份额 这里其实与硬同步的作用相同 。但若相位误差大于 SJW ,则增加或减少的时间份额就为 SJW 个 。 同步原则 : ① 在一个位时间里只允许一个同步 。 ② 仅当采集点之前监测到的值与紧跟沿之后的总线值不相符合时 ,才将沿用作与同步 。 ③ 总线空闲期间 ,有一“隐形”转变到 “显性”的沿 ,无论何时 ,硬同步都会被执行 。 ④ 如果仅将 “隐性”转变为 “显性”的沿用作与重新同步 ,则其他符合规则 1 和规则 2 的从 “隐性”转变为 “显性”的沿可用作为重新同步 。但有一例外情况 : 当发送一显性位的节点不执行重新同步而导致 “隐性”转变为 “显性”沿 ,此沿具有正相位误差 ,不能作为重新同步使用 。 4. 参考资料 百度文库 :《CAN 20 A B 标准》 下载链接 : https://wenku.baidu.com/view/549e1e15d4d8d15abf234e37.html