2、LIN协议基础:LIN帧结构、帧类型与帧ID优先级
好,咱们进入正题。LIN总线这东西,说白了就是汽车上那些不太重要的节点之间的通信方式。比如车窗、座椅、雨刮器——这些不需要CAN那么高的速率,成本又敏感,LIN就派上用场了。
我个人习惯把LIN帧理解成「一封格式固定的信」。你想想看,信要有信封、内容、署名,LIN帧也一样。咱们先拆开看看这封信长什么样。
2.1 LIN帧结构:一帧到底长啥样?
一个标准的LIN帧,由主机任务和从机任务共同完成。主机负责发帧头,从机负责回应数据。帧结构分成这么几段:
- 同步间隔段(Break):至少13个显性位。这是告诉所有节点「注意,要发新帧了」。
- 同步段(Sync):固定为0x55。用来校准从节点的时钟。我在项目中遇到过,有些便宜的晶振偏差大,同步段就是用来兜底的。
- 标识符段(PID):6位ID + 2位奇偶校验。决定了这帧数据是给谁的、什么类型。
- 数据段(Data):1到8个字节。真正要传的信息。
- 校验和段(Checksum):经典校验和或增强型校验和。用来检查数据有没有传错。
重点记住:整个帧除了Break段,其他部分都是用字节字段(Byte Field)的形式传输的。每个字节字段包含1个起始位、8个数据位、1个停止位。嗯,标准的UART格式。
2.2 帧类型:四种角色各司其职
LIN总线定义了四种帧类型。我刚开始学的时候也觉得有点绕,但实际用起来,每种都有它不可替代的场景。
2.2.1 无条件帧(Unconditional Frame)
这是最常用的帧类型。主机发出帧头,指定的从机必须无条件回应数据。说白了就是「点对点」的通信。
应用场景:比如车门模块定期上报车窗位置。主机每次发这个ID,从机就得乖乖把数据填上。
我曾经在一个项目中,从机没及时准备好数据,结果总线上全是错误帧。后来我加了个超时机制,才把问题解决。
2.2.2 事件触发帧(Event Triggered Frame)
这个就有意思了。它允许从机在数据变化时才主动响应。主机发一个帧头,多个从机都可以抢着回应。如果只有一个从机回应,那就正常收数据。如果有多个从机同时回应,就会产生冲突,然后主机再逐个轮询。
你想想看,这像不像老师点名:「谁有问题?」——没人举手就跳过,有人举手就单独问。效率高多了。
我的建议:事件触发帧适合那些不常变化但变化时需要及时上报的信号。比如门锁状态、灯光开关。别用在频繁变化的信号上,否则冲突率太高,反而降低效率。
2.2.3 偶发帧(Sporadic Frame)
这个跟事件触发帧有点像,但角色反过来了。偶发帧是主机主动发的,但只在数据变化时才发。如果数据没变,主机就跳过这个帧,把时间留给其他帧。
说白了,偶发帧就是「看心情发」。我在做雨量传感器项目时就用过——下雨了才发数据,晴天就跳过。省带宽。
2.2.4 诊断帧(Diagnostic Frame)
诊断帧有固定的ID:0x3C和0x3D。0x3C是主机请求帧,0x3D是从机响应帧。它们遵循ISO 15765-2的传输协议,可以传输超过8个字节的数据。
我记得有一次,客户要求通过LIN刷写ECU固件。诊断帧就是干这个的。它支持分包传输,最大可以传4095个字节。
注意:诊断帧的优先级是最高的。因为诊断和刷写通常涉及安全相关功能。千万别在正常通信时占用诊断帧的ID,否则会出大问题。
2.3 帧ID与优先级:谁先说话?
LIN总线的帧ID范围是0x00到0x3F,一共64个。但ID越小,优先级越高。0x00优先级最高,0x3F最低。
为什么会这样?因为LIN总线仲裁是靠ID的显性位数量来决定的。ID小的帧,显性位出现得更早,自然就抢到了总线控制权。
我一般这样分配优先级:
| 优先级 | ID范围 | 典型用途 |
|---|---|---|
| 最高 | 0x00 - 0x0F | 诊断帧、安全相关信号 |
| 中 | 0x10 - 0x2F | 周期性控制信号(车窗、门锁) |
| 低 | 0x30 - 0x3F | 状态上报、传感器数据 |
避坑指南:我曾经在一个项目中,把雨量传感器的ID设成了0x01,结果它老是跟诊断帧抢总线。后来我改成0x35,世界就清净了。记住,ID分配不是随便写的,要结合调度表来规划。
2.4 小结一下
嗯,这一章内容不少。咱们捋一捋:
- LIN帧结构:Break + Sync + PID + Data + Checksum
- 四种帧类型:无条件帧(最常用)、事件触发帧(省带宽)、偶发帧(看心情)、诊断帧(高优先级)
- 帧ID越小,优先级越高。分配时要考虑调度表
下一章咱们会深入调度表的配置。到时候你会看到,这些帧类型和优先级是怎么在时间轴上排兵布阵的。准备好了吗?