S32K144 LIN通讯

Master配置

添加lin模块,配置成MASTER,lin使用的是LPUART的通道资源,所以LPUART的引脚需要配置,另外LIN的超时需要定时器,再配一个500us的定时器,详细配置可以自己更改;

在这里插入图片描述
在这里插入图片描述

时钟和引脚相关配置不再说明,只贴lin相关的代码;
#define LIN1_RECV_STATUS_ID     (1U)
#define LIN1_SEND_STATUS_ID     (2U)
#define TIMER_COMPARE_VAL (uint16_t)(2000U)
#define TIMER_TICKS_1US   (uint16_t)(4U)
#define TIMEOUT             (500U)

uint8_t lin_master_txbuf[8] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7};
uint8_t lin_master_rxbuf[8] = {0};
uint16_t lin2_timerOverflowInterruptCount = 0U;

// lin init
LIN_DRV_Init(INST_LIN2, &lin2_InitConfig0, &lin2_State);
LIN_DRV_InstallCallback(INST_LIN2, (lin_callback_t)lin2_callback);

// config timer
FTM_DRV_Init(INST_FLEXTIMER_MC2, &flexTimer_mc2_InitConfig, &timer1_state);
INT_SYS_InstallHandler(FTM1_Ovf_Reload_IRQn, &timer1_handler, (isr_t *)0U);
INT_SYS_EnableIRQ(FTM1_Ovf_Reload_IRQn);

FTM_DRV_InitCounter(INST_FLEXTIMER_MC2, &flexTimer_mc2_TimerConfig);
FTM_DRV_CounterStart(INST_FLEXTIMER_MC2);



lin_callback_t lin2_callback(uint32_t instance, lin_state_t * lin2_State)
{
    (void)instance;
    lin_callback_t lin2_callback_cur = lin2_State->Callback;

    switch (lin2_State->currentEventId) {
        case LIN_PID_OK:
        	// 超时服务
            LIN_DRV_SetTimeoutCounter(INST_LIN2, TIMEOUT);
            
            // master send, slave recv
            if (lin2_State->currentId == LIN1_RECV_STATUS_ID) {
                LIN_DRV_SendFrameData(INST_LIN2, lin_master_txbuf, sizeof(lin_master_txbuf));
            }
            // master recv, slave send
            if (lin2_State->currentId == LIN1_SEND_STATUS_ID) {
                LIN_DRV_ReceiveFrameData(INST_LIN2, lin_master_rxbuf, sizeof(lin_master_rxbuf));
                lin_master_rx_flag = 1;
            }
            break;
        case LIN_PID_ERROR:
            break;
        case LIN_TX_COMPLETED:
        case LIN_RX_COMPLETED:
            LIN_DRV_GotoIdleState(INST_LIN2);
            break;
        case LIN_WAKEUP_SIGNAL:
            break;
        case LIN_RECV_BREAK_FIELD_OK:
            LIN_DRV_SetTimeoutCounter(INST_LIN2, TIMEOUT);
            break;
        default:
            break;
    }

    return lin2_callback_cur;
}
// 超时服务相关
uint32_t lin2TimerGetTimeIntervalCallback0(uint32_t *ns)
{
    static uint32_t lin2_previousCountValue = 0UL;
    uint32_t lin2_counterValue;

    lin2_counterValue = FTM_DRV_CounterRead(INST_FLEXTIMER_MC2);
    *ns = ((uint32_t)(lin2_counterValue + lin2_timerOverflowInterruptCount * TIMER_COMPARE_VAL - lin2_previousCountValue)) * 1000 / TIMER_TICKS_1US;
    lin2_timerOverflowInterruptCount = 0UL;
    lin2_previousCountValue = lin2_counterValue;

    return 0UL;
}

void timer1_handler()
{
	// 清除定时器标志
    FTM_DRV_ClearStatusFlags(INST_FLEXTIMER_MC2, FTM_TIME_OVER_FLOW_FLAG);

	// lin1配置成了slave,不需要可以删掉
	LIN_DRV_TimeoutService(INST_LIN1);
    lin1_timerOverflowInterruptCount ++;

    LIN_DRV_TimeoutService(INST_LIN2);
    lin2_timerOverflowInterruptCount ++;
}

// 按键控制发送帧头ID
void key1_2_callback()
{
    uint32_t key_int_flag = PINS_DRV_GetPortIntFlag(PORTC);

    if (key_int_flag & (1 << 12)) {
    	// 发送ID为LIN1_RECV_STATUS_ID的帧头
        LIN_DRV_MasterSendHeader(INST_LIN2, LIN1_RECV_STATUS_ID);
    } else if (key_int_flag & (1 << 13)) {
    	// 发送ID为LIN1_SEND_STATUS_ID的帧头
        LIN_DRV_MasterSendHeader(INST_LIN2, LIN1_SEND_STATUS_ID);
    }

    PINS_DRV_ClearPortIntFlagCmd(PORTC);
}

Slave配置

slave的模块配置和master基本相同,选择模式不同,相同部分不再说明,只贴不同的部分;
因为slave不需要发帧头,所以slave只需要处理ID即可;
LIN_DRV_Init(INST_LIN1, &lin1_InitConfig0, &lin1_State);
LIN_DRV_InstallCallback(INST_LIN1, (lin_callback_t)lin1_callback);

lin_callback_t lin1_callback(uint32_t instance, lin_state_t * lin1_State)
{
    (void)instance;
    lin_callback_t lin1_callback_cur = lin1_State->Callback;

    switch (lin1_State->currentEventId) {
        case LIN_PID_OK:
            LIN_DRV_SetTimeoutCounter(INST_LIN1, TIMEOUT);
            if (LIN1_RECV_STATUS_ID == lin1_State->currentId) {
                LIN_DRV_ReceiveFrameData(INST_LIN1, lin_slave_rxbuf, sizeof(lin_slave_rxbuf));
            }
            if (LIN1_SEND_STATUS_ID == lin1_State->currentId) {
                LIN_DRV_SendFrameData(INST_LIN1, lin_slave_txbuf, sizeof(lin_slave_txbuf));
            }
            break;
        case LIN_PID_ERROR:
            break;
        case LIN_TX_COMPLETED:
        case LIN_RX_COMPLETED:
            LIN_DRV_GotoIdleState(INST_LIN1);
            break;
        case LIN_WAKEUP_SIGNAL:
            break;
        case LIN_RECV_BREAK_FIELD_OK:
            LIN_DRV_SetTimeoutCounter(INST_LIN1, TIMEOUT);
            break;
        default:
            break;
    }

    return lin1_callback_cur;
}

uint32_t lin1TimerGetTimeIntervalCallback0(uint32_t *ns)
{
    static uint32_t lin1_previousCountValue = 0UL;
    uint32_t lin1_counterValue;

    lin1_counterValue = FTM_DRV_CounterRead(INST_FLEXTIMER_MC1);
    *ns = ((uint32_t)(lin1_counterValue + lin1_timerOverflowInterruptCount * TIMER_COMPARE_VAL - lin1_previousCountValue)) * 1000 / TIMER_TICKS_1US;
    lin1_timerOverflowInterruptCount = 0UL;
    lin1_previousCountValue = lin1_counterValue;

    return 0UL;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值