4、CAN数据帧结构(上):SOF、仲裁场(ID与RTR)、控制场(IDE、DLC)

好,咱们正式开始啃CAN报文了。说实话,很多工程师学CAN,上来就背帧格式,背完就忘。我个人的习惯是——先搞懂每个位是干嘛的,它为什么长这样。今天咱们先聊数据帧的前半段:SOF、仲裁场和控制场。

4.1 SOF——帧起始,一个简单的开始

SOF全称Start of Frame,就一个显性位(逻辑0)。

你想想看,总线空闲时是隐性电平(逻辑1)。一旦某个节点把总线拉低,其他节点就知道:有人要说话了。这个下降沿,就是SOF。

我在项目中遇到过一个问题:有个节点老是丢帧,查了半天,发现是SOF位被干扰了,变成了毛刺。嗯,这里要注意——SOF是同步的起点,如果它坏了,后面全乱套。

SOF要点:
  • 1个显性位
  • 用于同步所有节点的时钟
  • 标志着一帧数据的开始

4.2 仲裁场——谁说了算?

仲裁场包含两部分:ID(标识符)和RTR(远程帧标志)。这是CAN协议最巧妙的设计之一。

4.2.1 ID——报文的身份证

ID决定了两个事情:

  1. 报文的优先级——ID越小,优先级越高
  2. 报文的内容——比如0x123代表车速,0x456代表转速

标准帧的ID是11位,范围0x000~0x7FF。扩展帧是29位,咱们后面再聊。

为什么ID越小优先级越高?因为CAN总线是“线与”逻辑。显性位(0)会覆盖隐性位(1)。仲裁时,谁先发0,谁就赢了。说白了,就是比谁的数字小。

我的经验:设计CAN网络时,一定要把关键报文(比如刹车、转向)分配小ID。我曾经见过一个项目,把车窗控制报文ID设得比刹车还小,结果刹车信号被延迟了...这很危险。

4.2.2 RTR——你是来问问题的?

RTR位表示这是数据帧还是远程帧:

  • RTR = 0:数据帧(带数据)
  • RTR = 1:远程帧(不带数据,只是请求)

远程帧说白了就是:“喂,谁有数据?发给我!”

我建议初学者先别纠结远程帧,实际项目中用得不多。你只要记住:数据帧的RTR是0,远程帧是1。仲裁时,数据帧优先级更高(因为RTR=0是显性)。

4.3 控制场——IDE和DLC

控制场有6位,但咱们重点看两个:IDE和DLC。

4.3.1 IDE——你是标准帧还是扩展帧?

IDE全称Identifier Extension Bit:

  • IDE = 0:标准帧(11位ID)
  • IDE = 1:扩展帧(29位ID)

标准帧和扩展帧可以共存于同一总线。但要注意:标准帧的优先级永远高于扩展帧。为什么?因为IDE位在标准帧里是显性(0),在扩展帧里是隐性(1)。仲裁时,标准帧直接赢了。

避坑指南:我曾经在一个项目里混用了标准帧和扩展帧,结果发现某个扩展帧报文老是发不出去。查了半天,原来是总线上有个标准帧ID比它大,但IDE位让它输了仲裁。记住:IDE位本身就是仲裁的一部分!

4.3.2 DLC——你带了多少数据?

DLC全称Data Length Code,4位,表示数据场有多少字节。

DLC值 数据字节数
0 0
1 1
2 2
... ...
8 8
9~15 8(实际还是8字节)

注意最后一行!DLC可以设成9~15,但数据场最多8字节。这是CAN协议允许的,但实际传输的还是8字节。我建议你老老实实设0~8,别搞花活。有些CAN控制器对DLC>8的处理不一样,容易出兼容性问题。

4.4 一个完整的例子

咱们看一个实际报文,假设我用CAN分析仪抓到了这么一串:

0x123 8 01 02 03 04 05 06 07 08

拆解一下:

  • SOF:1个显性位(你看不到,但它在最前面)
  • ID:0x123(二进制0001 0010 0011,11位)
  • RTR:0(数据帧)
  • IDE:0(标准帧)
  • DLC:8(8字节数据)
  • 数据:01 02 03 04 05 06 07 08

你看,就这么简单。SOF告诉别人“我要开始说了”,ID告诉别人“我是谁”,RTR说“我带了数据”,IDE说“我是标准帧”,DLC说“我带了8个字节”。

小结一下今天的内容:
  • SOF:1位显性,帧开始
  • 仲裁场:ID(11位)+ RTR(1位),决定优先级
  • 控制场:IDE(1位)+ DLC(4位),描述帧类型和数据长度

下节课咱们聊数据帧的后半段:数据场、CRC场和ACK场。到时候你会看到,CAN协议为了保证数据不出错,做了多少“笨功夫”。

嗯,今天就到这儿。回去拿你的CAN分析仪抓几个报文,对照着看看,比光看书强十倍。