USART3_IRQHandler() 被连续调用 LL_USART_IsActiveFlag_TXE 集
USART3_IRQHandler() is continuously called with LL_USART_IsActiveFlag_TXE set
我要开发自己的串行代码(而不是使用 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 */
}
serial.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);
,问题就会消失(但我无法查看串行端口是否可以自由写入)。
逻辑错误。
TXE 中断应该被启用只有 如果你有一些数据要发送。
当您完成数据寄存器的输入后 - 您将禁用它。
没有TXE清除标志是符合逻辑的。 EMPTY 标志只能通过使其 不为空
来清除
but I then cannot then see if the serial port is free to write to
您需要实现一个缓冲区。并检查缓冲区中是否有 space 以放置要发送的新数据。
正如P__J__指出的那样,我的逻辑错误。
新代码看起来像这样,并且可以正常工作。
serial.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 详细信息。
我要开发自己的串行代码(而不是使用 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 */
}
serial.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);
,问题就会消失(但我无法查看串行端口是否可以自由写入)。
逻辑错误。
TXE 中断应该被启用只有 如果你有一些数据要发送。
当您完成数据寄存器的输入后 - 您将禁用它。
没有TXE清除标志是符合逻辑的。 EMPTY 标志只能通过使其 不为空
来清除but I then cannot then see if the serial port is free to write to
您需要实现一个缓冲区。并检查缓冲区中是否有 space 以放置要发送的新数据。
正如P__J__指出的那样,我的逻辑错误。
新代码看起来像这样,并且可以正常工作。
serial.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 详细信息。