4、CAN协议帧结构:数据帧、远程帧、错误帧、过载帧、帧间隔
各位同学,今天我们来啃CAN协议里最核心的一块——帧结构。说白了,CAN总线上跑的就是这五种帧:数据帧、远程帧、错误帧、过载帧,还有帧间隔。你只要把这五种帧搞明白了,CAN通信的底层逻辑就通了八成。
我记得刚入行那会儿,拿着逻辑分析仪抓了一堆波形,对着手册看半天,愣是分不清哪个是标准帧哪个是扩展帧。后来被老工程师点了一句,才恍然大悟。今天我把这些经验掰开揉碎了讲给你听。
4.1 五种帧类型概览
先给个全景图,让你心里有个底:
| 帧类型 | 作用 | 谁发起的 |
|---|---|---|
| 数据帧 | 发送节点把数据广播到总线上 | 发送节点 |
| 远程帧 | 请求其他节点发送指定ID的数据 | 接收节点 |
| 错误帧 | 检测到总线错误时通知所有节点 | 任何检测到错误的节点 |
| 过载帧 | 接收节点忙不过来,要求延迟发送 | 接收节点 |
| 帧间隔 | 帧与帧之间的隔离区 | 总线空闲时自动插入 |
实际项目中,数据帧和远程帧用得最多。错误帧和过载帧属于异常处理,但你必须懂,不然出了问题都不知道总线在吵什么。
4.2 数据帧——最核心的帧
数据帧就是用来传数据的。它分两种格式:标准帧(11位ID)和扩展帧(29位ID)。我建议你先把标准帧吃透,扩展帧就是在标准帧基础上加了个扩展段。
4.2.1 标准帧(11位ID)格式
标准帧由7个段组成,我按顺序给你列出来:
- 帧起始(SOF):1个显性位,告诉总线“我要开始发了”。
- 仲裁段:11位ID + RTR位(远程帧请求位)。ID越小优先级越高。
- 控制段:IDE位(标识符扩展位,标准帧里固定为显性)+ r0保留位 + DLC(4位数据长度码)。
- 数据段:0~8字节,你要传的数据放这里。
- CRC段:15位CRC校验 + 1位CRC界定符(隐性)。
- ACK段:1位ACK槽 + 1位ACK界定符。接收节点在ACK槽里拉低总线表示收到了。
- 帧结束(EOF):7个隐性位。
关键点:标准帧的IDE位是显性(0),扩展帧的IDE位是隐性(1)。这是区分两种帧的唯一标志。
4.2.2 扩展帧(29位ID)格式
扩展帧和标准帧的区别主要在仲裁段和控制段。我直接给你对比表:
| 字段 | 标准帧 | 扩展帧 |
|---|---|---|
| ID长度 | 11位 | 29位(11位基础ID + 18位扩展ID) |
| IDE位 | 显性(0),位于控制段 | 隐性(1),位于仲裁段 |
| SRR位 | 无 | 替代远程请求位,隐性 |
| 仲裁段长度 | 12位(ID + RTR) | 32位(基础ID + SRR + IDE + 扩展ID + RTR) |
| 控制段 | IDE + r0 + DLC | r1 + r0 + DLC |
扩展帧的仲裁过程是这样的:先比11位基础ID,如果相同,再比SRR位(扩展帧是隐性,标准帧RTR是显性,所以标准帧优先级更高),然后比18位扩展ID。说白了,扩展帧的优先级天生比标准帧低一点。
我的经验:在车载项目中,动力系统(发动机、变速箱)通常用标准帧,因为实时性要求高。信息娱乐系统用扩展帧,因为节点多,需要更多ID空间。别混着用,调试起来很头疼。
4.3 远程帧
远程帧长得跟数据帧几乎一样,就一个区别:RTR位是隐性(1)。数据帧的RTR位是显性(0)。
远程帧没有数据段。它的DLC字段表示请求的数据长度。比如你发一个远程帧,ID=0x123,DLC=8,意思就是“谁持有ID=0x123的数据,请发8个字节给我”。
避坑指南:我曾经在一个项目里,远程帧的DLC写错了,导致对方节点发过来的数据长度不匹配,接收缓冲区直接溢出。记住,远程帧的DLC必须和对应数据帧的DLC一致。
4.4 错误帧
错误帧由两部分组成:错误标志(6个连续显性位)+ 错误界定符(8个隐性位)。
CAN协议定义了5种错误:
- 位错误:发送节点监控总线,发现发送的电平和总线实际电平不一致。
- 填充错误:连续5个相同电平后,没有出现反码填充位。
- CRC错误:接收节点计算的CRC和发送节点的不一致。
- 形式错误:固定格式的位段(如EOF、界定符)出现了错误电平。
- ACK错误:发送节点在ACK槽没检测到显性位(没人确认收到)。
任何节点检测到错误,就会立刻发送错误帧。这会导致所有节点都收到错误标志,然后各自重发。嗯,这里要注意,错误帧的优先级是最高的,因为它一出现,总线就被显性位占满了。
4.5 过载帧
过载帧的结构和错误帧很像:过载标志(6个显性位)+ 过载界定符(8个隐性位)。
触发条件有两个:
- 接收节点还没处理完上一帧,内部缓冲区满了。
- 总线在帧间隔期间检测到显性位(非法情况)。
实际项目中,过载帧很少见。如果你发现总线上频繁出现过载帧,八成是接收节点的处理能力不够,或者中断响应太慢。我曾经在一个电机控制器上遇到过,后来把接收中断优先级调高就解决了。
4.6 帧间隔
帧间隔就是两帧之间的空闲时间。它由三部分组成:
- 间歇场:3个隐性位。
- 总线空闲:任意长度的隐性电平,直到有节点开始发送。
- 暂停发送场(仅被动错误节点):8个隐性位,让被动错误节点多等一会儿。
帧间隔的作用很简单:给总线一个喘息的机会,也让接收节点有时间把数据从缓冲区搬走。
4.7 标准帧 vs 扩展帧:怎么选?
我直接给你一个决策清单:
| 场景 | 推荐格式 | 原因 |
|---|---|---|
| 节点少于16个,实时性要求高 | 标准帧 | 帧短,总线占用时间少,优先级高 |
| 节点多,需要大量ID分配 | 扩展帧 | 29位ID,可分配超过5亿个ID |
| 兼容J1939协议 | 扩展帧 | J1939强制使用29位ID |
| 低速CAN(125kbps以下) | 标准帧 | 减少总线负载,提高可靠性 |
一句话总结:能用标准帧就用标准帧,除非ID不够用或者协议强制要求扩展帧。标准帧的实时性和可靠性都更好。
4.8 帧结构总览图
下面这张图把标准帧和扩展帧的结构画在一起,方便你对比记忆:
4.9 实战中的帧分析技巧
最后分享几个我在调试中总结的经验:
- 看波形先看SOF:SOF是显性位,从隐性跳变到显性的那个下降沿就是帧开始。用示波器抓的时候,触发条件设成下降沿触发。
- 数位宽判断帧类型:标准帧从SOF到EOF一共47位(数据段0字节时),扩展帧是67位。数一下位宽就能快速区分。
- IDE位是分水岭:在控制段第1位(标准帧)或仲裁段第13位(扩展帧)看IDE位是0还是1,一眼就能认出帧格式。
- 错误帧的特征:6个连续显性位,这在正常帧里不可能出现(因为有位填充机制)。看到6个显性位连在一起,肯定是错误帧。
小技巧:我习惯在CAN分析仪里设置一个过滤规则,只显示标准帧或只显示扩展帧。调试混合网络时,这能帮你快速聚焦到目标节点。
好了,帧结构这部分内容比较多,但它是CAN通信的基石。你把这五种帧的格式和用途记牢了,后面讲位时序、同步、采样点的时候,理解起来就轻松多了。