打印
[技术问答]

HC32L110_DDL_Rev1.0.2:串口驱动的问题(uart.c)

[复制链接]
2575|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
chzfmx|  楼主 | 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)){};


使用特权

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

使用特权

评论回复
评论
martinhu 2020-1-22 08:49 回复TA
是的 
地板
chzfmx|  楼主 | 2020-3-10 09:38 | 只看该作者
martinhu 发表于 2020-1-19 09:10
之前的uart.c的库,标志位清零的位置有问题,导致在查询发送,中断接收的全双工通信的时候,会卡死在发送函 ...

是的

使用特权

评论回复
5
windows100| | 2024-11-15 17:43 | 只看该作者
感谢呀,碰到了这种狗血的问题。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

15

帖子

1

粉丝