本文最后更新于 43 天前,其中的信息可能已经过时,如有错误请留言评论。
- 全称 Controller Area Network,控制器局域网
- 异步
- 串行
- 多主、竞争、广播
- 差分信号,一般使用双绞线
- 半双工
- 用于控制器间通讯
- 高性能、高可靠、实时性
- 逻辑 0,显性,CANH = 3.5V、CANL = 1.5V、Vdiff = 2V
- 逻辑 1,隐性,CANH = 2.5V、CANL = 2.5V、Vdiff = 0V
- 总线空闲时为隐性状态
- 数据帧:用于发送单元向接收单元传送数据的帧
- 远程帧:用于接收单元向具有相同 ID 的发送单元请求数据的帧
- 错误帧(硬件自动完成):当 CAN 节点检测到错误时发送,用于通知网络上的其他节点存在错误
- 过载帧(硬件自动完成):当 CAN 节点无法在当前的波特率下处理接收到的数据时发送
- 帧间隔(硬件自动完成):用于将数据帧及远程帧与前面的帧分离开来的帧
- SOF(Start of Frame):帧起始,表示后面一段波形为传输的数据位
- ID(Identify):标识符,区分功能,同时决定优先级,分为标准格式(11 位)和扩展格式(29 位)
- RTR(Remote Transmission Request):远程请求位,区分数据帧和远程帧
- IDE(Identifier Extension):扩展标志位,区分标准格式和扩展格式
- SRR(Substitute Remote Request):替代 RTR,协议升级时留下的无意义位
- r0/r1(Reserve):保留位,为后续协议升级留下空间
- DLC(Data Length Code):数据长度,指示数据段有几个字节
- Data:数据段的 1~8 个字节有效数据
- CRC(Cyclic Redundancy Check):循环冗余校验,校验数据是否正确
- ACK(Acknowledgement):应答位,判断数据有没有被接收方接收
- CRC/ACK 界定符:为应答位前后发送方和接收方释放总线留下时间
- EOF(End of Frame):帧结束,表示数据位已经传输完毕
- 总线上所有设备都会监督总线的数据,一旦发现 “位错误” 或 “填充错误” 或 “CRC 错误” 或 “格式错误” 或 “应答错误”,这些设备便会发出错误帧来破坏数据,同时终止当前的发送设备
- 当接收方收到大量数据而无法处理时,其可以发出过载帧,延缓发送方的数据发送,以平衡总线负载,避免数据丢失
- 将数据帧和远程帧与前面的帧分离开
- 3 位的帧间隔配合 7 位的 EOF 和 8 位的错误 / 过载界定符,可以实现更复杂的优先级控制策略(任何设备检测到连续 11 个隐性电平,即认为总线空闲)
- 规则:发送方每发送 5 个相同电平后,自动追加一个相反电平的填充位,接收方检测到填充位时,会自动移除填充位,恢复原始数据
即将发送 | 100000110 | 10000011110 | 0111111111110 |
实际发送 | 1000001110 | 1000001111100 | 011111011111010 |
实际接收 | 1000001110 | 1000001111100 | 011111011111010 |
移除填充后 | 100000110 | 10000011110 | 0111111111110 |
- 作用
- 增加波形的定时信息,利于接收方执行 “再同步”,防止波形长时间无变化导致接收方不能精确掌握数据采样时机
- 将正常数据流与 “错误帧” 和 “过载帧” 区分开,标志 “错误帧” 和 “过载帧” 的特异性
- 保持 CAN 总线在发送正常数据流时的活跃状态,防止被误认为总线空闲
- 先占先得
- 若当前已经有设备正在操作总线发送数据帧 / 远程帧,则其他任何设备不能再同时发送数据帧 / 远程帧(可以发送错误帧 / 过载帧破坏当前数据)
- 任何设备检测到连续 11 个隐性电平,即认为总线空闲,只有在总线空闲时,设备才能发送数据帧 / 远程帧
- 一旦有设备正在发送数据帧 / 远程帧,总线就会变为活跃状态,必然不会出现连续 11 个隐性电平,其他设备自然也不会破坏当前发送
- 若总线活跃状态其他设备有发送需求,则需要等待总线变为空闲,才能执行发送需求
- 非破坏性仲裁
- 若多个设备的发送需求同时到来或因等待而同时到来,则 CAN 总线协议会根据 ID 号 (仲裁段) 进行非破坏性仲裁,ID 号小的 (优先级高) 取到总线控制权,ID 号大的 (优先级低) 仲裁失利后将转入接收状态,等待下一次总线空闲时再尝试发送
- 实现非破坏性仲裁需要两个要求
- 线与特性:总线上任何一个设备发送显性电平 0 时,总线就会呈现显性电平 0 状态,只有当所有设备都发送隐性电平 1 时,总线才呈现隐性电平 1 状态,即 0&X&X=0、1&1&1=1
- 回读机制:每个设备发出一个数据位后,都会读回总线当前的电平状态以确认自己发出的电平是否被真实的发送出去了,根据线与特性,发出 0 读回必然是 0,发出 1 读回不一定是 1
- 举例
- 数据位从前到后依次比较,出现差异且数据位为 1 的设备仲裁失败
错误类型 | 错误条件 | 检测位置 | 检测单元 |
---|
位错误 | 比较输出电平和总线电平(不含填充位),两电平不一样 | 数据帧(SOF-EOF)远程帧(SOF-EOF)错误帧过载帧 | 发送单元接收单元 |
填充错误 | 在需要位填充的段内,连续检测到 6 位相同的电平 | 数据帧(SOF-CRC)远程帧(SOF-CRC) | 发送单元接收单元 |
CRC 错误 | 从接收到的数据计算出的 CRC 结果与接收到的 CRC 不同 | 数据帧(CRC)远程帧(CRC) | 接收单元 |
格式错误 | 检测出与固定格式的位段相反的格式 | 数据帧(CRC 界定符、ACK 界定符、EOF)远程帧(CRC 界定符、ACK 界定符、EOF)错误帧过载帧 | 接收单元 |
应答错误 | 发送单元在 ACK 中检测出隐性电平(ACK 没被传送过来) | 数据帧(ACK)远程帧(ACK) | 发送单元 |
- 每个设备内部管理一个 TEC 和 REC,根据 TEC 和 REC 的值确定自己的状态
- 主动错误状态的设备,正常参与通信并在检测到错误时发出主动错误标志
- 被动错误状态的设备,正常参与通信但检测到错误时只能发出被动错误标志
- 总线关闭状态 busoff 的设备,不能参与通信
| 接收和发送错误计数值的变动条件 | 发送错误计数值(TEC) | 接收错误计数值(REC) |
---|
1 | 接收单元检测出错误例外:接收单元在发送错误标志或过载标志中检测出 “位错误” 时,接收错误计数值不增加。 | – | +1 |
2 | 接收单元在发送完错误标志后检测到的第一个位为显性电平 | – | +8 |
3 | 发送单元在输出错误标志 | +8 | – |
4 | 发送单元在发送主动错误标志或过载标志时,检测出位错误 | +8 | – |
5 | 接收单元在发送主动错误标志或过载标志时,检测出位错误 | – | +8 |
6 | 各单元从主动错误标志、过载标志的最开始检测出连续 14 个位的显性位之后,每检测出连续的 8 个位的显性位 | 发送时 + 8 | 接收时 + 8 |
7 | 检测出在被动错误标志后追加的连续 8 个位的显性位时 | 发送时 + 8 | 接收时 + 8 |
8 | 发送单元正常发送数据结束时 (返回 ACK 且到帧结束也未检测出错误时)。 | -1TEC=0 时 TEC=0 | – |
9 | 接收单元正常接收数据结束 (到 CRC 未检测出错误且正常返回 ACK) | – | 1≤REC≤127 时 - 1 REC=0 时 REC=0 REC>127 时 REC=127 |
10 | 处于总线关闭态的单元,检测到 128 次连续 11 个位的隐性位 | TEC=0 | REC=0 |
- 为了灵活调整每个采样点的位置,使采样点对齐数据位中心附近,CAN 总线对每一个数据位的时长进行了更细的划分,分为同步段(SS)、传播时间段(PTS)、相位缓冲段 1(PBS1)和相位缓冲段 2(PBS2),每个段又由若干个最小时间单位(Tq)构成
- 波特率 = 1 / 数据位时间 = 1 / (TSS + TPTS + TPBS1 + TPBS2) = 1 / (TSync + TTSEG1 + TTEGS2)
- 采样点 = (TSS + TPTS + TPBS1) / (TSS + TPTS + TPBS1 + TPBS2) * 100% = (TSync + TTSEG1) / (TSync + TTSEG1 + TTEGS2) * 100%
位时间参数 (500Kbps) |
时间份额数 (TQ) | 时间段 1 (TSEG1 = TPTS + TPBS1) | 时间段 2 (TSEG2 = TPBS2) | 同步跳转带宽 (SJW) | 采样点 (Sample Point) | 采样次数 |
16 | 12 | 3 | 3 | 81.25% | 1 |
20 | 15 | 4 | 4 | 80.00% | 1 |
15 | 11 | 3 | 3 | 80.00% | 1 |
位时间参数 (250Kbps) |
时间份额数 (TQ) | 时间段 1 (TSEG1 = TPTS + TPBS1) | 时间段 2 (TSEG2 = TPBS2) | 同步跳转带宽 (SJW) | 采样点 (Sample Point) | 采样次数 |
16 | 13 | 2 | 1 | 87.5% | 1 |
20 | 16 | 3 | 1 | 85% | 1 |
- 每个设备都有一个位时序计时周期,当某个设备(发送方)率先发送报文,其他所有设备(接收方)收到 SOF 的下降沿时,接收方会将自己的位时序计时周期拨到 SS 段的位置,与发送方位的时序计时周期保持同步
- 硬同步只在帧的第一个下降沿(SOF 下降沿)有效
- 经过硬同步后,若发送方和接收方的时钟没有误差,则后续所有数据位的采样点必然都会对齐数据位中心附近
- 若发送方或接收方的时钟有误差,随着误差积累,数据位边沿逐渐偏离 SS 段,则此时接收方根据再同步补偿宽度值(SJW) 通过加长 PBS1 段,或缩短 PBS2 段,以调整同步
- 再同步可以发生在第一个下降沿之后的每个数据位跳变边沿
- 收发器内部,CANH、CANL 引脚是开漏驱动,目的是实现非破坏性仲裁所要求的线与特性
- TXD 高电平时,输出显性状态,高位和低位 FET 导通,CANH 输出高电平、CANL 输出低电平,总线寄生电容被充电
- TXD 低电平时,输出隐性状态,高位和低位 FET 关断,CANH 和 CANL 电平由总线阻容决定,总线寄生电容放电
- TXD 在收发器内部上拉,当悬空时内部高电平,输出保持隐性状态
- 收发器内部 CANH 和 CANL 之间有两个 “中拉电阻”,将 CANH 和 CANL 拉到 0.5 倍 VCC 的中间电平,即默认对地电压都是 2.5V 左右,并起到微弱的电平收紧作用
- 当总线(CANH-CANL)有电压差时,内部收发器输出 1,否则输出 0
- 内部收发器的输出电平,通过两个 FET 组成的推挽驱动器输出电平到 RXD 引脚
- 原因分析:CANH、CANL 之间没有匹配电阻或者匹配的终端电阻太大,导致寄生电容上的电荷放电速度过慢,在隐性状态出现边沿下降过缓的现象,导致 CAN 控制器无法采集到正确的电平
- 排查方案:
- 适当减小终端电阻的阻值,加快隐性状态放电,使下降沿快速下降
- 原因分析:总线电容过大
- 排查方案:
- 检查总线是否有外加电容、保护器件(如 TVS)的寄生电容过大,若过大则适当去除,建议单个 CAN 节点的电容控制在 40pF~100pF 内
- 适当降低波特率
- 原因分析:
- CAN 速率过高。由于 CAN 总线的仲裁机理,其对延时有着非常严格的要求。线缆延时的存在,使得导线长度制约着实际应用中 CAN 的最高工作速率。CAN 速率与通信距离成反比,速率越高,通信距离越短
- 线缆阻抗大,远端信号幅值过低
- 排查方案:
- 降低速率,或缩短总线长度,可参考线缆长度与波特率的关系
-
- 换用阻抗小的电线缆,或适当增大终端电阻值,可参考线缆长度与直流参数推荐
- 原因分析:线缆和 PCB 布局走线耦合感性负载,导致出现共模抖动
- 排查方案:修改终端电阻中点对地 split 电容,调整范围 1nF~100nF,推荐值 4.7nF
- 原因分析:电磁环境干扰
- 排查方案:
- 提高 CAN 双绞程度
- 加单双屏蔽层
- 使用 CAN 隔离模块
- 弱电远离强电
- 优化布线
- 优化组网方式和调整终端电阻,减少信号反射引起的信号振铃,避免总线差模信号反复在显性电平和隐性电平阈值震荡所导致的 RXD 误翻转
- 原因分析:出现位错误、ACK 错误、填充错误、CRC 错误、格式错误
- 排查方案:
- 检查 CANH 和 CANL 接线是否正确、是否有虚接
- 测量 CANH 电压应在 2.5V~3.5V 之间,CANL 电压应在 1.5V~2.5V 之间,否则应排查是否有线束短路情况
- 检查 CAN 网络两端是否各有 120Ω 终端电阻,且中间节点无终端电阻
- 检查各节点波特率是否一致
- 检查各节点采样点是否适合、并尽可能保持一致
- 用示波器测量波形,查看波形是否正常,是否出现前述隐性电平时下降沿过缓、共模震荡、干扰过大等问题,并做相应处理
- 用示波器测量波形,捕捉错误帧(错误帧由 6 个显性位和 8 个隐性位组成),分析错误类型和原因。例如 CAN 的仲裁域波特率为 500kbps 时,以 CANH 触发为例。选择触发方式为脉宽触发,触发脉宽选择 > 11us (保证大于 5 个连续显性位),触发电平 > 2.5V,即可抓取错误帧波形。