In this lesson, you will learn how to organize your system’s response to multiple simultaneous signals by assigning priority levels and using masking to selectively block specific interrupts.
The Need for Priority
When your microcontroller manages multiple peripherals—like an ADC completing a conversion and a Timer finishing a PWM cycle—it is possible for both to trigger an interrupt at the exact same moment. If both are equally important, the system might become sluggish. By assigning a numerical priority to each interrupt source, you tell the Nested Vectored Interrupt Controller (NVIC) which event is "more important." A higher priority interrupt can preempt (interrupt) the execution of a lower priority one, ensuring critical tasks like motor control take precedence over background data logging.
Controlling Flow with Masking
While priority dictates who goes first, masking dictates who is even allowed to speak. Masking acts like a gatekeeper. By setting a mask bit in a register, you can temporarily disable specific interrupts without turning off the peripheral itself.
For example, if you are performing a time-sensitive calculation in your main loop, you might want to mask "non-essential" interrupts to prevent them from interrupting your math. Once the calculation is finished, you "unmask" them to resume normal operation.
Practical Implementation
Consider a system where a high-priority motor interrupt must never be delayed by a low-priority sensor update:
// Setting priorities (Lower numbers typically mean higher priority)
NVIC_SetPriority(Motor_IRQn, 0); // Highest priority
NVIC_SetPriority(Sensor_IRQn, 1); // Lower priority
// Masking a peripheral interrupt
NVIC_DisableIRQ(Sensor_IRQn); // Stop sensor events from firing
// ... Execute time-critical code ...
// Unmasking to resume handling
NVIC_EnableIRQ(Sensor_IRQn); // Allow sensor interrupts again
By balancing these two tools, you create a responsive system where high-stakes events are handled immediately, while less critical tasks wait for a quieter moment. This prevents "interrupt nesting" chaos and keeps your system stable during peak activity.
Key Takeaway: Interrupt priorities determine the order of execution when multiple events occur simultaneously, while masking allows you to strategically disable specific interrupts to protect sensitive code execution.