2、LIN协议规范:帧结构
各位工程师朋友,咱们今天来聊聊LIN协议里最核心的东西——帧结构。说实话,我刚接触LIN的时候,觉得这东西比CAN简单多了,帧结构就那么几个字段,背下来就行了。结果呢?第一次调试就栽了跟头——同步间隔场长度不对,整个网络都不响应。从那以后,我老老实实把每个字段都吃透了。
LIN的帧结构,说白了就是主机发送一个“头”,从机响应一个“响应”。这个头包含同步间隔场、同步场和标识符场;响应则包含数据场和校验和场。咱们一个一个来看。
2.1 同步间隔场(Synch Break Field)
这是帧的起始信号。主机把总线拉低至少13个位时间(Tbit),从机检测到这个低电平就知道“要开始一帧了”。
关键参数:
- 同步间隔场长度:13~26个Tbit(推荐13~15)
- 同步间隔分隔符:至少1个Tbit的高电平
我个人习惯把同步间隔场设成14个Tbit。为什么?因为有些从机芯片的检测阈值是11个Tbit,留点余量更稳妥。我在项目里遇到过某款从机,标称支持13个Tbit,但实际测试时偶尔会漏检。后来我把间隔场拉到15个Tbit,问题就解决了。
避坑指南:我曾经因为同步间隔场长度不够,导致整个LIN网络间歇性通信失败。排查了整整两天,最后用示波器一看——间隔场只有11个Tbit。记住:宁长勿短。
2.2 同步场(Synch Field)
同步场的值固定为0x55(二进制01010101)。从机通过这个字节来校准自己的位时钟。说白了,就是让从机知道“主机的1位时间到底多长”。
你想想看,LIN总线没有单独的时钟线,全靠这个同步场来对齐。如果从机的晶振偏差大,或者波特率设置不对,同步场就校准不过来。嗯,这里要注意:LIN规范要求从机容差±2%,但实际项目中我建议按±1.5%来设计。
2.3 标识符场(Protected Identifier Field)
标识符场由两部分组成:6位ID + 2位奇偶校验。所以它也叫PID(Protected ID)。
| 位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| 含义 | P1 | P0 | ID5~ID0 | |||||
ID范围是0x00~0x3F(共64个)。其中:
- 0x00~0x3B:用于无条件帧、事件触发帧、偶发帧
- 0x3C~0x3D:用于诊断帧(Master Request / Slave Response)
- 0x3E~0x3F:保留
奇偶校验的计算方法我就不列公式了,直接给个经验:用查表法最省事。我在代码里放了一个64字节的校验表,运行时直接查,比实时计算快得多。
小技巧:调试时可以用示波器抓PID字节,手动算一下奇偶位对不对。我曾经用这个方法抓到一个从机ID配置错误的问题——它把ID=0x15配成了0x25,奇偶校验自然对不上。
2.4 数据场(Data Field)
数据场包含1~8个字节。具体长度由LDF(LIN描述文件)定义,不是由帧本身决定的。这一点和CAN不同——CAN帧里有个DLC字段告诉你要发多少字节,LIN没有,全靠配置。
我刚开始做LIN时犯过一个低级错误:从机收到帧后,按收到的字节数来解析数据。结果主机发了3个字节,从机却按4个字节解析,数据全乱了。后来才明白:数据长度是LDF里写死的,收发双方必须一致。
数据场注意事项:
- 字节顺序:低字节在前(Little-Endian)
- 信号可以跨字节:比如一个12位的信号,可以占用Byte0的低4位和Byte1的高8位
- 未使用的位:建议填0,但接收方不应依赖这个值
2.5 校验和场(Checksum Field)
LIN协议有两种校验和:经典校验和(Classic Checksum)和增强校验和(Enhanced Checksum)。
| 类型 | 计算范围 | 适用版本 |
|---|---|---|
| 经典校验和 | 仅数据场 | LIN 1.x |
| 增强校验和 | 数据场 + PID | LIN 2.x |
增强校验和把PID也纳入计算,能检测到ID传错的情况。我个人建议:新项目一律用增强校验和。除非你要兼容老设备,否则别用经典校验和。
校验和的计算方法是:把所有字节相加,取反,然后取低8位。举个例子:
// 假设数据场为 0x01, 0x02, 0x03,PID=0x15
// 增强校验和计算:
sum = 0x15 + 0x01 + 0x02 + 0x03 = 0x1B
checksum = ~0x1B & 0xFF = 0xE4
注意:我曾经遇到一个从机,校验和总是算不对。查了半天,发现它把PID的奇偶校验位也算进去了。记住:PID是8位的,但校验和计算时用的是完整的PID字节(含奇偶位),不是只取6位ID。
2.6 帧类型
LIN协议定义了四种帧类型,每种都有自己的用途。我按使用频率来介绍。
2.6.1 无条件帧(Unconditional Frame)
这是最常用的帧类型。主机发送帧头,指定的从机必须发送响应。不管数据有没有变化,只要到了调度时间,就得发。
说白了,这就是LIN网络里的“例行汇报”。比如温度传感器,每100ms上报一次当前温度,就用无条件帧。
2.6.2 事件触发帧(Event Triggered Frame)
这个有点意思。多个从机共享同一个ID,但只有数据变化时才响应。如果多个从机同时响应,就会发生冲突,然后主机再通过无条件帧逐个询问。
我在项目中用事件触发帧做过车门状态监测。四个车门的状态变化不频繁,但一旦变化需要立即上报。用事件触发帧,平时总线很安静,有事件时快速响应。不过要注意:冲突处理会增加延迟,实时性要求高的场景慎用。
2.6.3 偶发帧(Sporadic Frame)
偶发帧是主机主动发送的。主机在空闲时,检查有没有需要发送的偶发帧数据,有就发,没有就跳过。
你想想看,这和事件触发帧有什么区别?事件触发帧是从机主动上报,偶发帧是主机主动下发。比如主机要更新某个参数,就用偶发帧。
2.6.4 诊断帧(Diagnostic Frame)
诊断帧使用固定的ID:0x3C(主机请求)和0x3D(从机响应)。数据场固定为8个字节,遵循ISO 14229(UDS)协议。
诊断帧用于:
- 读取/写入从机参数
- 执行诊断服务(如DTC读取、例程控制)
- 从机节点配置
经验之谈:诊断帧的优先级最低。在调度表中,诊断帧通常放在最后,或者只在总线空闲时发送。我曾经在一个项目里把诊断帧的调度间隔设得太短,结果正常通信都被挤占了。
2.7 帧结构总览
说了这么多,咱们用一张图来总结一下LIN帧的完整结构:
这张图把帧结构和帧类型放在一起了。你看,四种帧类型共享相同的帧头结构,区别在于响应的触发方式和数据内容。无条件帧是“定时定点”的例行通信,事件触发帧是“按需上报”,偶发帧是“有空就发”,诊断帧则是“特殊用途”。
好了,帧结构这部分就讲到这里。记住:同步间隔场别太短,校验和用增强型,数据长度要跟LDF一致。做到这三点,大部分通信问题都能避免。
可可精品资料库