c++ - STM32L011 : Interrupt flag cannot be cleared in Interrupt Handler

标签 c++ interrupt stm32 reset interrupt-handling

使用 LPTIM1 中断处理程序,我的代码设置为在进入处理程序后立即清除中断标志,但在调试期间,“中断清除寄存器”(ICR) 中的标志未设置为 0,因此程序直接跳转到由于在“中断和状态寄存器”(ISR) 中设置的挂起中断位而离开后的中断处理程序

代码如下:

extern "C" void LPTIM1_IRQHandler()
{
  if(LPTIM1->ISR && LPTIM_ISR_ARRM){         //check if Interrupt flag is set
 //   __disable_irq();
    LPTIM1->ICR |= LPTIM_ICR_ARRMCF;        //reset Interrupt flag in the "Clear"-Register
    flag_TimerInterrupt = true;             //set flag for enabling next LED-cycle
  }

我在 Internet 搜索中没有找到有关类似问题的提示。

最佳答案

STM32L0x1 reference manual中LPTIM ICR寄存器中ARRMCF位的说明说:

Writing 1 to this bit clears the ARRM flag in the LPT_ISR register.

ARRMCF 位本身以及 ICR 寄存器中的所有其他位都是不可读的,因此您不应期望在读取它们时获得任何特定值。事实上,您使用 |= 的代码是可疑的,因为您隐式告诉编译器从该寄存器读取。我认为您应该将其更改为使用正常分配。

此外,您使用了错误的 C 运算符来检查是否设置了中断标志。

另外,我不确定位宏在您的环境中是如何定义的,因此为了安全起见,我不会在我将要展示的代码中使用它们。

综上所述,我建议将您的代码更改为:

extern "C" void LPTIM1_IRQHandler()
{
  if (LPTIM1->ISR & (1 << 1))
  {
    // ARRM interrupt flag is set, so clear it.
    LPTIM1->ICR = (1 << 1);
    flag_TimerInterrupt = true;
  }
}

此外,如果您使用的是调试器,则在调试器等待您的下一个操作时,计时器每秒可能会触发此中断数千次。如果是这样,您将永远无法真正单步执行主循环代码(任何中断之外的代码)。您可能只需要在真正的硬件上调试它,直到它工作。您可以使用 GPIO 获取有关程序状态的信息,并在示波器上查看 GPIO 信号。我没有经常使用 STM32 调试器,所以也许可以在调试器等待您时卡住定时器。

关于c++ - STM32L011 : Interrupt flag cannot be cleared in Interrupt Handler,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55434610/

相关文章:

c - stm32g483 基于 SysTick 的计时器的奇怪行为

c++ - GDB是否可以只运行一个线程

c++ - 初始化成员变量

c++ - 在 C++ 中使用另一个头文件中的抽象类

c++ - GD32VF103 龙眼纳米中断不起作用

interrupt - 进入 HALT 模式并启用主中断但未启用中断(0xFF0F = 0)?

c++ - 以固定容量初始化大小为 0 的 vector<vector<double>> 的最快方法

c - block 模式下的读取中断

stm32 - 如何找到STM32F103RET的设备ID

stm32 - STM32 上 bxCAN i/f 的重要示例代码?