第二章:CAN总线基础

2.1 CAN协议的起源与发展

说到CAN总线,我得先聊聊它的来历。上世纪80年代初,汽车里的电子设备越来越多,线束越来越重,故障率也越来越高。我记得有次拆解一辆老款车型,光是车门里的线束就够绕三圈。博世公司看不下去了,于是在1983年开始研发CAN协议,1986年正式推出。

说白了,CAN就是为了解决「多节点通信」而生的。它不像RS-485那样需要主机调度,也不像I2C那样有主从之分。每个节点都能主动发消息,谁抢到总线谁说话。这个设计理念,在当时是非常超前的。

CAN协议发展时间线:

  • 1986年:博世在SAE大会上首次发布CAN协议
  • 1991年:发布CAN 2.0规范,分为A和B两个版本
  • 1993年:ISO 11898标准正式发布,CAN成为国际标准
  • 2003年:CAN FD(灵活数据速率)开始研发
  • 2012年:博世发布CAN FD 1.0规范
  • 2015年:CAN FD成为ISO 11898-1:2015标准

我在做车载网关项目时,遇到过一台2008年的德系车,用的还是CAN 2.0A协议。当时调试工具只支持2.0B,结果报文ID全对不上。嗯,这就是历史遗留问题。所以了解版本差异,真的很重要。

2.2 CAN 2.0A与2.0B帧结构详解

CAN 2.0A和2.0B最大的区别,就是ID长度。2.0A用11位标识符,2.0B用29位。你想想看,11位最多只能有2048个不同的ID,而29位能到5亿多个。对于现代汽车来说,动辄上百个ECU,11位确实不够用。

2.2.1 标准帧(CAN 2.0A)结构

标准帧的格式,我建议你死记硬背下来。因为调试时,你看到的每一个bit都有意义。

字段长度(位)说明
SOF1帧起始,显性电平(0)
ID11标识符,决定优先级
RTR1远程帧标志,0=数据帧,1=远程帧
IDE1扩展标志,标准帧中为显性(0)
r01保留位
DLC4数据长度,0-8字节
Data0-64数据字段,最多8字节
CRC15循环冗余校验
CRC Delimiter1CRC分隔符,隐性电平(1)
ACK1应答槽,发送方发隐性,接收方拉显性
ACK Delimiter1应答分隔符,隐性电平
EOF7帧结束,全部隐性

我的经验:调试CAN总线时,先看SOF和EOF。如果SOF之后没有正常结束,多半是总线竞争或者硬件故障。我曾经花了两天时间查一个丢帧问题,最后发现是CAN收发器的共模电压不对。

2.2.2 扩展帧(CAN 2.0B)结构

扩展帧就是把ID从11位扩展到29位。结构上多了个SRR位和扩展ID部分。SRR位替代了标准帧中的RTR位置,但功能不同。

// 标准帧ID解析示例
uint16_t standard_id = 0x7FF;  // 11位最大值
// 扩展帧ID解析示例
uint32_t extended_id = 0x1FFFFFFF;  // 29位最大值

// 实际项目中,我常用这种方式判断帧类型
if (frame.IDE == 0) {
    // 标准帧,ID范围 0x000 - 0x7FF
    process_standard_frame(frame.ID);
} else {
    // 扩展帧,ID范围 0x00000000 - 0x1FFFFFFF
    process_extended_frame(frame.ID);
}

这里有个坑要注意:扩展帧的优先级不一定比标准帧低。仲裁时,标准帧的IDE位是显性(0),扩展帧的IDE位是隐性(1)。所以标准帧的优先级更高。但如果你把扩展帧的ID设得很小,它照样能抢到总线。

2.3 CAN总线物理层特性

物理层这块,说白了就是信号怎么在线上跑。CAN总线用的是差分信号,两条线:CAN_H和CAN_L。显性电平对应逻辑0,隐性电平对应逻辑1。

2.3.1 电平特性

状态CAN_H电压CAN_L电压差分电压
显性(Dominant)3.5V1.5V2.0V
隐性(Recessive)2.5V2.5V0V

为什么用差分信号?抗干扰能力强啊。我在工厂现场调试时,旁边就是大功率电机,单端信号根本没法看。但CAN总线照样跑得稳稳的。因为干扰是共模的,差分信号一减就没了。

2.3.2 终端电阻

CAN总线两端必须各接一个120欧姆的终端电阻。这个电阻的作用是匹配阻抗,防止信号反射。我见过太多人忽略这个,结果总线波形乱七八糟。

警告:千万不要在总线中间接终端电阻!我曾经接手过一个项目,对方在三个节点上都接了120欧姆电阻,结果等效电阻只有40欧姆,总线根本拉不动。正确的做法是:只在最远端的两个节点各接一个120欧姆电阻。

2.3.3 总线长度与速率

CAN总线的速率和长度是成反比的。速率越高,能跑的距离越短。这是物理规律,没办法。

// 常见速率与最大距离对照
// 1 Mbps -> 40米
// 500 kbps -> 100米  
// 250 kbps -> 250米
// 125 kbps -> 500米
// 50 kbps -> 1000米
// 10 kbps -> 5000米

// 实际项目中,我建议留20%的余量
// 比如需要跑100米,选500kbps就有点悬
// 最好降到250kbps

为什么会这样?因为CAN总线是CSMA/CA机制,节点发完数据后要等ACK。如果总线太长,信号传播时间就长,位时序就不好调。我做过一个测试,在500米总线上跑1Mbps,结果误码率高达10%。降到125kbps后,一切正常。

2.3.4 节点数量

理论上,CAN总线最多可以挂110个节点。但实际中,我建议不要超过32个。为什么?因为每个节点都会增加总线电容,电容大了信号边沿就变缓,容易出错。

节点数量建议:

  • 1 Mbps:不超过20个节点
  • 500 kbps:不超过32个节点
  • 250 kbps及以下:不超过64个节点

嗯,这里还要提一下CAN收发器。常用的有TJA1050、SN65HVD230等。选型时要注意:是5V还是3.3V供电,是高速还是容错模式。我习惯用TJA1050,皮实耐用,就是功耗大了点。

最后说一句:CAN总线的物理层看似简单,但坑不少。布线时要注意双绞,远离大功率线束。地线要处理好,不然共模电压一高,收发器就烧了。我烧过三个TJA1050才学会这个教训。