0

我要开发自己的串行代码(而不是使用 CubeMX 的 HAL)来连接需要低级串行功能的现有协议代码库。

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

/**
  * @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:

/**
 * @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()不存在。

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

4

2 回答 2

1

错误的逻辑。

只有当您有一些数据要发送时,才应启用 TXE 中断。

当您完成输入数据寄存器时 - 您将其禁用。

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

但是然后我无法查看串行端口是否可以自由写入

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

于 2020-03-18T10:49:13.717 回答
0

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

新代码看起来像这样,并且正在运行。

序列号.c:

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,而不是缓冲,因为这是更高(预先存在的)通信层所需要的。

- 更新 -

此代码的微小变化不起作用。在获得该芯片 3,000 多页手册的参考之前,我尝试使用 TXC 标志。第 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

于 2020-03-18T12:41:48.027 回答