2、LIN总线协议基础:帧结构与帧类型
好,咱们今天聊聊LIN总线的帧结构。说实话,刚接触LIN的时候,我觉得它比CAN简单太多了。但用久了才发现,简单归简单,坑也不少。
LIN总线上的通信,说白了就是主节点发号施令,从节点乖乖响应。每个消息就是一帧数据。那这一帧里到底装了些什么?我带你拆开看看。
2.1 帧结构:六个场,一个都不能少
一个完整的LIN帧,由六个部分组成。我习惯把它们分成“头”和“响应”两段。主节点负责发“头”,从节点负责发“响应”。
| 场名称 | 字节数 | 发送方 | 说明 |
|---|---|---|---|
| 同步间隔场 | 至少13位显性 | 主节点 | 唤醒总线,标识帧开始 |
| 同步场 | 1字节 (0x55) | 主节点 | 从节点用它校准时钟 |
| 标识符场 | 1字节 | 主节点 | 决定谁来响应、数据长度 |
| 数据场 | 1~8字节 | 发送节点 | 真正的数据内容 |
| 校验和场 | 1字节 | 发送节点 | 检查数据是否传错 |
2.1.1 同步间隔场
这是帧的“起跑线”。主节点会把总线拉低至少13个位时间。为什么是13?因为正常的字节传输最多也就10个位(1起始+8数据+1停止),13个连续的显性位,从节点一看就知道:哦,新的一帧开始了。
我曾经遇到过一个坑:某个从节点的晶振偏差太大,13位的间隔它愣是没识别出来。后来我查了规范,建议间隔场至少18位才保险。嗯,从此我设计时都按18位来。
2.1.2 同步场
同步场固定是 0x55,也就是二进制 01010101。为什么选这个值?你想想看,它刚好是高低电平交替,从节点可以用它来测量主节点的位时间,校准自己的时钟。
说白了,这就是一个“时钟校准信号”。没有它,从节点可能因为晶振偏差而读错数据。我个人习惯在调试时先抓一下同步场的波形,看看从节点有没有正确同步。
2.1.3 标识符场
标识符场只有1个字节,但信息量不小。它包含:
- 6位ID:取值范围0~63,决定消息的身份
- 2位奇偶校验:保证ID传输正确
这里有个关键点:ID不仅决定了消息是谁的,还隐含了数据长度。比如ID 0x00~0x3F,每个ID都对应一个固定的数据字节数(2、4或8字节)。这个映射关系在LDF文件里定义好了。
重点:标识符场里的奇偶校验是硬件自动计算的,你不需要手动处理。但如果你用软件模拟LIN主节点,就得自己算一下。
2.1.4 数据场
数据场就是真正要传的信息了。1到8个字节,具体长度由ID决定。比如车门模块的ID可能只传2个字节(状态+校验),而车窗模块可能要传4个字节(位置、速度、电流、温度)。
我在项目中遇到过一个问题:某个从节点总是丢数据。查了半天,发现是数据场发送时,字节间的间隔太长了。LIN规范要求字节间间隔不能超过一个位时间。嗯,这个细节很容易被忽略。
2.1.5 校验和场
校验和分两种:经典校验和(Classic Checksum)和增强校验和(Enhanced Checksum)。
- 经典校验和:只对数据场做校验
- 增强校验和:对数据场+标识符场一起做校验
LIN 2.0以后,诊断帧必须用增强校验和。其他帧可以选。我建议统一用增强校验和,省得后面出问题还要排查。
小技巧:校验和的计算方法是:把所有字节加起来,取反,再取低8位。你可以用C语言写个函数,几行代码就搞定了。
2.2 帧类型:四种角色,各司其职
LIN总线定义了四种帧类型。说实话,日常开发中用得最多的就是无条件帧和诊断帧。事件触发帧和偶发帧,我做了这么多年项目,也就用过几次。
2.2.1 无条件帧
这是最基础的帧类型。主节点发出帧头,不管有没有从节点响应,它都会发。从节点根据ID判断:如果ID是自己的,就乖乖发响应。
举个例子:车门状态帧,ID=0x10,数据长度2字节。主节点每隔10ms发一次这个帧头,车门模块收到后,就把门锁状态、车窗位置发回来。
我习惯把所有周期性信号都用无条件帧实现。简单、可靠、好调试。
2.2.2 事件触发帧
这个就有点意思了。它用于多个从节点共享同一个ID的场景。平时主节点不发这个帧,只有当某个从节点有事件发生时,它才会主动请求。
但有个问题:如果两个从节点同时响应,就会冲突。所以事件触发帧的数据场里,第一个字节必须是发送节点的ID(从节点ID,不是消息ID)。主节点收到后,就知道是谁发的了。
注意:事件触发帧的冲突概率虽然低,但一旦发生,数据就丢了。所以关键信号别用事件触发帧,用无条件帧更稳妥。
2.2.3 偶发帧
偶发帧,说白了就是“有条件才发的无条件帧”。它有一个固定的调度表,但只有当数据发生变化时,才真正发送。
比如温度传感器,温度变化很慢,没必要每10ms发一次。用偶发帧,只有温度变化超过1度时才发。这样能节省总线带宽。
我记得有一次,客户要求降低总线负载率。我把几个周期性信号改成偶发帧,负载率直接从40%降到了15%。效果立竿见影。
2.2.4 诊断帧
诊断帧是LIN总线的“医生”。它使用固定的ID:
- 主节点请求帧:ID=0x3C,主节点发
- 从节点响应帧:ID=0x3D,从节点发
诊断帧的数据场固定8个字节,格式遵循ISO 15765-2(也就是UDS on LIN)。比如读取故障码、写入配置参数,都通过诊断帧完成。
我在项目中最常用诊断帧做两件事:一是产线终检时刷写配置参数,二是售后排查问题时读取故障码。嗯,诊断帧真的是开发调试的利器。
2.3 避坑指南
最后分享几个我踩过的坑:
- 同步间隔场长度:别卡着13位的下限,留点余量,用18位以上
- 校验和类型:统一用增强校验和,别混用
- 事件触发帧:别用于关键信号,冲突丢数据是常态
- 诊断帧:记得用增强校验和,否则从节点不认
好了,这一章的内容就到这里。下一章我们聊聊LIN的调度表,看看主节点是怎么安排这些帧的发送顺序的。