这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 行业应用 » 汽车电子 » 【S32K3XX】LIN 通讯模块使用

共2条 1/1 1 跳转至

【S32K3XX】LIN 通讯模块使用

高工
2026-04-07 08:37:21     打赏

【简介】

在车载领域LIN通讯在整车的网路中经常会被使用,S32K3 芯片可以通过 lpuart 配置为LIN来实现LIN通讯功能。配置LIN功能前我们需要先配置硬件的端口为UART功能。

按照本地的硬件原理图在S32DS 中配置对应的端口为LPUART 功能。

image.png

image.png

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

image.png

image.png

配置开启LPURAT0 的中断

image.png

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

image.png

本地添加如下的代码测试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端成功接收到消息数据。

image.png

image.png

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

image.png

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

image.png

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

image.png



           


院士
2026-04-07 17:38:31     打赏
2楼

谢谢分享。


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]