[技术问答] HC32L110_DDL_Rev1.0.2:串口驱动的问题(uart.c)

[复制链接]
271|3
 楼主 | 2020-1-17 13:39 | 显示全部楼层 |阅读模式
串口0参数配置:工作模式:模式1(异步全双工)     发送方式:查询      接收发送:中断

问题描述:
串口接收中断开启,当串口以查询的方式发送数据的同时,串口有可能收到数据进入中断服务函数,代码如下:
/**
******************************************************************************
** \brief  UART通道发送数据函数,查询方式调用此函数,中断方式发送不适用
**
** \param [in] 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 [in] 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)){};


使用特权

评论回复
| 2020-1-19 09:10 | 显示全部楼层
本帖最后由 martinhu 于 2020-1-19 09:15 编辑

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




使用特权

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

使用特权

评论回复

评论

martinhu 2020-1-22 08:49 回复TA
是的 
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 投诉建议 创建版块 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

在线客服 快速回复 返回顶部 返回列表