STM32 Uart HalfDuplex 在 USART2_IRQHandler 上保持循环,永不中断

问题描述 投票:0回答:1

我似乎无法弄清楚为什么,但是当启用中断时,它只是不断调用 USART2_IRQHandler 我已经检查了 ISR 寄存器,没有任何改变,一切都保持不变。

我尝试将其重新配置为全双工,但遇到了同样的问题。 uart应该是单线/半双工

void USART2_IRQHandler()
{
    //never stops getting called loops
}
static void MX_USART2_UART_Init(void)
{
    /* USER CODE BEGIN USART2_Init 0 */
    // HAL_UART_Receive_IT(&huart1, &Uart1_Rx, 1);
    /* USER CODE END USART2_Init 0 */

    /* USER CODE BEGIN USART2_Init 1 */

    /* USER CODE END USART2_Init 1 */
    huart2.Instance = DELTA_USART;
    huart2.Init.BaudRate = 57600; // 57.6
    huart2.Init.WordLength = UART_WORDLENGTH_9B;
    huart2.Init.StopBits = UART_STOPBITS_1;
    huart2.Init.Parity = UART_PARITY_ODD;
    huart2.Init.Mode = UART_MODE_TX_RX;
    huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart2.Init.OverSampling = UART_OVERSAMPLING_8;
    huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
    huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
    if (HAL_HalfDuplex_Init(&huart2) != HAL_OK) {
         Error_Handler();
    }
    /* USER CODE BEGIN USART2_Init 2 */

    /* USER CODE END USART2_Init 2 */
}


inline void EnableInterupt()
{
    NVIC_EnableIRQ(irq);
}
inline void DisableInterupt()
{
    NVIC_DisableIRQ(irq);
}

void setupUartInterupt()
{
    huart2.Instance->CR1 |= USART_CR1_RXNEIE //| USART_CR1_TXEIE
                    | USART_CR1_IDLEIE;
    huart2.Instance->CR1 |= USART_CR1_TE | USART_CR1_RE;
        //_huart->CR3 |= USART_CR3_OVRDIS;

    NVIC_SetPriority(USART2_IRQn, 2);
}
stm32 uart hal usart
1个回答
0
投票

在回答您的问题之前,先了解一下内部工作原理:

让我们回顾一下Cortex-M MCU(例如STM32)中中断如何发生的逻辑。

STM32(至少是 Cortex-M 内核)中涉及三个设备来产生中断:中断事件源(UART 外围设备)、NVIC(内核外围设备)和内核本身。我会稍微宽松地使用“核心”这个词,人们总是可以更深入,但这与本次讨论无关。

我画了一张插图,请原谅它的粗鲁:

几个要点是:
-你的外设没有直接连接到核心,它本身不会触发核心中断
- 内核只有一根中断信号线。所有异常和中断事件均使用这一唯一的一行来触发。
-NVIC 位于核心中断线上并触发它。
-NVIC从其他外设接收中断事件信号作为中断请求(IRQ),然后,如果该中断被使能,NVIC将依次触发内核中断。在某种程度上,当中断启用时,NVIC 将外设中断信号传递到内核。

NVIC 基本上是内核的中断管理器。它控制优先级,控制启用和禁用哪些中断,但它还跟踪中断处理状态 - 中断处理程序是否仍在执行?结束了吗?它会自动设置和清除中断处理程序状态标志本身(但不在外设中)。这些状态包括“中断处理程序等待启动”或“中断处理程序正在执行”。您可以在名为编程手册(针对您的 MCU 核心)的文档中检查 NVIC 寄存器。


回答问题:

为什么您的实施没有按照您预期的方式进行?
因为您从未删除过 UART 事件触发器(见图)。外设中的事件位被设置。该信号不断发送到 NVIC,而不是作为脉冲。只要外设中的事件位被设置,外设就会触发 NVIC 中的 IRQ,即使 NVIC 刚刚执行了事件处理程序,并将该事件处理程序标记为已完成,它也会不断收到来自外设的另一个中断请求。

解决方案:
中断处理程序需要清除外设中的事件标志,因此外设不会不断触发NVIC。您不需要清除 NVIC 中的事件标志,它会自动执行此操作,但外设位于核心之外,它们实际上是核心的外部设备,因此您需要手动清除外设中的事件标志。

© www.soinside.com 2019 - 2024. All rights reserved.