一、CAN总线基础:从物理层到仲裁机制
大家好,我是老张。做汽车电子测试这么多年,CAN总线可以说是每天都要打交道的"老朋友"了。今天咱们就来聊聊CAN总线的基础知识。别小看这些基础内容,我见过太多测试脚本出问题,最后追根溯源都是基础概念没吃透。
1.1 CAN协议概述
CAN,全称Controller Area Network,控制器局域网。说白了,就是让车上各个电子模块能互相说话的一套规则。
为什么汽车要用CAN?你想想看,一辆车上有几十个ECU(电子控制单元),发动机、变速箱、ABS、气囊、车窗……每个模块都要交换数据。要是每个模块之间都拉一根线,那线束比车还重。CAN总线只用两根线,就能让所有节点共享数据。
我个人习惯把CAN总线比作一个会议室。谁想发言,先听一下会议室里有没有人在说话。没人说话,就抢麦发言。如果两个人同时抢麦,那就按优先级来,级别高的先讲。这个比喻虽然简单,但核心机制都在里面了。
核心特点:
- 多主总线:任何节点都可以主动发消息
- 实时性强:优先级高的消息优先发送
- 可靠性高:有完善的错误检测机制
- 成本低:只用两根线(CAN_H和CAN_L)
1.2 CAN物理层与数据链路层
CAN总线分两层:物理层和数据链路层。咱们做HIL测试,这两层都得懂。
物理层
物理层就是实实在在的硬件。两根线:CAN_H和CAN_L。信号怎么传?靠差分电压。
我刚开始做测试时,有个坑让我印象很深。有一次测试脚本怎么都收不到报文,查了半天,原来是CAN_H和CAN_L接反了。嗯,这种低级错误,犯过一次就记住了。
| 信号状态 | CAN_H电压 | CAN_L电压 | 差分电压 |
|---|---|---|---|
| 显性(Dominant) | 3.5V | 1.5V | 2.0V |
| 隐性(Recessive) | 2.5V | 2.5V | 0V |
显性电平代表逻辑0,隐性电平代表逻辑1。显性会覆盖隐性——这个特性是总线仲裁的基础。
数据链路层
数据链路层负责把数据打包成帧,然后发出去。它管的事情包括:帧格式、仲裁、应答、错误检测等等。
这里有个关键点:CAN总线用的是CSMA/CA(载波监听多点接入/冲突避免),不是CSMA/CD。什么意思?就是先监听,再发送,尽量避免冲突。而不是像以太网那样,冲突了再重传。
1.3 CAN报文帧结构
CAN总线有四种帧类型:数据帧、远程帧、错误帧、过载帧。咱们做HIL测试,打交道最多的是数据帧和错误帧。
数据帧
数据帧是干活的主力。它负责把数据从一个节点传到另一个节点。标准帧有11位ID,扩展帧有29位ID。
数据帧的结构是这样的:
帧起始(SOF) + 仲裁场 + 控制场 + 数据场 + CRC场 + 应答场 + 帧结束(EOF)
我建议你重点记住仲裁场。仲裁场里包含ID和RTR位。ID决定了消息的优先级,数值越小优先级越高。
小技巧:做HIL测试时,我习惯把关键消息的ID设小一点,比如0x100以下。这样在总线负载高的时候,关键消息不会被挤掉。
远程帧
远程帧是用来请求数据的。一个节点发远程帧,另一个节点收到后,就会发对应的数据帧回来。
远程帧和数据帧的区别在哪?远程帧没有数据场。就这么简单。
错误帧
错误帧是CAN总线的"保安"。一旦检测到错误,就发错误帧通知所有节点。
错误帧分两种:主动错误帧和被动错误帧。主动错误帧发6个显性位,被动错误帧发6个隐性位。
避坑指南:我曾经遇到过一个案例,测试时总线老是报错,查了半天发现是某个节点的终端电阻没焊好。CAN总线两端必须各接一个120Ω的终端电阻,少一个都不行。这个坑,我替你们踩过了。
过载帧
过载帧用得不多。它表示节点太忙了,处理不过来,要求延迟发送。过载帧和错误帧结构类似,但触发条件不同。
1.4 CAN总线仲裁机制
仲裁机制是CAN总线的精髓。多个节点同时发消息怎么办?谁优先级高谁先发。
仲裁过程是这样的:
- 所有节点同时发送帧起始位(显性位)
- 然后逐位发送ID
- 如果某个节点发送隐性位(1),但总线上是显性位(0),说明有更高优先级的节点在发消息
- 这个节点就停止发送,转为接收
说白了,就是"谁的数字小,谁先走"。ID为0x001的消息,肯定比ID为0x100的消息先发出去。
我刚开始做HIL测试时,写了一个脚本往总线上狂发消息。结果发现发动机ECU的报文老是延迟。后来一查,是我发的测试消息ID设得太小了,把发动机的优先级给抢了。从那以后,我测试用的消息ID都统一用0x700以上的值,给真正的ECU让路。
仲裁机制要点:
- 基于逐位仲裁,非破坏性
- ID越小,优先级越高
- 数据帧优先级高于远程帧(RTR位决定)
- 仲裁失败的节点自动转为接收,不会丢数据
这里有个细节要注意:仲裁是在帧起始之后,逐位进行的。所以帧起始位是所有节点同步的起点。如果帧起始位出问题,整个仲裁就乱了。
嗯,CAN总线的基础知识就聊到这儿。这些内容看着简单,但做HIL测试时处处都用得上。下一章咱们聊聊CANoe和Python怎么配合,写第一个测试脚本。