【简介】
在车载领域LIN通讯在整车的网路中经常会被使用,S32K3 芯片可以通过 lpuart 配置为LIN来实现LIN通讯功能。配置LIN功能前我们需要先配置硬件的端口为UART功能。
按照本地的硬件原理图在S32DS 中配置对应的端口为LPUART 功能。


在S32DS 配置工具中加入LIN 驱动。


配置开启LPURAT0 的中断

生成代码后LIN的驱动文件已经被加入到工程中。

本地添加如下的代码测试LIN 发送功能。
/** *****************************************************************************************************
* \file lin_driver.c *
* \brief *
* *
* <table> *
* <tr><th>Date <th>Version *
* <tr><td>2026/04/07 <td>1.0.0 *
* </table> *
*******************************************************************************************************/
/********************************************************************************************************
* Include header files *
*******************************************************************************************************/
#include "Lpuart_Lin_Ip.h"
#include <string.h>
#include <stdlib.h>
#include "data_trace.h"
#if (1 == CFG_FUNC_AUTO_INIT)
#include "func_init.h"
#endif
/*==================================================================================================
* LOCAL MACROS
*================================================================================================*/
#define DBG_ENABLE
#define DBG_TAG "LIN"
#define DBG_LEVEL DBG_LOG
#define DBG_COLOR
#include <rtdbg.h>
#define LIN_SEND_PID (0x1A)
#define LIN_RECV_PID (0x2B)
#define SEND 0
#define RECV 1
#define BUFFER_SIZE (8U)
/*==================================================================================================
* LOCAL CONSTANTS
*================================================================================================*/
/*==================================================================================================
* LOCAL FUNCTIONS
*================================================================================================*/
/*==================================================================================================
* LOCAL VARIABLES
*================================================================================================*/
static uint32_t LinSendCounter = 0;
static uint32_t LinRecvCounter = 0;
static uint8 LpuartTxBuff[BUFFER_SIZE] = {1,2,3,4,5,6,7,8}; /*The data to be send out*/
static uint8 *RxBuff; /*The point to receive the data*/
static Lpuart_Lin_Ip_PduType LinLpuartPdu[] =
{
{
.Pid = (uint8)LIN_SEND_PID,
.Cs = LPUART_LIN_IP_ENHANCED_CS,
.SduPtr = LpuartTxBuff,
.Drc = LPUART_LIN_IP_FRAMERESPONSE_TX,
.Dl = (uint8)BUFFER_SIZE
},
{
.Pid = (uint8)LIN_RECV_PID,
.Cs = LPUART_LIN_IP_ENHANCED_CS,
.SduPtr = NULL, /* This value should have been the Rx buffer.But it is not used by the driver. */
.Drc = LPUART_LIN_IP_FRAMERESPONSE_RX,
.Dl = (uint8)BUFFER_SIZE
}
};
/*==================================================================================================
* LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS)
*================================================================================================*/
/*==================================================================================================
* LOCAL FUNCTION PROTOTYPES
*================================================================================================*/
/*==================================================================================================
* GLOBAL VARIABLES
*================================================================================================*/
/*==================================================================================================
* GLOBAL CONSTANTS
*================================================================================================*/
/*==================================================================================================
* GLOBAL FUNCTIONS
*================================================================================================*/
void LinMasterCallback(uint8 Instance, Lpuart_Lin_Ip_StateStructType *LpuartStateStruct)
{
switch (LpuartStateStruct->CurrentEventId)
{
/* transmission ok */
case LPUART_LIN_IP_TX_COMPLETED:
/*add user code after LIN master completed transmission*/
LinSendCounter++;
LOG_I("LIN transmission completed %ld.", LinSendCounter);
break;
/* receiving ok */
case LPUART_LIN_IP_RX_COMPLETED:
/*add user code after LIN master completed receiving*/
LinRecvCounter++;
LOG_I("LIN reception completed %ld.", LinRecvCounter);
trace_byte_stream(RxBuff, 8, 0);
break;
default:
/* do nothing */
break;
}
}
static int lin_init(void)
{
Lpuart_Lin_Ip_StatusType ret;
/* Init LIN master */
ret = Lpuart_Lin_Ip_Init(Lpuart_Lin_Ip_Sa_pxHwConfigPB_0.Instance, &Lpuart_Lin_Ip_Sa_pxHwConfigPB_0);
if(ret == LPUART_LIN_IP_STATUS_SUCCESS)
{
LOG_I("LIN init OK.");
}
else
{
LOG_E("LIN init failed %x.", ret);
}
return 1;
}
unsigned int lin(char argc, char **argv)
{
uint32 TimeoutValue = 4*400000U;
uint8 *DummyBuffer;
volatile Lpuart_Lin_Ip_TransferStatusType LpuartMasterStatus = LPUART_LIN_IP_STATUS_OPERATIONAL;
if(argc == 2 && strcmp(argv[1], "init") == 0)
{
lin_init();
}
else if(argc == 2 && strcmp(argv[1], "send") == 0)
{
/* Start of the sending frame from Lpuart Master*/
Lpuart_Lin_Ip_SendFrame(Lpuart_Lin_Ip_Sa_pxHwConfigPB_0.Instance, &LinLpuartPdu[SEND]);
/*Wait for the transmission done */
do
{
LpuartMasterStatus = Lpuart_Lin_Ip_GetStatus(Lpuart_Lin_Ip_Sa_pxHwConfigPB_0.Instance, (const uint8 **)&DummyBuffer);
}
while ((LPUART_LIN_IP_STATUS_TX_OK != LpuartMasterStatus) && (TimeoutValue-- > 1));
}
else if(argc == 2 && strcmp(argv[1], "recv") == 0)
{
/* Start of the sending frame from Lpuart Master*/
Lpuart_Lin_Ip_SendFrame(Lpuart_Lin_Ip_Sa_pxHwConfigPB_0.Instance, &LinLpuartPdu[RECV]);
/*Wait for the receiving done */
do
{
/*The Rx buffer is obtained here*/
LpuartMasterStatus = Lpuart_Lin_Ip_GetStatus(Lpuart_Lin_Ip_Sa_pxHwConfigPB_0.Instance, (const uint8 **)&RxBuff);
}
while ((LPUART_LIN_IP_STATUS_RX_OK != LpuartMasterStatus) && (TimeoutValue-- > 1));
}
else
{
PRINTF("Invalid command. Usage: lin init|send|recv\n");
}
return 0;
}
本地出发 lin 的初始化和 发送接口函数执行成功,并在LIN slave端成功接收到消息数据。


LIN 接收0X2B 的数据帧从slave 节点接收数据。

上述log 和LIN trace 的数据也是能够匹配的。

本地LIN 收/发 穿插验证trace 上的数据和本地收发的也是保持一致的。

我要赚赏金
