LIN总线uart形式实现lin通信

LIN是Local Interconnect Network的缩写,是基于UART/SCI(Universal Asynchronous Receiver-Transmitter/Serial Communication Interface 通用异步收发器/串行通信接口)的低成本串行通信协议。可用于汽车、家电、办公设备等多种领域。在这里插入图片描述
这里不再多说lin的特点。这篇只讲LIN发送。

1、LIN协议层

帧的结构
Frame包含Header和Response两部分。主机负责发送帧头,从机任务接收并对帧头所包含信息进行解析,然后决定是发送应答还是接收应答,还是不作出反应。
在这里插入图片描述
帧头包括同步间隔段、同步段以及PID(Protected Identifier,受保护ID)段,应答包括数据段和校验和段,其中值“0”为显性电平(Dominant),值“1”为隐性电平(Recessive)
在这里插入图片描述
1.1同步间隔段(Break Field)
同步间隔段由同步间隔(Break)和同步间隔段间隔符(Break Delimiter)构成,同步间隔是至少持续13位的显性电平,Break Field是一个Frame开始的标志。同步间隔段间隔符是至少持续1位的隐性电平。
在这里插入图片描述
1.2同步段(Sync Byte Field)
这里有个字节域(Byte Field)概念,Byte Field包括1位Start Bit 显性,+8位data bit + 1位Stop Bit隐性,是一种标准的UART数据传输格式。在lin帧中,数据传输都是先发送LSB(least significan bit),最后发送MSB(Most Significant Bit, 最高有效位),LIN同步以下降沿位判断标志,采用字节0x55(二进制为 01010101b)。
在这里插入图片描述
1.3受保护ID段(Protected Identifier Field)
受保护ID段的前6位叫作帧ID(Frame ID),加上两个奇偶校验位后称作为受保护ID.
在这里插入图片描述
帧ID的范围在0x00~0x3F之间,共64个,奇偶校验位的校验公式如下
在这里插入图片描述
1.4数据段(Data Field)
节点发送的数据位于数据段,包含 1 到 8 个字节(注 1),先发送编号最低的字节 DATA1,编号依次增加
在这里插入图片描述
1.5校验和段(Checksum Field)
Checksum Field 是对帧中所传输的内容进行校验在这里插入图片描述
校验和分为标准型校验和(Classic Checksum)及增强型校验和(Enhanced Checksum)
在这里插入图片描述
例如:采用标准型校验和,Data1 = 0x4A,Data2 = 0x55,Data3 = 0x93,Data4 = 0xE5,计算方法如下
在这里插入图片描述

2、以下为一个小工装的部分代码

代码所用MCU为 stm32,源代码有点乱,只发部分,水平有限仅供参考

/*
*******************************************************************************************
*                          LIN总线分析头文件
* 文件名称:  LIN.h
* 版本号     : V0.9
* 编写人     : Andy.Wu
* 编写日期 :
*******************************************************************************************
*/
#ifndef __LIN_H
#define __LIN_H
/*******************************包含的文件******************************/
#include "main.h"

/*******************************宏定义************************************/
//#define  LIN_MODULE
#define BIT(A,B)      ((A>>B)&0x01)   
/*******************************数据类型定义***************************/

typedef struct
{
#define SYNC_BYTE_FIELD 0x55
#define LIN_BUFF_SIZE 8

#define LIN_PID_KEY    LIN_PID_32_0x20
#define LIN_PID_ACC    LIN_PID_33_0x21

	uint8_t length;
	uint8_t FrameSync;
	uint8_t FrameId;
	uint8_t FrameData[LIN_BUFF_SIZE];
}LinSendTypeDef;

/*******************************函数声明***************************/
void LIN_SendDataFrame(UART_HandleTypeDef *huart, LinSendTypeDef *LinMsg, uint8_t state);
#endif

LIN.c

/*
*******************************************************************************************
*                          LIN总线分析文件
* 文件名称:  LIN.c
* 版本号     : V0.9
* 编写人     : Andy.Wu
* 编写日期 :
*******************************************************************************************
*/

uint8_t LINCheckSumEn(uint8_t PID, uint8_t *buf, uint8_t lens)
{
    uint8_t i, ckm = 0;
    uint16_t chm1 = PID;
    for(i = 0; i < lens; i++)
    {
        chm1 += *(buf++);
    }
    ckm = chm1 / 256;
    ckm = ckm + chm1 % 256;
    ckm = 0xFF - ckm;
    return ckm;
}

