How to Use Interrupts and NVIC in STM32 A Complete Developer’s Guide

How to Use Interrupts and NVIC in STM32 A Complete Developer’s Guide , When working with STM32 microcontrollers, mastering interrupts and the Nested Vectored Interrupt Controller (NVIC) is essential for writing efficient and responsive embedded applications. Whether you’re building a simple LED toggle system triggered by a button or a complex real-time data acquisition system, understanding how interrupts work—and how to manage them with NVIC—can be the difference between a reliable project and one riddled with delays and missed events.
What Are Interrupts in Embedded Systems?
At its core, an interrupt is a signal that temporarily halts the main execution of a program to allow the CPU to respond to an external or internal event. Imagine you’re typing a document and someone knocks at your door. You pause your typing, answer the door, and then return to where you left off. That’s essentially how interrupts work in microcontrollers.
In STM32, interrupts allow the processor to respond instantly to events like:
- A button being pressed (external interrupt)
- A timer reaching a set count (timer interrupt)
- Data being received over UART (communication interrupt)
This mechanism ensures the CPU doesn’t waste time polling for events and instead reacts only when necessary.
NVIC: The Brain Behind Interrupt Handling
The Nested Vectored Interrupt Controller (NVIC) is an integral part of the Cortex-M architecture in STM32 microcontrollers. It handles:
- Enabling/disabling individual interrupts
- Setting interrupt priorities (preemption and subpriority)
- Nesting interrupts
Without NVIC, managing multiple interrupts would be a chaotic task. NVIC ensures that higher-priority tasks can preempt lower-priority ones, maintaining system responsiveness.
Setting Up an Interrupt in STM32: A Step-by-Step Example
Let’s consider a practical use case: responding to a button press using an external interrupt.
1. Configure the Peripheral (EXTI)
The first step is to configure the specific GPIO pin to trigger an interrupt. This involves:
- Setting the pin as input
- Configuring it as an external interrupt source (EXTI)
- Choosing the edge trigger type (rising, falling, or both)
2. Enable the Interrupt in NVIC
After configuring the EXTI line, you need to enable the corresponding IRQ in the NVIC:
HAL_NVIC_SetPriority(EXTI0_IRQn, 2, 0); // Preemption priority 2, subpriority 0
HAL_NVIC_EnableIRQ(EXTI0_IRQn);
3. Implement the ISR (Interrupt Service Routine)
The ISR is the function that gets called when the interrupt occurs:
void EXTI0_IRQHandler(void) {
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0); // Handle the interrupt
}
Understanding Interrupt Prioritization
NVIC allows setting both preemption priority and subpriority. Here’s how they differ:
- Preemption Priority: Determines whether one interrupt can interrupt another.
- Subpriority: Used to resolve conflicts when two interrupts of the same preemption level occur simultaneously.
A practical tip: In time-critical applications (e.g., motor control), assign a higher preemption priority to ensure minimal latency.
Common Pitfalls and Best Practices
- Always clear the interrupt flag: Failure to do so can cause the ISR to run repeatedly.
- Keep ISRs short: Do only the essential work inside the ISR. Delegate longer tasks to the main loop or another thread.
- Avoid using delay() in ISRs: Delays inside an ISR can block other interrupts and degrade system performance.
Real-World Analogy
Think of NVIC as an air traffic controller at a busy airport. Every interrupt is like a plane wanting to land. The NVIC decides:
- Which plane (interrupt) lands first (priority)
- Whether an emergency landing (higher-priority interrupt) preempts others already in line
This coordination ensures a smooth and safe landing schedule—just like NVIC ensures responsive and orderly interrupt handling.
Why NVIC Matters in Advanced STM32 Projects
In complex projects like real-time audio processing or industrial automation, you might have dozens of peripherals demanding attention. NVIC makes sure you don’t drop the ball:
- High-speed ADC sampling can take priority over UI updates.
- Critical safety signals can preempt less important logging tasks.
Without NVIC, managing such complexity would be nearly impossible.
External Resources
FAQs
Q: Can I change interrupt priorities at runtime?
A: Yes, NVIC allows dynamic priority changes, but use this carefully to avoid unintended preemptions.
Q: What happens if two interrupts of the same priority occur simultaneously?
A: The one with the lower IRQ number gets serviced first.
Q: How many levels of priority are available?
A: This depends on the STM32 family, but most support up to 16 priority levels.
Q: Is NVIC only used for external interrupts?
A: No, NVIC handles both external and internal (peripheral-based) interrupts.
Q: What’s the difference between EXTI and NVIC?
A: EXTI handles the detection of external signals, while NVIC manages prioritization and dispatching of the corresponding interrupts.
Conclusion
Interrupts are the heartbeat of responsive embedded systems, and NVIC is the rhythm keeper. Whether you’re building a basic project or architecting a high-performance embedded solution, mastering these concepts will empower you to create robust, efficient, and scalable applications on STM32. Keep your ISRs lean, your priorities clear, and let NVIC do the heavy lifting.
If you found this article, How to Use Interrupts and NVIC in STM32 A Complete Developer’s Guide, helpful, share it with your friends and visit our website for more tutorials.