HC32L110_DDL_Rev1.0.2:串口驱动的问题(uart.c)
串口0参数配置:工作模式:模式1(异步全双工) 发送方式:查询 接收发送:中断问题描述:
串口接收中断开启,当串口以查询的方式发送数据的同时,串口有可能收到数据进入中断服务函数,代码如下:
/**
******************************************************************************
** \briefUART通道发送数据函数,查询方式调用此函数,中断方式发送不适用
**
** \param u8Idx通道号,Data发送数据
**
** \retval Ok发送成功
**\retval ErrorInvalidParameter发送失败
******************************************************************************/
en_result_t Uart_SendData(uint8_t u8Idx, uint8_t u8Data)
{
stc_uart_instance_data_t *pstcData = NULL;
ASSERT(IS_VALID_CH(u8Idx));
pstcData = UartGetInternDataPtr(u8Idx);
if (NULL == pstcData)
{
return ErrorInvalidParameter;
}
Uart_ClrStatus(u8Idx,UartTxEmpty);
pstcData->pstcInstance->SBUF =u8Data;
while(FALSE == Uart_GetStatus(u8Idx,UartTxEmpty))
{}
Uart_ClrStatus(u8Idx,UartTxEmpty);
return Ok;
}
******************************************************************************
** \brief UART通道中断处理函数
**
** \param u8Param通道号
**
** \retval 无
**
******************************************************************************/
void Uart_IRQHandler(uint8_t u8Param)
{
stc_uart_instance_data_t *pstcData = NULL;
pstcData = UartGetInternDataPtr(u8Param);
if (NULL == pstcData)
{
return;
} //----------错误帧--------
if(1 == pstcData->pstcInstance->ISR_f.FE)
{
Uart_ClrStatus(u8Param,UartRFRAMEError);
if(NULL != pstcData->stcUartInternIrqCb.pfnRxErrIrqCb)
{
pstcData->stcUartInternIrqCb.pfnRxErrIrqCb();
}
return;//若奇偶校验出错则不进行后续数据处理
} //----------接收--------
if(1 == pstcData->pstcInstance->ISR_f.RI)
{
Uart_ClrStatus(u8Param,UartRxFull);
if(NULL != pstcData->stcUartInternIrqCb.pfnRxIrqCb)
{
pstcData->stcUartInternIrqCb.pfnRxIrqCb();
}
} //----------发送--------
if(1 == pstcData->pstcInstance->ISR_f.TI)
{
Uart_ClrStatus(u8Param,UartTxEmpty); //pstcData->pstcInstance->ISR_f.TI清0
if(NULL != pstcData->stcUartInternIrqCb.pfnTxIrqCb)
{
pstcData->stcUartInternIrqCb.pfnTxIrqCb();
}
}
}
在执行完接收部分,会判断发送完成标志pstcData->pstcInstance->ISR_f.TI是否置位,若此时pstcData->pstcInstance->ISR_f.TI==1,会执行Uart_ClrStatus(u8Param,UartTxEmpty)清0,然后串口发送就会停在while(FALSE == Uart_GetStatus(u8Idx,UartTxEmpty)){};
本帖最后由 martinhu 于 2020-1-19 09:15 编辑
之前的uart.c的库,标志位清零的位置有问题,导致在查询发送,中断接收的全双工通信的时候,会卡死在发送函数的查询标志位的地方可以如下图将标志位清零的函数移到判断是否定义了Tx的回调函数之后。
这样在查询发送的时候,不定义Tx的回调,就不会在接收中断的时候将TC标志清零。
//----------发送--------
if(1 == pstcData->pstcInstance->ISR_f.TI)
{
Uart_ClrStatus(u8Param,UartTxEmpty); //pstcData->pstcInstance->ISR_f.TI清0
if(NULL != pstcData->stcUartInternIrqCb.pfnTxIrqCb)
{
pstcData->stcUartInternIrqCb.pfnTxIrqCb();
}
}
发送不开启发送中断,把上边这段代码注释掉,应该就不会出现发送时候,接受数据而卡死发送的情况了吧。 martinhu 发表于 2020-1-19 09:10
之前的uart.c的库,标志位清零的位置有问题,导致在查询发送,中断接收的全双工通信的时候,会卡死在发送函 ...
是的 感谢呀,碰到了这种狗血的问题。 感谢呀,也碰到同样的问题 从官网找例程,从开发板找例程 哈哈哈 当串口以查询的方式发送数据的同时,串口有可能收到数据进入中断服务函数 当串口以查询的方式发送数据的同时,串口有可能收到数据进入中断服务函数 嗯,用国产芯片是得踩一些坑啊。 学习一下啊!感觉有点知识慌了
页:
[1]