S32K144 SDK uart-串口中断接收使用空闲中断, IDLE

在网上看了很多S32K14x串口接收的,基官方SDK的串口接收大部分都是使用中断或者DMA接收定长的数据帧,想要接收不定长的数据帧需要开一个接收超时定时器(需要占用系统资源且效率低下)。

查看手册得之S32K14x的串口带有空闲中断的功能,本文记录下在串口中断接收时使用空闲中断的用法。

官方SDK中没有使用空闲中断,所以需要修改官方SDK程序。

1、空闲间隔

默认是1个字节,手里没有示波器,测不出来,所以先使用默认空闲间隔。

2、主程序中

定义接收数组

static uint8_t rx_buff[200] = {0};

在主循环中调用串口初始化,这里还是用的PE的生成的配置

LPUART_DRV_Init(INST_LPUART0, &lpuart0_State, &lpuart0_InitConfig0);

继续使用SDK使用的获取数据函数,在主循环之前调用一次,将定义的接收数组传递进去,接收长度设为0

LPUART_DRV_ReceiveData(INST_LPUART0, rx_buff, 0);

为了方便测试,在主程序定义一个全局变量,用于在串口空闲中断中设置标志,表示串口空闲生效。
主循环中检测到该标志有效后,打印接收到的数据长度,打印接收到的数据。
重新开启串口接收。

volatile char rx_frame_flag = 0; /* 防止被编译器优化掉 */

int main(void)
{
	LPUART_DRV_Init(INST_LPUART0, &lpuart0_State, &lpuart0_InitConfig0);
	LPUART_DRV_ReceiveData(INST_LPUART0, rx_buff, 0);
	while(1)
	{
		if (rx_frame_flag)
        {
            rx_frame_flag = 0;
            DEBUG_INFO("\r\nrx len %d", lpuart0_State.rxSize);
            LPUART_DRV_SendData(INST_LPUART0, (uint8_t *)rx_buff, lpuart0_State.rxSize);
            LPUART_DRV_ReceiveData(INST_LPUART0, rx_buff, 0);
        }
	}
}

3、修改SDK

主要修改lpuart_driver.c函数中的内容

3.1 修改串口接收中断函数

主要修改:
1、在接收到第一个字节时,打开串口空闲中断。
2、接收长度由递减改为递增。

static void LPUART_DRV_RxIrqHandler(uint32_t instance)
{
    lpuart_state_t * lpuartState = (lpuart_state_t *)s_lpuartStatePtr[instance];
    LPUART_Type * base = s_lpuartBase[instance];
    
    /* Get data and put in receive buffer  */
    LPUART_DRV_GetData(instance);

    if (lpuartState->rxSize == 0)
    {
        LPUART_SetIntMode(base, LPUART_INT_IDLE_LINE, true);
    }

    /* Update the internal state */
    if (lpuartState->bitCountPerChar == LPUART_8_BITS_PER_CHAR)
    {
        ++lpuartState->rxBuff;
        ++lpuartState->rxSize;
    }
    else
    {
        lpuartState->rxBuff = &lpuartState->rxBuff[2];
        lpuartState->rxSize += 2U;
    }
}

3.2 修改串口中断函数

主要修改:
一定要写在错误中断处理函数之前,处理空闲中断,因为在错误处理函数里面会把空闲中断标志位清除,所以写在后面会识别不到空闲中断。
这里为了方便测试,在识别到空闲中断后,将rx_frame_flag变量置1。
识别到空闲中断后,关闭空闲中断和串口接收。

extern char rx_frame_flag;
void LPUART_DRV_IRQHandler(uint32_t instance)
{
    DEV_ASSERT(instance < LPUART_INSTANCE_COUNT);

    const LPUART_Type * base = s_lpuartBase[instance];

    if (LPUART_GetIntMode(base, LPUART_INT_IDLE_LINE))
    {
        if (LPUART_GetStatusFlag(base, LPUART_IDLE_LINE_DETECT))
        {
            rx_frame_flag = 1;
            LPUART_SetIntMode(base, LPUART_INT_IDLE_LINE, false);
            LPUART_DRV_CompleteReceiveDataUsingInt(instance);
        }
    }

    LPUART_DRV_ErrIrqHandler(instance);
    
    /* 后面的程序不需要修改,这里不粘贴过来了 */
}

4、测试效果

结合上面的主循环,使用串口通信助手测试,发送数据,串口助手显示如下所示

[23:31:11.173]发→◇123456□
[23:31:11.195]收←◆
rx len 6
123456
[23:31:11.831]发→◇123456□
[23:31:11.853]收←◆
rx len 6
123456
[23:31:16.970]发→◇qwer1234□
[23:31:16.995]收←◆
rx len 8
qwer1234
[23:31:17.824]发→◇qwer1234□
[23:31:17.849]收←◆
rx len 8
qwer1234

5、后记

本文记录为串口接收中断配合空闲中断使用,基本可以满足大部分使用需求。
如果数据量过大,考虑用DMA接收配置空闲中断。

  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值