This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

关于串口回调函数触发的条件,调用HalUARTWrite()触发了串口回调函数,什么原因呢?

Genius 3030 points

调用HalUARTWrite()时进入了串口回调函数,LED1闪烁

  • 这个是正常的。你自己起的rxCB的名,不表示它不处理串口发送的事件。

    你可以看到HalUARTPollDMA() 函数,显然call back 也需要处理HAL_UART_TX_EMPTY,HAL_UART_TX_FULL等发送 事件。

  • static void HalUARTPollDMA(void)
    {
    uint16 cnt = 0;
    uint8 evt = 0;

    if (HAL_UART_DMA_NEW_RX_BYTE(dmaCfg.rxHead))
    {
    rxIdx_t tail = findTail();

    // If the DMA has transferred in more Rx bytes, reset the Rx idle timer.
    if (dmaCfg.rxTail != tail)
    {
    dmaCfg.rxTail = tail;

    // Re-sync the shadow on any 1st byte(s) received.
    if (dmaCfg.rxTick == 0)
    {
    dmaCfg.rxShdw = ST0;
    }
    dmaCfg.rxTick = HAL_UART_DMA_IDLE;
    }
    else if (dmaCfg.rxTick)
    {
    // Use the LSB of the sleep timer (ST0 must be read first anyway).
    uint8 decr = ST0 - dmaCfg.rxShdw;

    if (dmaCfg.rxTick > decr)
    {
    dmaCfg.rxTick -= decr;
    dmaCfg.rxShdw = ST0;
    }
    else
    {
    dmaCfg.rxTick = 0;
    }
    }
    cnt = HalUARTRxAvailDMA();
    }
    else
    {
    dmaCfg.rxTick = 0;
    }

    if (cnt >= HAL_UART_DMA_FULL)
    {
    evt = HAL_UART_RX_FULL;
    }
    else if (cnt >= HAL_UART_DMA_HIGH)
    {
    evt = HAL_UART_RX_ABOUT_FULL;
    PxOUT |= HAL_UART_Px_RTS; // Disable Rx flow.
    }
    else if (cnt && !dmaCfg.rxTick)
    {
    evt = HAL_UART_RX_TIMEOUT;
    }

    if (dmaCfg.txMT)
    {
    dmaCfg.txMT = FALSE;
    evt |= HAL_UART_TX_EMPTY;
    }

    if (dmaCfg.txShdwValid)
    {
    uint8 decr = ST0;
    decr -= dmaCfg.txShdw;
    if (decr > dmaCfg.txTick)
    {
    // No protection for txShdwValid is required
    // because while the shadow was valid, DMA ISR cannot be triggered
    // to cause concurrent access to this variable.
    dmaCfg.txShdwValid = FALSE;
    }
    }

    if (dmaCfg.txDMAPending && !dmaCfg.txShdwValid)
    {
    // UART TX DMA is expected to be fired and enough time has lapsed since last DMA ISR
    // to know that DBUF can be overwritten
    halDMADesc_t *ch = HAL_DMA_GET_DESC1234(HAL_DMA_CH_TX);
    halIntState_t intState;

    // Clear the DMA pending flag
    dmaCfg.txDMAPending = FALSE;

    HAL_DMA_SET_SOURCE(ch, dmaCfg.txBuf[dmaCfg.txSel]);
    HAL_DMA_SET_LEN(ch, dmaCfg.txIdx[dmaCfg.txSel]);
    dmaCfg.txSel ^= 1;
    HAL_ENTER_CRITICAL_SECTION(intState);
    HAL_DMA_ARM_CH(HAL_DMA_CH_TX);
    do
    {
    asm("NOP");
    } while (!HAL_DMA_CH_ARMED(HAL_DMA_CH_TX));
    HAL_DMA_CLEAR_IRQ(HAL_DMA_CH_TX);
    HAL_DMA_MAN_TRIGGER(HAL_DMA_CH_TX);
    HAL_EXIT_CRITICAL_SECTION(intState);
    }
    else
    {
    halIntState_t his;

    HAL_ENTER_CRITICAL_SECTION(his);
    if ((dmaCfg.txIdx[dmaCfg.txSel] != 0) && !HAL_DMA_CH_ARMED(HAL_DMA_CH_TX)
    && !HAL_DMA_CHECK_IRQ(HAL_DMA_CH_TX))
    {
    HAL_EXIT_CRITICAL_SECTION(his);
    HalUARTIsrDMA();
    }
    else
    {
    HAL_EXIT_CRITICAL_SECTION(his);
    }
    }

    if (evt && (dmaCfg.uartCB != NULL))
    {
    dmaCfg.uartCB(HAL_UART_DMA-1, evt);
    }
    }

  • 您好请问您的问题解决了吗?我也遇到类似的问题这个怎么解决?
  • 您好 我也遇到类似问题 请问怎么修改
  • 看上面解释就知道了

  • 您好 我遇到和楼主一样的问题,我在HalUARTPollDMA()中的最后一个if判断语句中改成了

    if (evt && (dmaCfg.uartCB != NULL))

      {

        evt &= HAL_UART_TX_N;//0xf7  屏蔽掉HAL_UART_TX_FULL和HAL_UART_TX_EMPTY

        dmaCfg.uartCB(HAL_UART_DMA-1, evt);

      }
    但是还是不行,请指正

  • dmaCfg.uartCB(HAL_UART_DMA-1, evt);这个也要屏蔽,其实思路就是要屏蔽发送产生的事件,或者不去处理产生的事件