3、CAN报文类型:数据帧、远程帧、错误帧、过载帧、帧间隔
CAN总线上跑的无非就这五种东西:数据帧、远程帧、错误帧、过载帧和帧间隔。
我刚入行那会儿,总觉得搞懂数据帧就够了。后来在实车上踩过坑才明白——不理解错误帧和过载帧,你连故障原因都定位不了。嗯,咱们一个一个说清楚。
一句话总结:数据帧和远程帧是“干活”的,错误帧和过载帧是“纠错”的,帧间隔是“喘口气”的。
3.1 数据帧——最常用的报文
数据帧就是“正主”。一个节点想往总线上发数据,用的就是它。
数据帧分两种格式:标准帧(11位ID)和扩展帧(29位ID)。我个人习惯在低速网络(如车身控制)用标准帧,高速动力系统用扩展帧——因为节点多,ID不够分。
| 字段 | 长度 | 说明 |
|---|---|---|
| 帧起始 | 1 bit | 显性电平,同步所有节点 |
| 仲裁段 | 12/32 bit | ID + RTR + IDE + SRR(扩展帧) |
| 控制段 | 6 bit | DLC(数据长度码) |
| 数据段 | 0~8 字节 | 实际载荷数据 |
| CRC段 | 16 bit | 15位CRC + 1位界定符 |
| ACK段 | 2 bit | 接收节点应答 |
| 帧结束 | 7 bit | 隐性电平 |
我的经验:解析数据帧时,先看DLC。DLC告诉你后面跟了几个有效字节。我曾经遇到一个ECU,DLC总是填8,但实际只用了前3个字节——后面5个全是随机数。坑不坑?
3.2 远程帧——只问不拿
远程帧说白了就是“请求帧”。一个节点发远程帧,意思是:“谁有ID=0x123的数据?发给我!”
远程帧和数据帧长得几乎一样,唯一的区别是RTR位:数据帧RTR=0(显性),远程帧RTR=1(隐性)。
你想想看,远程帧没有数据段。它的DLC虽然存在,但只用来告诉对方“我要多少字节”,实际不携带数据。
注意:远程帧的优先级比同ID的数据帧低。因为RTR位是隐性的,仲裁时抢不过数据帧。这是CAN协议故意设计的——数据优先于请求。
3.3 错误帧——总线的“警报器”
错误帧是CAN总线最容易被忽视、也最容易让人头疼的东西。
任何节点检测到错误,就会立刻发送错误帧。错误帧由两部分组成:
- 错误标志:6个连续显性位(主动错误)或6个连续隐性位(被动错误)
- 错误界定符:8个连续隐性位
我记得有一次在台架上调试,总线莫名其妙地频繁中断。用示波器一抓,发现某个节点一直在发主动错误标志。查了半天,原来是它的晶振漂了,位时序对不上。嗯,硬件问题往往最隐蔽。
| 错误类型 | 触发条件 | 常见原因 |
|---|---|---|
| 位错误 | 发送的电平和总线电平不一致 | 总线短路、多节点同时发送不同电平 |
| 填充错误 | 连续6个相同电平 | 位填充规则被破坏 |
| CRC错误 | 接收方计算的CRC与发送方不一致 | 数据传输过程中被干扰 |
| 形式错误 | 固定格式位出现错误电平 | 帧结束位被拉低 |
| ACK错误 | 发送方没收到应答 | 总线上没有其他节点接收 |
避坑指南:我曾经在项目里遇到一个“幽灵故障”——总线偶尔丢帧,但抓波形又正常。后来发现是某个节点在被动错误状态下发错误帧,隐性标志不破坏总线,但导致发送节点重传。这种问题用CAN分析仪的“错误帧统计”功能才能抓到。
3.4 过载帧——总线的“刹车”
过载帧和错误帧长得有点像,但用途完全不同。过载帧是接收节点主动发的,意思是:“我处理不过来了,慢点!”
过载帧的结构:
- 过载标志:6个连续显性位
- 过载界定符:8个连续隐性位
触发条件有两个:
- 接收节点内部缓冲区满了,来不及处理
- 帧间隔期间检测到显性位(非法情况)
说实话,过载帧在实际应用中不太常见。现在的CAN控制器硬件FIFO深度都够,除非你搞了个特别慢的MCU还在跑轮询——嗯,我见过。
3.5 帧间隔——总线的“换气时间”
帧间隔不是报文,而是一段空闲时间。任何节点在发送完一帧后,必须等3个隐性位才能发下一帧。这3个位叫间歇场。
帧间隔的作用很简单:给其他节点一个机会。如果间歇场期间有节点想发数据,它就可以开始仲裁。如果没人发,总线就进入空闲状态。
小技巧:用CAN分析仪看波形时,帧间隔的隐性位是最容易识别的——连续的高电平。如果你看到帧与帧之间没有间隔,说明总线负载已经接近极限了。我一般建议负载率不要超过70%,超过这个值,错误帧概率会明显上升。
3.6 五种报文的关系——一张图说清楚
咱们用个表格总结一下:
| 报文类型 | 谁发的 | 干什么的 | 有没有数据段 |
|---|---|---|---|
| 数据帧 | 发送节点 | 广播数据 | 有(0~8字节) |
| 远程帧 | 请求节点 | 请求数据 | 无 |
| 错误帧 | 任何检测到错误的节点 | 通知总线错误 | 无 |
| 过载帧 | 接收节点 | 请求延迟发送 | 无 |
| 帧间隔 | 所有节点 | 总线空闲/等待 | 无 |
搞懂这五种报文,CAN总线的基本通信逻辑你就拿下了。下一层咱们要深入的是——数据帧里那8个字节到底怎么拆?嗯,那是第四章的内容了。