3、CAN总线基础:CAN协议概述、CAN帧结构、CAN总线物理层

好,咱们进入正题。UWB车钥匙最终要跟整车对话,靠的就是CAN总线。说白了,CAN就是汽车里的“神经系统”。我这几年调试UWB模块,十次有八次的问题都出在CAN通信上。所以这一章,咱们把CAN的基础打牢。

3.1 CAN协议概述——为什么是它?

CAN,全称Controller Area Network,控制器局域网。上世纪80年代由Bosch公司发明,初衷就是为了让汽车里的各种电子控制单元(ECU)能高效、可靠地交换数据。

你想想看,一辆车里有几十个ECU:发动机、变速箱、ABS、气囊、车身控制器、车机……如果每个ECU之间都拉一根专线,那线束比车还重。CAN总线只用两根线(CAN_H和CAN_L),就能把所有节点挂上去。这就是它的核心价值。

CAN协议的几个关键特点:

  • 多主总线:任何节点都可以主动发消息,没有“老大”管着。谁抢到总线谁说话。
  • 基于优先级仲裁:如果两个节点同时发,ID小的(优先级高)的胜出。这个机制非常巧妙,后面细说。
  • 差分信号传输:抗干扰能力强。车上的电磁环境有多恶劣,搞过电子的都懂。
  • 错误检测与重发:每个节点都会检查总线上的错误,一旦发现,立刻通知所有人重发。

我个人习惯:在项目初期,我会先确认整车的CAN网络拓扑。是单条CAN?还是多条(动力CAN、车身CAN、信息娱乐CAN)?UWB车钥匙通常挂在车身CAN或蓝牙/NFC模块所在的CAN上。这个搞错了,后面全是白干。

3.2 CAN帧结构——数据是怎么打包的?

CAN总线上传输的基本单位叫“帧”。一共有四种帧类型:数据帧、远程帧、错误帧、过载帧。咱们UWB车钥匙最常用的是数据帧和错误帧。远程帧偶尔用,过载帧基本不用管。

3.2.1 数据帧——主角

数据帧就是用来传输实际数据的。标准格式(CAN 2.0A)有11位ID,扩展格式(CAN 2.0B)有29位ID。UWB车钥匙通常用标准格式就够了,因为节点不多。

数据帧的结构(从开始到结束):

  1. 帧起始(SOF):1个显性位(逻辑0)。告诉所有人:“我要发消息了!”
  2. 仲裁场:11位ID + 1位RTR位(远程帧请求位,数据帧里是显性0)。这里就是决定优先级的地方。
  3. 控制场:6位。包含IDE位(标识扩展帧)、保留位、以及4位DLC(数据长度码)。DLC告诉你后面跟了多少字节数据,0~8。
  4. 数据场:0~8字节。这就是UWB车钥匙要发的实际数据,比如钥匙ID、定位坐标、指令等。
  5. CRC场:15位CRC校验码 + 1位CRC界定符。用来检查数据有没有传错。
  6. 应答场(ACK):2位。发送节点发完数据后,会释放总线。如果接收节点正确收到了,就会在ACK Slot位拉一个显性位作为应答。发送节点如果没收到应答,就知道出问题了。
  7. 帧结束(EOF):7个隐性位(逻辑1)。表示这帧结束了。

避坑指南:我曾经在一个项目中,UWB模块发送数据帧时,DLC设置成了8,但数据场只填了4个有效字节。结果接收方解析时,把后面4个随机值当成了有效数据,导致车门误动作。记住:DLC必须与实际数据长度一致!

3.2.2 远程帧——请求数据

远程帧看起来跟数据帧很像,但有两个关键区别:

  • RTR位是隐性(1),表示这是一个远程帧。
  • 没有数据场。DLC虽然存在,但只是用来告诉对方“我想要多少字节的数据”。

举个例子:车身控制器可以发一个远程帧,ID是UWB模块的ID,DLC=8。意思就是:“UWB模块,请把你的8字节数据发给我。” UWB模块收到后,就会发一个对应的数据帧回去。

