2. CAN协议核心概念:CAN2.0A与CAN2.0B区别、标准帧与扩展帧、数据帧与远程帧

好,咱们今天聊聊CAN协议里最基础、也最容易搞混的几个概念。说实话,我当年刚接触CAN的时候,也被这些帧类型绕得晕头转向。特别是标准帧和扩展帧,光看协议文档总觉得差不多,一上示波器才发现坑不少。

先给你吃颗定心丸:这些概念其实就三组对比。搞清楚了,后面CANopen、J1939这些高层协议你上手会快很多。

2.1 CAN2.0A 与 CAN2.0B:两个版本的恩怨

CAN协议最早是1986年由Bosch公司提出的。那时候的版本叫CAN 1.0,后来升级到CAN 2.0。1991年Bosch发布了CAN 2.0规范,分成了两部分:

  • CAN 2.0A:只支持11位标识符,也就是标准帧
  • CAN 2.0B:支持11位和29位标识符,也就是标准帧+扩展帧

你可能会问:为什么要有两个版本?说白了,就是11位ID不够用了。早期一个ECU控制几个功能,11位ID绰绰有余。后来车上电子设备越来越多,11位ID只能表示2048个不同的消息(实际可用更少),根本不够分。

关键区别一句话总结:

CAN 2.0A节点只能收发标准帧;CAN 2.0B节点既能收发标准帧,也能收发扩展帧。

我在一个商用车项目里就吃过这个亏。当时选了一款号称支持CAN 2.0B的MCU,结果它的CAN控制器是"2.0B passive"模式——只能接收扩展帧,不能发送。嗯,这个细节很多芯片手册写得含糊,你得留个心眼。

2.2 标准帧 vs 扩展帧:11位与29位的博弈

标准帧和扩展帧,最直观的区别就是仲裁场的长度。

对比项 标准帧 (CAN 2.0A) 扩展帧 (CAN 2.0B)
标识符长度 11位 29位
仲裁场长度 12位 32位
最大消息数 2048种 约5.36亿种
帧长度 较短(效率高) 较长(灵活性高)
IDE位 显性(0) 隐性(1)
兼容性 所有CAN节点 仅2.0B节点

你想想看,11位ID能表示2^11=2048个不同的消息ID。听起来不少,但实际项目中,每个ID还要划分优先级、源地址、功能码……很快就用完了。29位ID就不一样了,5亿多个组合,基本想怎么分就怎么分。

但扩展帧也有代价——帧更长。标准帧数据场为0时只有47位,扩展帧要64位。总线负载率会高一些。我建议你:能用标准帧就别用扩展帧,除非你的ID规划确实需要那么多位。

我的经验:

在J1939协议里,29位ID被拆成了优先级、PDU格式、PDU特定、源地址等字段。这种结构化的ID分配方式,比单纯用11位ID做扁平化设计要清晰得多。如果你做的是多节点、多功能的系统,建议优先考虑扩展帧+高层协议。

2.3 数据帧 vs 远程帧:谁在请求,谁在响应?

数据帧和远程帧的区别,我习惯用一个比喻:

  • 数据帧:就像一个人主动说"我这里有数据,你们谁要?"
  • 远程帧:就像一个人喊"谁有数据?给我一份!"

远程帧的作用就是请求数据。一个节点发送远程帧,目标节点收到后,会发送对应的数据帧作为响应。

它们的帧结构几乎一样,唯一的区别是RTR位(Remote Transmission Request):

  • 数据帧:RTR = 0(显性)
  • 远程帧:RTR = 1(隐性)

等等,这里有个容易踩的坑——远程帧没有数据场。虽然远程帧的DLC(数据长度码)可以设置,但它实际上不携带任何数据字节。我曾经见过一个同事,在远程帧里填了8个字节的数据,结果总线上一堆错误帧……

避坑指南:

我曾经在一个项目中用远程帧做数据请求,结果发现某些CAN控制器对远程帧的处理有bug——收到远程帧后,它会自动发送一个空数据帧,而不是你期望的那个。后来我改用"请求ID+数据帧"的方式,彻底绕开了远程帧。我的建议是:除非你的CAN控制器对远程帧支持非常完善,否则尽量少用远程帧。用数据帧+应用层协议来做请求/响应,更可控。

2.4 帧结构对比:一张图看懂

下面这张SVG图,把标准帧、扩展帧、数据帧、远程帧的关系画清楚了。你一看就明白。

CAN帧类型关系图 CAN帧 数据帧 远程帧 标准数据帧 扩展数据帧 标准远程帧 扩展远程帧 关键区别 • 标准帧 vs 扩展帧:标识符长度不同(11位 vs 29位),由IDE位区分 • 数据帧 vs 远程帧:RTR位不同(0 vs 1),远程帧无数据场 • 标准帧仲裁场:11位ID + RTR + IDE + r0 • 扩展帧仲裁场:11位ID + SRR + IDE + 18位ID + RTR + r1 + r0 • 远程帧DLC表示请求的数据长度,但实际不发送数据字节

2.5 实际项目中的选择策略

说了这么多理论,咱们来点实际的。你在项目中到底该怎么选?

  1. 简单系统(2-5个节点,功能单一):用标准帧+数据帧就够了。比如一个电机控制器,只需要发送转速、温度几个信号。
  2. 中等系统(5-20个节点,功能较多):建议用标准帧+数据帧,配合简单的应用层协议。比如我做过的一个AGV小车项目,11位ID刚好够用。
  3. 复杂系统(20+节点,多网段):必须上扩展帧+高层协议(CANopen/J1939)。比如工程机械、商用车,29位ID才能满足复杂的网络管理需求。

我的建议:

如果你刚开始做CAN项目,先别急着上扩展帧。从标准帧+数据帧开始,把基础搞扎实了。等遇到ID不够用的时候,再切换到扩展帧也不迟。记住:简单就是可靠。

2.6 常见误区与避坑

最后,我把自己这些年踩过的坑整理一下,你遇到了可以少走弯路:

  • 误区一:远程帧可以带数据 —— 不行!远程帧的DLC只是告诉对方"我想要多长的数据",它本身不携带数据字节。
  • 误区二:扩展帧比标准帧高级 —— 不一定。扩展帧只是ID空间更大,但帧更长、效率更低。选哪个看需求。
  • 误区三:CAN 2.0B节点一定能发扩展帧 —— 不一定。有些芯片是"2.0B passive",只能收不能发。买芯片前一定要看手册。
  • 误区四:标准帧和扩展帧可以混用 —— 可以,但要小心。同一个网络上,标准帧和扩展帧的ID可以相同,但它们是不同的消息。有些高层协议(如CANopen)明确禁止混用。

嗯,这一章的内容就到这里。这些概念虽然基础,但真的很重要。后面讲CANopen和J1939的时候,你会发现今天的内容是理解那些高层协议的基石。