0
0
Cnc-programmingHow-ToBeginner · 3 min read

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:

  • IRQn is the interrupt number (negative for system exceptions, positive for external interrupts).
  • priority is 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/RegisterDescriptionNotes
NVIC_SetPriority(IRQn, priority)Sets interrupt priority using CMSISPriority 0 = highest, max depends on __NVIC_PRIO_BITS
NVIC_EnableIRQ(IRQn)Enables the interrupt in NVICMust be called after setting priority
NVIC->IP[IRQn]Direct register to set priorityPriority value must be shifted by (8 - __NVIC_PRIO_BITS)
__NVIC_PRIO_BITSNumber of implemented priority bitsCheck 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.