LIN总线⼊门
LIN总线是⽬前常见的⼀种A类⽹络协议。LIN的全称为Local Interconnect Network。LIN主要功能是为CAN总线⽹络提供辅助功能,应⽤场合有智能传感节点、⾃动车窗节点等。⽬前最新的LIN协议是LIN2.2,制定于2010年。LIN的⼀⼤优点是成本低,但其最⼤传输速率为
20Kbps。建议的通信速率如下,低速2400bps,中速9600bps,⾼速19200bps。根据OSI参考模型,LIN总线仅规范了数据链路层和物理层。
LIN的部分应⽤
LIN的特点如下:
1.采⽤单主多从的组⽹⽅式,⽆CAN总线那样的仲裁机制,最多可连接16个节点(1主15从)。
2.对硬件要求简单,仅需UART/SCI 接⼝,辅以简单驱动程序便可实现 LIN 协议。故⼏乎所有的MCU均⽀持LIN。
3.不需要单独的晶振,便能完成主、从节点的同步,硬件成本⼤幅降低。
4.仅使⽤⼀根信号线便可完成信息的传输,即所谓的单总线设备。
5.传输速率最⾼可达20Kbps,符合A类⽹络标准,满⾜车⾝控制需要。
6.LIN ⽹络中新节点的加⼊,对⽹络中其他原有节点的软硬件设计不会造成影响。
LIN⽹络主从节点的功能
LIN⽹络中的节点任务分为主机任务和从机任务两类。其中,主机任务只在主机节点上运⾏,⽽从机任务在主机节点和从机节点上均可运⾏。也就是说,主机节点可以实现主机任务和从机任务。
A.主机任务主要执⾏以下功能:
1.定义总线上的通信速率。(同步场?待考)
2.发送报⽂帧头,包含同步间隔场、同步场和标识符场三个部分。
3.监控总线通信,通过校验和确定数据正确性与否。
4.使从机进⼊唤醒或睡眠状态,并响应从机的唤醒要求。
B.从机任务既可运⾏于主机⼜可运⾏于从机,它主要完成以下功能:
1.等待主机任务发送的同步间隔,使从机与主机于同步场中获得同步。
2.分析标识符场,若与⾃⼰相关,则接收或发送数据,若与⾃⼰⽆关则什么都不做。
3.检查和发送校验和。
4.接受主机任务的唤醒和睡眠请求。
综上,主机报⽂的标识符能触发与之对应的不同从机之间的通信。
LIN报⽂的帧结构
LIN 总线上具有“显性”和“隐性”两种互补的逻辑电平。其中,显性电平(参考地电压)是逻辑 0,隐性电平(电源电压)是逻辑1。
LIN在总线上以具有固定格式的报⽂进⾏传递,但是这种报⽂数据段的长度是可以调整的。LIN⽹络中的所有节点(包括主机节点)都具有从机任务,当接到主机任务的报⽂信息时,它们中的某⼀个要对报⽂做出响应。
报⽂头仅可以由主机节点发出
LIN总线的⼀帧主要由两部分组成,即报⽂头(Header)和报⽂响应(Response)。其中,报⽂头是
由⼀个主机节点的主机任务发出的,⽽报⽂响应(以下简称响应)是由⼀个主机节点或从机节点的从机任务发出的。其中报⽂头由同步间隔场(最⼩13个显性位)、同步场(1个字节,数据不变,0x55)、和PID场(1个字节)三部分组成;报⽂响应由2/4/8个字节的数据场、校验和场(1个字节)所组成。报⽂头和响应之间有⼀个帧内空间分隔,最⼩空间为0。
LIN的帧结构(英⽂版)
LIN的帧结构(彩图版)LIN的帧结构
⽰波器采出来的LIN波形,能看出0x00和0x55
LIN 的字节场格式就是通常的“SCI”或“UART”串⾏数据格式(N81编码)。即每个字节场的长度是10个位定时(BIT TIME):1bit起始位+8bits数据位+1bit停⽌位。
起始位(START BIT)是⼀个“显性”位,它标志着字节场的开始。接着是8个数据位,⾸先发送最低位。停⽌位(STOP BIT)是⼀个“隐性”位,它标志着字节场的结束。LIN报⽂帧中的同步场、标识符场、数据场、校验和场的格式都符合上述字节场的格式。
下⾯对⼏个重要的部分详细说明。
同步间隔场
间隔场是唯⼀⼀个不符合字节场格式的场。从节点需要检测到⾄少连续11个显性位才认为是间隔信号。
同步场
⼀个字节,即0x55。
LIN的被保护标识符场(PID场)
PID场定义了报⽂的内容和长度。如图,PID场分为6个标识符位和2个ID奇偶校验位。6个标识符位我们称之为ID。如果加上2个奇偶校验位就变成PID了,即Protected ID。6个标识符位中,标识符后两位为数据长度控制位。总的来看,ID的范围是0-0x3F。注意是ID,不是PID。要区分开。这⼀段要讲的是我们需要将LIN的ID与PID分清楚,不能混淆。
上图中的ID4和ID5为数据长度控制位(ID4是低位)。值为00或10时,数据长度为2个字节。值为01时,数据长度为4个字节。值为11时,数据长度为8个字节。在实际应⽤中,我并没有发现ID4和ID5与真实的数据长度有什么关系。接触到的LIN报⽂均为8个字节的数据。
P0和P1为奇偶校验位,算法如下:
#include <stdio.h>
#include <windows.h>
int main()
{
short p0=0,p1=0;
short LIN_ID=0x22,PID=0x00;
p0 = (LIN_ID & 0x01) ^ ((LIN_ID & 0x02) >> 1) ^ ((LIN_ID & 0x04) >> 2) ^ ((LIN_ID & 0x10) >> 4); //按位异或
p0 = p0 & 0x01;
p1 = ~(((LIN_ID & 0x02) >> 1) ^ ((LIN_ID & 0x08) >> 3) ^ ((LIN_ID & 0x10) >> 4) ^ ((LIN_ID & 0x20) >> 5));
p1 = p1 & 0x01;
PID = (p1 << 7) | (p0 << 6) | LIN_ID;
printf("p0=%#x,p1=%#x,PID=%#X\n",p0,p1,PID);
system("pause");
return 0;
}
所谓奇偶校验就是在发送的每⼀个字节后都加上⼀位,使得每个字节中1的个数为奇数个或偶数个。接收⽅通过计算数据中1的个数是否满⾜奇偶性来确定数据是否有错。这个不⽤背,⽤的时候可以查表。
数据场
数据场主要需注意每个字节先传输的是最低位。即如果某⼀信号长度超过1个字节,采⽤低位在前的⽅式发送(⼩端)。
校验和场(checksum)
校验和场是数据场所有字节的和的反码。所有数据字节的和的补码,与校验和字节相加所得的和必须是0xFF。
算法(Classical):累加所有字节。对每次加和进⾏判断,如果和⼤于0xFF,那么就把⾼⼋位的1,与低⼋位相加,其实就是低⼋位加
1(翻转⼋位和)。得到最后的结果后,取其反码,我们就得到了最后的校验和。参照下图理解⼀下。
如何算出LIN的校验和场
讲解⼀下上⾯的图,0x4A+0x55 = 0x9F这个没有疑问,再加0x93 = 0x132,很明显,超过了0xFF,分解为0x1和0x32,突出的⾼8位删除,加到低8位中,0x1+0x32=0x33。再加0xE5 = 0x118,⼜超了,0x1+0x18=0x19。取反(Not),0xE6。
练习:下图是⼀些LIN总线数据,以最后⼀组为例,2个0xFF之和为0x1FE,处理后仍然为0xFF。故8个0xFF加和之后仍为0xFF,取反码为0x00。
⼀组LIN报⽂
校验和场的两种类型
校验和场通常会有两种不同的类型,英⽂简称为CST(Checksum Type)。⼀种是classic checksum(LIN 1.3),⼀种是enhanced checksum(LIN 2.0及以上)。上⽂讲到的校验和场算法实际上是classic
的,即只对Data(数据场)进⾏校验和的计算。Enhanced Checksum 在计算时需要把PID也加⼊到计算队列中。
9600波特率下,ChecksumType为classic
下图是CST(校验和类型)为Enhanced时的报⽂形态。此时校验和的计算需要包含前⾯的PID字节。举例,下图中第⼀帧报⽂,ID为
0x02,PID通过查表(参考⽂献5)可得到对应的PID是0x42,0x42的反码是0xBD。原理上⼀样,只不过计算校验和的时候,需要把PID也放进去。
PLIN-USB收到的LIN报⽂,很详细
这⾥有个知识点⼀定要注意:标识符为0x3C和0x3D的帧只能使⽤经典校验,这两组帧是LIN的诊断帧。即LIN 2.0及以上才有的诊断帧,需要使⽤经典校验,不能将PID也加⼊到校验计算序列。⾃⼰写LIN驱动的⼩伙伴要格外注意。
⽤Kvaser收到的第⼀个LIN报⽂
LIN总线的布线组⽹
LIN⽹络的节点数量不应超过16个,否则节点增加将减少⽹络阻抗,会导致环境条件变差,从⽽不能进⾏正常的⽆错误通讯。BOSCH汽车电⽓与电⼦中这样描述,“LIN总线规范中没有规定总线允许的最⼤节点数。......但实际应⽤中,为了保证数据传输的可靠性,总线允许的最⼤节点数为16个。“
实验证明(该实验需要考证),每增加⼀个节点,就会减少约3%的阻抗;⽹络中的通讯导线长度应⼩于或等于40m;主机节点的总线端电阻典型值是1kΩ,从机节点是30 kΩ。
LIN总线的应⽤
LIN总线上可以传输的两类数据,信号报⽂和诊断报⽂。
诊断报⽂的输送是在具有两个保留标识符的帧⾥⾯完成的。数据场的判读取决于数据场本⾝以及通讯节点的状态。
LIN具有调度表机制。调度表负责调度⽹络各报⽂发送的顺序。调度表在⽹络系统设计阶段确定。调度表使得LIN通信具有可预测性。主任务可以拥有多个调度表,并在不同的调度表之间切换。
LIN的描述⽂件叫做LDF⽂件,可以设置报⽂帧,信号和调度表等。
LIN帧的分类
LIN帧按照帧类型来分类可以分为普通帧、事件触发帧、零星帧、诊断帧、⽤户⾃定义帧和保留帧。
普通帧的标识符(ID)为0到0x3B。主任务发出报⽂头,⼀个任务响应,⼀个或多个任务接收。
事件触发帧的标识符为0到0x3B。事件触发帧必须有⼀个独⽴的ID,该ID可以与多个普通帧相关联。在事件触发帧时隙内发送帧头,只有当相关联的⽆条件帧内有信号被更新时,才发送帧响应。帧响应的第⼀个数据字节等于标识符,即响应最多可以传输7个字节的数据;如果没有帧响应,帧头被忽略。帧响应可由多个节点发送,发⽣冲突时切换到“冲突解决调度表”,之后再切换回到原来的调度表。
零星帧表⽰共⽤⼀个时隙、在需要时才被发送的⼀组普通帧。标识符为0到0x3B。
诊断帧⽤来传输诊断或配置信息,⼀般包含8个字节数据。0x3C为主请求帧,0x3D为从响应帧(注意校验⽅式是classic!)。诊断响应基于ISO15765-2传输层和ISO14229应⽤层。
诊断帧
⽤户⾃定义帧标识符为0x3E,可以传输任何⽤户⾃定义的信息。
保留帧的标识符为0x3F。略。
关于LIN的版本
LIN2.0新增加了下列属性:“增强校验和(Enhanced)”、“重新配置和诊断”、“波特率⾃动探测”、“响应错误状态监控”。LIN2.0从机节点⽆法与LIN1.3主机节点操作。
关于睡眠
主节点可以发送⼀帧ID为0x3c,第⼀个字节为零的主请求帧来使处于⼯作状态的从节点进⼊睡眠。这帧报⽂称为睡眠指令。
从节点在接到睡眠指令之后,也可以选择不进⼊睡眠状态⽽继续⼯作,这根据应⽤层协议⽽定。
当总线空闲4到10秒的时候,所有从节点必须进⼊睡眠状态。(注:空闲的定义是没有显性位和隐性位之间的转换。)
关于唤醒
汽车入门
在⼀个处于睡眠状态的LIN⽹络中,任何⼀个节点都可以发送唤醒信号。
唤醒信号是⼀个250us到5ms的显性电平。
问题:这⾥的唤醒信号可否按照恒润的教程理解为在20Kbit/s波特率下的0x0F,或在1Kbit/s波特率下的0x0F?
当从节点发出唤醒信号之后150ms,主节点仍未发送报头时,从节点可以再次发送唤醒信号。当连续发送了3次唤醒信号之后如果主节点仍未发送报头,从节点要等待1.5秒以后才可以再次发送唤醒信号。
关于LIN的基础知识先介绍到这⾥。推荐⼀个帖⼦:《⽩话LIN总线》,很⽣动形象!
上的消息显⽰称,LIN2.2A为最后⼀版⾮ISO的LIN总线标准。
LIN总线最新的specification(规范)将会是ISO 17987 Part 1-7 中的⼀部分。