chzfmx 发表于 2020-1-17 13:39

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:10

本帖最后由 martinhu 于 2020-1-19 09:15 编辑

之前的uart.c的库,标志位清零的位置有问题,导致在查询发送,中断接收的全双工通信的时候,会卡死在发送函数的查询标志位的地方可以如下图将标志位清零的函数移到判断是否定义了Tx的回调函数之后。
这样在查询发送的时候,不定义Tx的回调,就不会在接收中断的时候将TC标志清零。





wenlong0601 发表于 2020-1-21 11:42

//----------发送--------
    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();
          }
   }
发送不开启发送中断,把上边这段代码注释掉,应该就不会出现发送时候,接受数据而卡死发送的情况了吧。

chzfmx 发表于 2020-3-10 09:38

martinhu 发表于 2020-1-19 09:10
之前的uart.c的库,标志位清零的位置有问题,导致在查询发送,中断接收的全双工通信的时候,会卡死在发送函 ...

是的

windows100 发表于 2024-11-15 17:43

感谢呀,碰到了这种狗血的问题。

JoneyJob 发表于 2024-11-28 17:17

感谢呀,也碰到同样的问题

地瓜patch 发表于 2025-1-21 21:58

从官网找例程,从开发板找例程

申小林一号 发表于 2025-1-22 08:51

哈哈哈

sj8zw8 发表于 2025-1-31 11:45

当串口以查询的方式发送数据的同时,串口有可能收到数据进入中断服务函数

雨果喝水 发表于 2025-4-23 16:33

当串口以查询的方式发送数据的同时,串口有可能收到数据进入中断服务函数

chenqianqian 发表于 2025-4-23 21:04

嗯,用国产芯片是得踩一些坑啊。

Amazingxixixi 发表于 2025-4-24 14:48

学习一下啊!感觉有点知识慌了
页: [1]
查看完整版本: HC32L110_DDL_Rev1.0.2:串口驱动的问题(uart.c)