STM32中断标志位的正确清除方式探讨
Great question—this is a super common gotcha in bare-metal STM32L4 development, and it ties directly to how ST's peripherals handle interrupt flags under the hood. Let's break this down clearly:
Your current flow is correct
The sequence you're using—read peripheral status to identify the triggering event → execute the corresponding action → clear the originally read flag—aligns with the majority of STM32L4 peripheral requirements. Many peripherals (like UART, SPI, EXTI, and some timers) explicitly require you to first read the status register before clearing the interrupt flag. This is because:
- Reading the status register locks in the current interrupt event context, ensuring you're clearing the exact flag that triggered the ISR, not an unrelated or unprocessed one.
- Some error flags (e.g., UART overrun errors) will only acknowledge a clear operation if you've first read the status register to confirm the error exists. Skip this step, and your clear attempt might be ignored, leading to infinite interrupt loops.
Don't clear flags at the start of the ISR—here's why
Clearing the interrupt flag immediately when entering the ISR is a bad practice for two critical reasons:
- Peripheral timing violations: As mentioned above, many STM32 peripherals require a specific read-then-write sequence to clear flags. Jumping straight to clearing can leave flags stuck, causing the ISR to fire repeatedly without stopping.
- Lost interrupt events: Suppose a second interrupt event occurs between when you enter the ISR and when you clear the flag. If you clear first, you might overwrite or lose track of that new event before you've had a chance to process it. While the NVIC will hang onto interrupt requests, peripheral flags might not behave the same way—some will only latch events until the flag is cleared, meaning you could miss the second trigger entirely.
What happens if an event fires during step 2?
Your intuition here is spot on. If the same peripheral event occurs while you're executing your action (step 2), the peripheral will set the interrupt flag again. When you finish step 2 and clear the original flag you read earlier, this new flag will remain set. As soon as your ISR exits, the NVIC will recognize the pending flag and trigger the ISR again to handle the new event.
This is actually the intended behavior! It ensures you don't miss any interrupts, which is critical in real-time systems. The only caveat: make sure your action code is either reentrant (safe to run multiple times in quick succession) or that you add safeguards (like temporarily disabling the peripheral interrupt during processing) if reentrancy would cause issues.
内容的提问来源于stack exchange,提问作者Guillaume Petitjean




