第3章:CAN总线数据链路层:CAN帧结构、帧类型与位填充机制
各位同学,咱们今天聊聊CAN总线最核心的部分——数据链路层。说白了,就是CAN报文在线上到底长什么样,怎么传,怎么保证不出错。
我记得刚入行那会儿,拿着逻辑分析仪抓了一堆CAN波形,看着那些高低电平,完全不知道在说什么。后来才明白,这些波形背后就是咱们今天要讲的帧结构。搞懂了它,你就能读懂任何一条CAN报文。
3.1 标准帧与扩展帧:两种身份证
CAN总线上的每个报文,都得有个ID。这个ID就像人的身份证号,决定了这条报文的优先级。ID越小,优先级越高。
标准帧的ID是11位,扩展帧是29位。为什么要有两种?说白了,早期11位ID够用,后来车上节点越来越多,11位不够分了,就搞了个29位的扩展帧。
我给大家画个重点:
- 标准帧:11位ID,最大能表示2048个不同的ID
- 扩展帧:29位ID,最大能表示5亿多个ID
你想想看,现在一辆高端车上有上百个ECU,每个ECU可能发好几条报文,11位ID确实捉襟见肘。所以现在新车基本都用扩展帧了。
关键区别:标准帧和扩展帧的帧格式不同,但它们在总线上可以共存。CAN控制器会自动识别。不过我个人建议,一个项目里最好统一用一种,混着用容易出问题。
3.2 帧类型:四种角色各司其职
CAN总线上一共有四种帧类型。我习惯把它们比作四种不同的信使:
3.2.1 数据帧:主角登场
数据帧是咱们用得最多的。它负责把数据从发送节点传到接收节点。一个数据帧最多带8个字节的数据。
数据帧的结构是这样的:
帧起始(SOF) + 仲裁场 + 控制场 + 数据场 + CRC场 + ACK场 + 帧结束(EOF)
嗯,这里要注意,数据场最多8字节。为什么是8?不是16或32?我猜当年设计者觉得8字节够用了,而且8字节的CRC校验效率最高。实际项目中,大部分报文也就用2-4个字节。
3.2.2 远程帧:请求数据
远程帧很有意思。它不带数据,只带一个ID。作用是:一个节点向另一个节点请求数据。
举个例子:发动机ECU想请求车速信号,它就发一个远程帧,ID填车速信号的ID。车速传感器收到后,就会发一个数据帧回来。
避坑指南:我曾经在一个项目中,发现总线负载率异常高。查了半天,原来是有个节点不停地发远程帧,而对应的数据节点没响应。结果远程帧反复重发,把总线堵死了。所以用远程帧时,一定要确保对方能响应。
3.2.3 错误帧:纠错机制
错误帧是CAN总线自愈能力的关键。任何一个节点检测到错误,就会立刻发错误帧,通知所有节点:刚才那帧数据有问题,大家别用。
错误帧由两部分组成:
- 错误标志:6个连续的显性位(正常帧不允许出现6个相同位)
- 错误界定符:8个连续的隐性位
我刚开始学的时候,觉得错误帧就是用来报错的。后来做项目才发现,错误帧其实是一种「主动破坏」。它故意打破位填充规则,让所有节点都知道出错了。这种设计很巧妙。
3.2.4 过载帧:慢一点,我跟不上
过载帧用得比较少。它表示接收节点处理不过来,请求发送节点慢一点。
过载帧的结构和错误帧很像,也是6个显性位+8个隐性位。但触发条件不同:
- 接收节点还没准备好接收下一帧
- 检测到总线空闲时出现显性位
注意:过载帧不能滥用。如果一个节点频繁发过载帧,说明它的处理能力不足,或者总线负载太高。我曾经调试过一个项目,某个ECU每隔几帧就发过载帧,最后发现是它的CAN接收缓冲区太小了。
3.3 位填充机制:保证时钟同步
这个知识点,很多初学者会忽略。但我觉得它特别重要。
位填充的规则很简单:连续发送5个相同位后,自动插入一个相反位。
比如你要发送5个1,实际线上会变成:1 1 1 1 1 0。这个0就是填充位。
为什么要这么做?
因为CAN总线没有单独的时钟线。接收节点靠检测电平跳变来同步时钟。如果连续很多位都不跳变,接收节点的时钟就会漂移,导致采样错误。
你想想看,如果发送的是00000000,接收节点怎么知道这是8个0还是7个0?有了位填充,最多5个相同位后就会跳变,接收节点就能准确计数了。
重要:位填充只覆盖SOF到CRC场。ACK场和EOF不参与位填充。另外,错误帧和过载帧故意打破位填充规则,这是它们的工作方式。
我给大家算一笔账:
| 数据内容 | 原始位数 | 填充后位数 | 效率 |
|---|---|---|---|
| 0x55 (01010101) | 8 | 8 | 100% |
| 0x00 (00000000) | 8 | 10 | 80% |
| 0xFF (11111111) | 8 | 10 | 80% |
看到没?数据越随机,效率越高。全是0或全是1,效率最低。实际项目中,CAN总线的有效数据率大概在70%-85%之间。
个人经验:我在做总线负载率计算时,一般会按80%的有效率来估算。比如你算出来理论负载率是50%,实际可能到60%左右。留点余量,别把总线跑满了。
3.4 小结
今天咱们讲了三个核心内容:
- 帧结构:标准帧11位ID,扩展帧29位ID,混用要小心
- 帧类型:数据帧、远程帧、错误帧、过载帧,各有各的用途
- 位填充:5个相同位后插反位,保证时钟同步
这些是CAN总线最基础的知识。搞懂了它们,你就能看懂CAN波形了。下一章咱们聊聊CAN的仲裁机制——为什么多个节点同时发数据不会冲突?这个很有意思。
好,今天就到这儿。有问题随时交流。