首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >USART3_IRQHandler()是用LL_USART_IsActiveFlag_TXE集连续调用的

USART3_IRQHandler()是用LL_USART_IsActiveFlag_TXE集连续调用的
EN

Stack Overflow用户
提问于 2020-03-18 09:19:13
回答 2查看 1.5K关注 0票数 0

我将开发自己的串行代码(而不是使用CubeMX的HAL)来接口现有的协议代码库,这需要低级别的串行特性。

USART3_IRQHandler()被反复调用(因此也调用了serial::serial_irq_handler() )。

代码语言:javascript
复制
/**
  * @brief This function handles USART3 global interrupt.
  */
void USART3_IRQHandler(void)
{
  /* USER CODE BEGIN USART3_IRQn 0 */
  serial_irq_handler(&usart3);
  /* USER CODE END USART3_IRQn 0 */
  /* USER CODE BEGIN USART3_IRQn 1 */

  /* USER CODE END USART3_IRQn 1 */
}

连载.c:

代码语言:javascript
复制
/**
 * @brief Should be called only by UART/USARTx_IRQHandler()
 */
void serial_irq_handler(struct serial *serial)
{
    // "while" is used in case we decide to turn on the limited FIFOs (USARTs only).
    while (LL_USART_IsActiveFlag_RXNE(serial->usart)) {
        uint8_t b = LL_USART_ReceiveData8(serial->usart);
        circbuf_push(&serial->rxcircbuf, b);
    }

    if (LL_USART_IsActiveFlag_TXE(serial->usart)) {
        LL_USART_ClearFlag_TC(serial->usart);
        serial->txbusy = 0;
    }
}

(上面代码中的serial->usart == USART3。)

我认为问题在于我正在清除错误的标志(TC而不是TXE)。

这是问题的原因吗?

我不能清除TXE,因为LL_USART_ClearFlag_TXE()不存在。

如果我在intialisation代码中注释掉LL_USART_EnableIT_TXE(serial->usart);,问题就会消失(但这样我就无法查看串行端口是否可以自由写入)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-03-18 10:49:13

逻辑不对。

如果您有一些数据要发送,TXE中断只应该是。

当您完成输入数据寄存器-您禁用它。

没有TXE清除标志是合乎逻辑的。标志只能通过使其不为空才能清除。

,但这样我就无法查看串口是否可以自由地写到

您需要实现一个缓冲区。并检查缓冲区中是否有空间放置要发送的新数据。

票数 1
EN

Stack Overflow用户

发布于 2020-03-18 12:41:48

正如P__J__所指出的,我的逻辑是错误的。

新代码看起来像这样,并且正在工作。

连载.c:

代码语言:javascript
复制
int serial_tx(struct serial *serial, uint8_t byte) {
    if (serial->txbusy) {
        serial->stats.txbusy++;
        return -1;
    }
    serial->txbusy = 1;
    LL_USART_TransmitData8(serial->usart, byte);
    LL_USART_EnableIT_TXE(serial->usart);
    serial->stats.txbytes++;
    return 0;
}

int serial_rx(struct serial *serial, uint8_t *out) {
    return circbuf_pop(&serial->rxcircbuf, out);
}

/*
 * @brief Should be called only by void UART/USARTx_IRQHandler()
 */
void serial_irq_handler(struct serial *serial)
{
    // while is used in case we decide to turn on the limited FIFOs (USARTs only).
    while (LL_USART_IsActiveFlag_RXNE(serial->usart)) {
        uint8_t b = LL_USART_ReceiveData8(serial->usart);
        circbuf_push(&serial->rxcircbuf, b);
    }

    if (LL_USART_IsActiveFlag_TXE(serial->usart)) {
        LL_USART_DisableIT_TXE(serial->usart);
        serial->txbusy = 0;
    }
}

我必须实现字节I/O,而不是缓冲,因为更高的(预先存在的)通信层需要这样做。

-更新

此代码的小变体不起作用。我试着使用TXC标志,然后再引用该芯片的3,000+页面手册。第48章包含USART的详细内容。

https://www.st.com/resource/en/reference_manual/dm00314099-stm32h742-stm32h743-753-and-stm32h750-value-line-advanced-arm-based-32-bit-mcus-stmicroelectronics.pdf

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60736520

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档