本文最后更新于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的设备仲裁失败
-
-
- 数据帧的优先级高于远程帧
-
-
-
- 标准格式的优先级高于扩展格式(SRR为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速率与通信距离成反比,速率越高,通信距离越短
- 线缆阻抗大,远端信号幅值过低
- 排查方案:
- 降低速率,或缩短总线长度,可参考线缆长度与波特率的关系
-
- 换用阻抗小的电线缆,或适当增大终端电阻值,可参考线缆长度与直流参数推荐
CAN总线波形出现明显的共模震荡
- 原因分析:线缆和PCB布局走线耦合感性负载,导致出现共模抖动
- 排查方案:修改终端电阻中点对地split电容,调整范围1nF~100nF,推荐值4.7nF
总线干扰过大
- 原因分析:电磁环境干扰
- 排查方案:
- 提高CAN双绞程度
- 加单双屏蔽层
- 使用CAN隔离模块
- 弱电远离强电
- 优化布线
- 优化组网方式和调整终端电阻,减少信号反射引起的信号振铃,避免总线差模信号反复在显性电平和隐性电平阈值震荡所导致的RXD误翻转
错误帧/Busoff故障
- 原因分析:出现位错误、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,即可抓取错误帧波形。