嗯,这里要注意:远程帧在实际UWB车钥匙项目中用得不多。因为UWB模块通常是主动上报位置信息,而不是等别人来问。但如果你做的是“按需定位”方案,远程帧就派上用场了。

3.2.3 错误帧——保命用的

错误帧是CAN节点发现自己或别人出错时,主动发出来的。它的结构很简单:

  • 错误标志:6个连续的显性位(主动错误)或6个连续的隐性位(被动错误)。
  • 错误界定符:8个隐性位。

为什么说它是保命用的?因为一旦有节点检测到错误(比如CRC校验失败、位填充错误、ACK错误等),它会立刻拉6个显性位,破坏当前正在传输的帧。所有其他节点检测到这6个显性位后,也会知道出错了,然后丢弃当前帧,准备重发。

我曾经踩过的坑:有一次UWB车钥匙在车上测试,频繁出现无法解锁。用CAN分析仪抓包一看,发现UWB模块一直在发错误帧。原因是模块的CAN控制器时钟精度不够,导致位时序偏差,总被其他节点认为是错误。最后换了更高精度的晶振才解决。所以,CAN节点的时钟精度非常重要,尤其是波特率较高时(比如500kbps以上)。

3.3 CAN总线物理层——两根线怎么干活?

物理层,说白了就是CAN_H和CAN_L这两根线,以及它们背后的电气特性。

差分信号:

  • 显性位(逻辑0):CAN_H电压比CAN_L高。通常CAN_H=3.5V,CAN_L=1.5V,差分电压=2V。
  • 隐性位(逻辑1):CAN_H和CAN_L电压相等,都是2.5V,差分电压=0V。

为什么用差分?因为车上的电磁干扰是共模的,两根线受到的干扰几乎一样。接收器只看两根线的电压差,所以干扰就被抵消了。这就是CAN能在发动机舱那种恶劣环境下稳定工作的原因。

终端电阻:

CAN总线两端各需要接一个120Ω的电阻。为什么是120Ω?因为CAN双绞线的特性阻抗大约是120Ω。接上终端电阻,可以防止信号反射,保证通信质量。

我建议:在UWB车钥匙的CAN接口设计中,一定要预留终端电阻的位置。虽然模块本身通常不接(因为它在总线上是中间节点),但调试时可能需要临时接入。我见过有人忘了接终端电阻,总线信号反射得一塌糊涂,通信时好时坏。

CAN收发器:

MCU里的CAN控制器负责协议处理(组帧、拆帧、错误检测等),但它输出的信号是TTL电平(0~5V或0~3.3V),不能直接驱动CAN总线。所以需要一个CAN收发器,比如TJA1050、SN65HVD230等。收发器负责把TTL电平转换成差分信号,同时提供总线保护和驱动能力。

波特率:

UWB车钥匙常用的CAN波特率是125kbps或250kbps。为什么不用更高的500kbps?因为车身CAN通常距离较长(可能十几米),节点也多,波特率太高容易出错。125kbps是个比较稳妥的选择。

波特率 位时间 典型应用
125 kbps 8 μs 车身CAN、舒适系统
250 kbps 4 μs 动力CAN、底盘CAN
500 kbps 2 μs 高速CAN、诊断

一个小技巧:调试CAN通信时,别急着上逻辑分析仪。先用万用表量一下CAN_H和CAN_L对地的电压。正常工作时,CAN_H应该在2.5V~3.5V之间摆动,CAN_L在1.5V~2.5V之间。如果两根线都是2.5V不动,说明总线处于空闲状态(隐性)。如果一根线对地短路了,电压会异常,通信肯定不行。

好了,CAN总线的基础就这些。下一章咱们会把这些知识用起来,讲UWB车钥匙的CAN报文如何设计、如何发送和接收。到时候你会发现,基础打牢了,实战就是水到渠成的事。