//计算校验位
uint8_t LINCalcParity(uint8_t id)
{
  uint8_t parity, p0,p1;
  parity=id; 
  p0=(BIT(parity,0)^BIT(parity,1)^BIT(parity,2)^BIT(parity,4))<<6;     //偶校验位
  p1=(!(BIT(parity,1)^BIT(parity,3)^BIT(parity,4)^BIT(parity,5)))<<7;  //奇校验位
  parity|=(p0|p1);
  return parity;
}

//******************************************************************
// 函数: void LIN_SendSnycSeg(UART_HandleTypeDef *huart, LinSendTypeDef *LinMsg)
// 功能: 发送同步间隔段
// 输入: huart:UART_HandleTypeDef结构的指针;  LinMsg:LinSendTypeDef结构体的指针
// 输出: 无
//******************************************************************
void LIN_SendSnycSeg(UART_HandleTypeDef *huart, LinSendTypeDef *LinMsg)
{
	while(HAL_UART_Transmit_IT(huart, &(LinMsg->FrameSync), 1) != HAL_OK);
}
//******************************************************************
// 函数: void LIN_SendPID(UART_HandleTypeDef *huart, LinSendTypeDef *LinMsg)
// 功能: 发送PID
// 输入: huart:UART_HandleTypeDef结构的指针;  LinMsg:LinSendTypeDef结构体的指针
// 输出: 无
//******************************************************************
void LIN_SendPID(UART_HandleTypeDef *huart, LinSendTypeDef *LinMsg)
{
    uint8_t parity; 
	parity = LINCalcParity(LinMsg->FrameId);
	while(HAL_UART_Transmit_IT(huart, &parity, 1) != HAL_OK);
	//debug_printf("parity = 0x%x, ID = 0x%x\r\n", parity, LinMsg->FrameId);
}
//******************************************************************
// 函数: void LIN_SendData(UART_HandleTypeDef *huart, LinSendTypeDef *LinMsg)
// 功能: 发送数据内容
// 输入: huart:UART_HandleTypeDef结构的指针;  LinMsg:LinSendTypeDef结构体的指针
// 输出: 无
//******************************************************************
void LIN_SendData(UART_HandleTypeDef *huart, LinSendTypeDef *LinMsg) 	//uint8_t *buff, uint8_t len
{
	while(HAL_UART_Transmit_IT(huart, LinMsg->FrameData, LinMsg->length) != HAL_OK);
}
//******************************************************************
// 函数: void LIN_SendDataFrame(UART_HandleTypeDef *huart, LinSendTypeDef *LinMsg, uint8_t state)
// 功能: 发送数据内容校验和
// 输入: huart:UART_HandleTypeDef结构的指针;  LinMsg:LinSendTypeDef结构体的指针;state :状态
// 输出: 无
//******************************************************************
void LIN_SendDataFrame(UART_HandleTypeDef *huart, LinSendTypeDef *LinMsg, uint8_t state)
{
	uint8_t ckm;
    //uint8_t test[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
     if(state==LIN_KEY_ON)
    {
     
		LinMsg->FrameId = LIN_PID_KEY;
		LinMsg->FrameSync = SYNC_BYTE_FIELD;
		LinMsg->length = 4;
		LinMsg->FrameData[0] = 0;
		LinMsg->FrameData[1] = 0;
		LinMsg->FrameData[2] = 0;
		LinMsg->FrameData[3] = 0x05;
    }
	else if(state==LIN_KEY_OFF)
	{
		LinMsg->FrameId = LIN_PID_KEY;
		LinMsg->FrameSync = SYNC_BYTE_FIELD;
		LinMsg->length = 4;
		LinMsg->FrameData[0] = 0;
		LinMsg->FrameData[1] = 0;
		LinMsg->FrameData[2] = 0;
		LinMsg->FrameData[3] = 0x85;
	}
	
     
    while(HAL_LIN_SendBreak(huart) != HAL_OK);	//同步间隔段
	LIN_SendSnycSeg(huart, LinMsg);		        //同步段
	LIN_SendPID(huart, LinMsg);		        //受保护ID
	
    //LIN_SendHead(huart, LinMsg);
	LIN_SendData(huart, LinMsg); 
	
	ckm = LINCheckSumEn(LINCalcParity(LinMsg->FrameId), LinMsg->FrameData, LinMsg->length);		// Send checksum field
	while(HAL_UART_Transmit_IT(huart, &ckm, 1) != HAL_OK);
}

参考文献:《lin入门书》 RENESAS


版权声明:本文为weixin_43978088原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。