STM32:无法退出UART中断的中断处理程序

时间:2018-09-13 18:25:27

标签: c interrupt stm32 uart ll

我正在STM32F103上实现一个简单的UART收发协议,我在这里使用的库/样板代码是LL,而不是HAL(因为HAL包含疯狂的开销)

我的问题是,成功进入中断处理程序“ USART1_IRQHandler”后,它会一直循环打开。 我的代码在这里:

    void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
    int ii = 0;
    for(ii=0; ii<4;  ii++){
        LL_mDelay(40);
        LL_GPIO_TogglePin(GPIOA, LL_GPIO_PIN_5);
        LL_mDelay(40);
        LL_GPIO_TogglePin(GPIOA, LL_GPIO_PIN_5);

    }
    uint8_t cc = LL_USART_ReceiveData8(USART1);
    LL_USART_TransmitData8(USART1, cc);
    LL_mDelay(130);

    //LL_USART_ClearFlag_RXNE(USART1);
    //NVIC_ClearPendingIRQ( USART1_IRQn );

  /* USER CODE END USART1_IRQn 0 */
  /* USER CODE BEGIN USART1_IRQn 1 */
  /* USER CODE END USART1_IRQn 1 */
}

在main.c中,我有:

LL_USART_EnableIT_RXNE(USART1);
  while (1)
  {

        LL_mDelay(300);
        LL_GPIO_TogglePin(GPIOA, LL_GPIO_PIN_5);
        LL_mDelay(300);
        LL_GPIO_TogglePin(GPIOA, LL_GPIO_PIN_5);

        //LL_USART_EnableIT_TC(USART1);

  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */

  }

GPIO_Toggle命令就在那里使LED闪烁,所以我知道发生了什么。这是发生了什么: 当我给MC通电时,它将进入主循环并缓慢闪烁。 当我通过UART发送某些内容(约10个字节)时,LED开始快速闪烁,表明它已进入中断处理程序。 PProblem是它永远不会停止,并且会在中断处理程序中不断旋转。

我尝试使用现在注释的功能

LL_USART_ClearFlag_RXNE(USART1);
NVIC_ClearPendingIRQ( USART1_IRQn );

单独或组合使用,但它们对任何事物都完全没有影响。 我究竟做错了什么? 如何退出处理程序?

2 个答案:

答案 0 :(得分:3)

实际上,USART中断处理程序中的所有内容都是错误的。

  1. 您不检查引起中断的原因。 如果它是RXNE标志,则应仅从DR寄存器中加载该值。您不需要清除任何标志。如果它是TXE标志,则可以将数据存储到DR寄存器。您无法通过其他任何方式清除此标志。如果没有任何数据要发送,则需要禁用TXE中断。否则它将连续触发。

您不能只在需要时读写数据寄存器。您需要知道是否被允许

您还应该控制错误状态。

  1. 不得在中断例程中使用任何延迟。保持尽可能快。
  2. 请勿触摸NVIC来启用和禁用中断,因为您现在不知道它是干什么的。

答案 1 :(得分:0)

用于控制延迟的系统时间通过定期的sysTick中断进行更新。如果RXNE中断的优先级高于sysTick中断,那么当您在RXNE IRQ处理程序中时,它将不会被处理,因此该时间将永远不会增加,并且您的延迟结束时间将永远无法到达。取决于延迟的实现方式,它可能会使CPU陷入永不退出的自旋锁。