3、LIN总线协议基础:帧结构详解
各位同学,今天我们进入LIN总线最核心的部分——帧结构。说实话,很多工程师学了几年LIN,遇到通信问题还是抓瞎,根本原因就是对帧结构理解不透。我当年刚入行时也吃过这个亏,后来亲手抓了几百次波形,才算真正搞明白。
一个完整的LIN帧,由六个场组成:同步间隔场、同步场、标识符场、数据场、校验和场。咱们一个一个来拆解。
3.1 同步间隔场(Break Field)
这是帧的起始信号。主节点会强制拉低总线至少13个位时间(bit time)。为什么是13?因为LIN规范要求从节点检测到连续11个显性位就认为是同步间隔。我习惯留点余量,所以实际项目中我一般配置成14-15个位时间。
关键参数:
- 同步间隔长度:13-26个位时间(推荐13-15)
- 同步间隔分隔符:至少1个位时间的隐性电平
⚠ 我曾经踩过的坑: 有次量产时发现部分从节点偶尔无法同步,抓波形才发现同步间隔只有12个位时间。有些芯片的检测阈值比较严格,12位就是临界值。从那以后,我所有项目都强制配置为14位,再没出过问题。
3.2 同步场(Sync Field)
同步场的格式固定为 0x55,二进制就是 01010101。你想想看,这个波形在总线上就是方波,高低电平交替。从节点就靠这个来校准自己的波特率。
为什么会这样设计?因为LIN总线没有独立的时钟线,所有从节点必须通过同步场来测量主节点的位时间。说白了,这就是一个「时钟校准信号」。
我记得有个项目,客户抱怨通信偶尔出错。排查后发现是晶振偏差太大,从节点用同步场算出来的波特率跟主节点差了3%以上。LIN规范要求容差2%以内,所以后来我建议客户换更高精度的晶振。
3.3 标识符场(Identifier Field, PID)
标识符场占1个字节,但真正有用的只有6位(ID0-ID5),最高两位是奇偶校验位。
| 位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| 含义 | P1 | P0 | ID5 | ID4 | ID3 | ID2 | ID1 | ID0 |
这里有个容易混淆的地方:标识符范围是0x00-0x3F,共64个。但0x3D和0x3E被保留用于诊断,实际可用的是62个。我建议大家在设计系统时,把标识符规划好,别随便用。
💡 个人经验: 标识符的奇偶校验位计算方式如下:
P0 = ID0 ⊕ ID1 ⊕ ID2 ⊕ ID3 ⊕ ID4
P1 = !(ID1 ⊕ ID2 ⊕ ID3 ⊕ ID4 ⊕ ID5)
我习惯在代码里用查表法,比实时计算快得多。
3.4 数据场(Data Field)
数据场长度1-8字节,具体由标识符决定。注意,LIN 2.x规范中,数据长度由标识符的ID4和ID5位编码决定,而不是像CAN那样由DLC字段指定。
嗯,这里要注意:数据场采用LSB优先传输。也就是说,每个字节的最低位先发。我刚开始做LIN驱动时,就因为这个搞反了字节顺序,调试了两天才发现。
数据长度编码规则:
- ID4=0, ID5=0 → 2字节数据
- ID4=0, ID5=1 → 2字节数据
- ID4=1, ID5=0 → 4字节数据
- ID4=1, ID5=1 → 8字节数据
3.5 校验和场(Checksum Field)
校验和分两种:经典校验和(LIN 1.x)和增强校验和(LIN 2.x)。
经典校验和: 只对数据场做校验。
增强校验和: 对数据场+标识符场一起做校验。
计算方法是:把所有字节相加,取低8位,然后取反。说白了就是「和的反码」。
// 增强校验和计算示例
uint8_t lin_checksum(uint8_t pid, uint8_t *data, uint8_t len)
{
uint16_t sum = pid; // 包含标识符
for(uint8_t i = 0; i < len; i++)
{
sum += data[i];
if(sum > 0xFF)
{
sum -= 0xFF; // 进位回卷
}
}
return (uint8_t)(~sum);
}
⚠ 避坑指南: 我曾经在一个项目中,从节点用的是LIN 1.x协议,主节点升级到LIN 2.x后,校验和一直报错。原因是主节点用了增强校验和,而从节点还在用经典校验和。所以,同一个网络里,校验和方式必须统一。
3.6 帧结构总结
咱们把整个帧结构串起来看看:
| 场名称 | 长度 | 发送者 | 说明 |
|---|---|---|---|
| 同步间隔场 | 13+位时间 | 主节点 | 帧起始标志 |
| 同步场 | 1字节 | 主节点 | 0x55,用于时钟校准 |
| 标识符场 | 1字节 | 主节点 | 含6位ID+2位奇偶校验 |
| 数据场 | 1-8字节 | 主/从节点 | LSB优先传输 |
| 校验和场 | 1字节 | 主/从节点 | 经典或增强校验 |
你想想看,整个帧结构其实很简洁。主节点负责发起同步间隔、同步场和标识符,然后根据标识符决定是自己发数据还是让从节点发数据。从节点只需要监听总线,匹配到自己的标识符就响应。
我个人觉得,LIN协议的精髓就在于「简单」。它不像CAN那么复杂,但足够应对车身低速控制场景。只要把帧结构吃透了,后面学调度表、状态机什么的就轻松多了。
下一章咱们聊聊LIN的通信调度,也就是主节点怎么安排各个帧的发送时机。到时候我会拿一个实际的车窗控制案例来讲解,敬请期待。