这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 行业应用 » 汽车电子 » 【S32K3XX】串口接收不响应问题确认

共1条 1/1 1 跳转至

【S32K3XX】串口接收不响应问题确认

高工
2025-09-28 08:54:16     打赏

【问题现象】

本地使用S32K328 芯片时使用的UART中断的方式接收数据,偶发的串口无法接收。

【问题调查】

复现问题的时候本地attach 到板子上查UART 的寄存器发现控制寄存器的串口接收中断被关闭了。

image.png

知道了问题原因,我们就可以针对该问题进行调查确认,我们可以这对该寄存器下数据断点查看何发生了改写。

image.png

本地复现问题发现是触发了串口ERROR异常,从而关闭了串口接收中断

image.png

以下是uart 错误异常的处理代码,检测到错误事件后会清除对应的事件,并关闭接收处理同时调用event callback 函数通知应用层。

static void Lpuart_Uart_Ip_ErrIrqHandler(const uint8 Instance)
{
Lpuart_Uart_Ip_StateStructureType * UartState;
const Lpuart_Uart_Ip_UserConfigType *UartUserCfg;
LPUART_Type * Base;
boolean IsError = FALSE;
boolean IsReturn = FALSE;

Base = Lpuart_Uart_Ip_apBases[Instance];
UartState = (Lpuart_Uart_Ip_StateStructureType *)Lpuart_Uart_Ip_apStateStructuresArray[Instance];
UartUserCfg = Lpuart_Uart_Ip_apUserConfig[Instance];

/* Handle receive overrun interrupt */
if (Lpuart_Uart_Ip_GetStatusFlag(Base, LPUART_UART_IP_RX_OVERRUN))
{
if (!Lpuart_Uart_Ip_GetIntMode(Base, LPUART_UART_IP_INT_RX_OVERRUN))
{
IsReturn = TRUE;
}
else
{
/* Update the status */
IsError = TRUE;
UartState->ReceiveStatus = LPUART_UART_IP_STATUS_RX_OVERRUN;
/* Clear the flag */
Lpuart_Uart_Ip_ClearStatusFlag(Base, LPUART_UART_IP_RX_OVERRUN);
}
}
/* Handle framing error interrupt */
if (Lpuart_Uart_Ip_GetStatusFlag(Base, LPUART_UART_IP_FRAME_ERR) && (FALSE == IsReturn))
{
if (!Lpuart_Uart_Ip_GetIntMode(Base, LPUART_UART_IP_INT_FRAME_ERR_FLAG))
{
IsReturn = TRUE;
}
else
{
/* Update the status */
IsError = TRUE;
UartState->ReceiveStatus = LPUART_UART_IP_STATUS_FRAMING_ERROR;
/* Clear the flag */
Lpuart_Uart_Ip_ClearStatusFlag(Base, LPUART_UART_IP_FRAME_ERR);
}
}
/* Handle parity error interrupt */
if (Lpuart_Uart_Ip_GetStatusFlag(Base, LPUART_UART_IP_PARITY_ERR) && (FALSE == IsReturn))
{
if (!Lpuart_Uart_Ip_GetIntMode(Base, LPUART_UART_IP_INT_PARITY_ERR_FLAG))
{
IsReturn = TRUE;
}
else
{
/* Update the status */
IsError = TRUE;
UartState->ReceiveStatus = LPUART_UART_IP_STATUS_PARITY_ERROR;
/* Clear the flag */
Lpuart_Uart_Ip_ClearStatusFlag(Base, LPUART_UART_IP_PARITY_ERR);
}
}
/* Handle noise error interrupt */
if (Lpuart_Uart_Ip_GetStatusFlag(Base, LPUART_UART_IP_NOISE_DETECT) && (FALSE == IsReturn))
{
if (!Lpuart_Uart_Ip_GetIntMode(Base, LPUART_UART_IP_INT_NOISE_ERR_FLAG))
{
IsReturn = TRUE;
}
else
{
/* Update the internal status */
IsError = TRUE;
UartState->ReceiveStatus = LPUART_UART_IP_STATUS_NOISE_ERROR;
/* Clear the flag */
Lpuart_Uart_Ip_ClearStatusFlag(Base, LPUART_UART_IP_NOISE_DETECT);
}
}

#if (LPUART_UART_IP_ENABLE_TIMEOUT_INTERRUPT == STD_ON)
/* Handle the error interrupts if timeout error */
if (Lpuart_Uart_Ip_GetStatusFlag(Base, LPUART_UART_IP_TIMEOUT) && (FALSE == IsReturn))
{
/* This checking also ensures that the feature is activated for the current instance
         * because the Interrupt can be enabled only in this case.
         */
if (Lpuart_Uart_Ip_GetIntMode(Base, LPUART_UART_IP_INT_TIMEOUT))
{
/* Update the internal status */
IsError = TRUE;
/* Update the status */
UartState->ReceiveStatus = LPUART_UART_IP_STATUS_RX_IDLE_STATE;
/* Clear Timeout Interrupt Error flag */
Lpuart_Uart_Ip_ClearStatusFlag(Base, LPUART_UART_IP_TIMEOUT);
}
else
{
IsReturn = TRUE;
}
}
#endif

if (FALSE == IsReturn)
{
if (TRUE == IsError)
{
if (LPUART_UART_IP_USING_INTERRUPTS == UartUserCfg->TransferType)
{
/* Complete the transfer (disable rx logic) */
Lpuart_Uart_Ip_CompleteReceiveDataUsingInt(Instance);
}
#if (LPUART_UART_IP_HAS_DMA_ENABLED == STD_ON)
else
{
/* Complete the transfer (stop DMA channel) */
(void)Dma_Ip_SetLogicChannelCommand(UartUserCfg->RxDMAChannel, DMA_IP_CH_CLEAR_HARDWARE_REQUEST);
Lpuart_Uart_Ip_CompleteReceiveUsingDma(Instance);
}
#endif
/* Invoke callback if there is one */
if (UartUserCfg->Callback != NULL_PTR)
{
#if (LPUART_UART_IP_ENABLE_TIMEOUT_INTERRUPT == STD_ON)
if (LPUART_UART_IP_STATUS_RX_IDLE_STATE == UartState->ReceiveStatus)
{
UartUserCfg->Callback(Instance, LPUART_UART_IP_EVENT_IDLE_STATE, UartUserCfg->CallbackParam);
}
else
#endif
{
UartUserCfg->Callback(Instance, LPUART_UART_IP_EVENT_ERROR, UartUserCfg->CallbackParam);
}
}
}
}
}

知道了问题原因后我们就可以在针对该问题添加策略了,串口接收错误事件会通过callback 函数上报给用户,我们可以在里面检测错误事件并开启串口中断。


image.png

修改代码后串口异常关闭问题已经被解决。




共1条 1/1 1 跳转至

回复

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