How to Set Interrupt Priority in ARM Cortex-M Processors
To set interrupt priority in ARM Cortex-M, use the
NVIC_SetPriority(IRQn, priority) function or write directly to the NVIC->IP registers. The priority value is a number where lower means higher priority, and the number of priority bits depends on the specific Cortex-M model.Syntax
The main way to set interrupt priority is using the CMSIS function:
void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
Where:
IRQnis the interrupt number (negative for system exceptions, positive for external interrupts).priorityis the priority level, with lower numbers meaning higher priority.
Alternatively, you can write directly to the NVIC->IP array, where each element corresponds to an interrupt priority register byte.
c
void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority); // Direct register access example: NVIC->IP[IRQn] = (priority << (8 - __NVIC_PRIO_BITS));
Example
This example sets the priority of the USART1 interrupt to a high priority (lower number) and enables it.
c
#include "stm32f4xx.h" // Example CMSIS header int main(void) { // Set USART1 interrupt priority to 2 (assuming 4 bits of priority) NVIC_SetPriority(USART1_IRQn, 2); // Enable USART1 interrupt NVIC_EnableIRQ(USART1_IRQn); while(1) { // Main loop } }
Common Pitfalls
Common mistakes when setting interrupt priority include:
- Using a priority value outside the allowed range. The number of priority bits (
__NVIC_PRIO_BITS) varies by Cortex-M model, so check your device. - Confusing priority numbers: lower numbers mean higher priority.
- Not enabling the interrupt after setting priority.
- Writing priority values without shifting according to
__NVIC_PRIO_BITS, causing incorrect priority settings.
c
/* Wrong way: setting priority without shifting */ NVIC->IP[USART1_IRQn] = 2; // Incorrect if __NVIC_PRIO_BITS < 8 /* Right way: shift priority to align with priority bits */ NVIC->IP[USART1_IRQn] = (2 << (8 - __NVIC_PRIO_BITS));
Quick Reference
| Function/Register | Description | Notes |
|---|---|---|
| NVIC_SetPriority(IRQn, priority) | Sets interrupt priority using CMSIS | Priority 0 = highest, max depends on __NVIC_PRIO_BITS |
| NVIC_EnableIRQ(IRQn) | Enables the interrupt in NVIC | Must be called after setting priority |
| NVIC->IP[IRQn] | Direct register to set priority | Priority value must be shifted by (8 - __NVIC_PRIO_BITS) |
| __NVIC_PRIO_BITS | Number of implemented priority bits | Check device header or datasheet |
Key Takeaways
Use NVIC_SetPriority() to set interrupt priority safely and portably.
Lower priority numbers mean higher interrupt priority.
Shift priority values correctly when writing directly to NVIC->IP registers.
Always enable the interrupt after setting its priority.
Check __NVIC_PRIO_BITS for your Cortex-M device to know valid priority range.