What Are Interrupts in a Microcontroller and How Do They Work?

A microcontroller often needs to respond to events happening outside the processor. A button may be pressed, a timer may expire, a sensor may produce new data, or another device may send a message.

One way to detect these events is to repeatedly check the hardware in a program loop. This method is called polling.

Another method is to use interrupts. An interrupt allows hardware or software to notify the processor that an event needs attention.

Interrupts are one of the most important concepts in embedded programming because they allow a microcontroller to respond quickly to events while continuing to perform other tasks.

What Is an Interrupt?

An interrupt is a mechanism that temporarily changes the normal flow of processor execution so that the microcontroller can respond to a specific event.

When an interrupt occurs, the processor saves enough information to continue its current program later, executes a special function called an interrupt service routine, and then returns to the previous program.

The exact mechanism depends on the processor architecture, but the basic idea is similar across many microcontrollers.

Why Are Interrupts Needed?

Without interrupts, firmware may need to repeatedly check every device to determine whether something has happened.

For example, a program might continuously check a button, timer, UART receiver, ADC, and sensor.

This can waste processor time and make the software harder to manage.

Interrupts allow the hardware to notify the processor only when a relevant event occurs.

Polling vs Interrupts

Polling means that the processor repeatedly checks the state of a device.

An interrupt allows the device or peripheral to notify the processor when an event occurs.

Polling can be simple and predictable for some applications, while interrupts are useful when events are asynchronous, frequent, or need quick attention.

Simple Polling Example

Imagine a button connected to a GPIO input.

A polling program might repeatedly read the GPIO pin inside an infinite loop and check whether the button has been pressed.

The processor must continue checking the input even when nobody is pressing the button.

Simple Interrupt Example

With an interrupt, the GPIO hardware can detect a configured change on the button input and notify the processor.

The processor can then execute an interrupt service routine to handle the button event.

Between events, the processor can perform other work or enter a low-power mode.

What Is an Interrupt Service Routine?

An Interrupt Service Routine, commonly called an ISR, is a special function that runs when a particular interrupt occurs.

The ISR should normally perform only the work necessary to handle the event or record that the event occurred.

Long or complicated operations are often better handled by the main program after the ISR has finished.

Basic Interrupt Flow

The general interrupt process can be represented as a sequence.

An event occurs, the peripheral generates an interrupt request, the interrupt controller determines whether the interrupt is enabled, the processor temporarily pauses normal execution, the ISR runs, and the processor returns to the previous program.

What Is an Interrupt Request?

An interrupt request is a signal indicating that a hardware or software event requires processor attention.

The request can originate from a GPIO peripheral, timer, communication peripheral, ADC, watchdog, or another hardware block.

What Is an Interrupt Controller?

An interrupt controller manages interrupt requests and determines which interrupts should be delivered to the processor.

Modern microcontrollers can have many interrupt sources, so the interrupt controller helps organize and prioritize them.

What Is Interrupt Priority?

Interrupt priority determines which interrupt should receive attention first when multiple interrupt events occur.

A high-priority interrupt may be allowed to interrupt a lower-priority interrupt depending on the processor architecture and configuration.

Priority is useful when some events require faster or more predictable responses than others.

What Is Interrupt Latency?

Interrupt latency is the time between an interrupt event occurring and the processor beginning to execute the corresponding interrupt handler.

Lower latency can be important in applications such as motor control, communication, measurement systems, and other time-sensitive embedded systems.

What Is a Hardware Interrupt?

A hardware interrupt is generated by a hardware component or peripheral when a particular event occurs.

Examples include a GPIO edge, timer overflow, received UART data, completed ADC conversion, or communication peripheral event.

What Is a Software Interrupt?

A software interrupt is generated by executing a specific instruction or software mechanism that causes an interrupt-like transition into a handler.

Software interrupts can be used for operating-system services, controlled transitions, exceptions, or other processor-specific functions.

What Is a GPIO Interrupt?

A GPIO interrupt allows a microcontroller to respond when an input pin changes state.

The GPIO system can often be configured to generate an interrupt on a rising edge, falling edge, or another supported condition.

Rising Edge

A rising-edge interrupt occurs when a digital signal changes from LOW toward HIGH.

Falling Edge

A falling-edge interrupt occurs when a digital signal changes from HIGH toward LOW.

Both Edges

Some microcontrollers can generate interrupts on both rising and falling signal transitions.

GPIO Interrupt Example

Suppose a button is connected to a GPIO input with a pull-up resistor.

When the button is not pressed, the input remains HIGH. When the button is pressed, the input is connected to ground and becomes LOW.

The microcontroller can be configured to generate an interrupt when the signal changes from HIGH to LOW.

The ISR can then record that the button was pressed.

Why Button Interrupts Can Be Tricky

Mechanical buttons can produce multiple rapid electrical transitions when pressed or released.

This phenomenon is called switch bounce or contact bounce.

A single physical button press can therefore generate multiple interrupt events.

What Is Interrupt Debouncing?

Interrupt debouncing is the process of preventing mechanical button bounce from being interpreted as multiple valid button presses.

Software can ignore additional transitions for a short period or use a timer to confirm that the signal has remained stable.

Hardware filtering can also be used when appropriate.

What Is a Timer Interrupt?

A timer interrupt occurs when a hardware timer reaches a configured condition.

For example, a timer can be configured to generate an interrupt every millisecond.

The firmware can use this periodic event to maintain software timing, update counters, schedule tasks, or perform periodic measurements.

Why Use Hardware Timers Instead of Software Delays?

A blocking software delay can prevent the processor from performing other work during the delay.

A timer interrupt can provide a timing event while the main program continues executing other tasks.

UART Interrupts

A UART peripheral can generate an interrupt when new data has been received.

The ISR can read the received byte and store it in a buffer for processing by the main program.

This allows the processor to perform other tasks instead of continuously checking whether new serial data has arrived.

ADC Interrupts

An ADC can generate an interrupt when an analog-to-digital conversion has completed.

The firmware can then read the conversion result and process the measured value.

DMA and Interrupts

Direct Memory Access, or DMA, can transfer data between peripherals and memory without requiring the CPU to handle every individual data transfer.

A DMA controller can generate an interrupt when a transfer has completed or when another configured condition occurs.

What Is an Interrupt Flag?

An interrupt flag is a hardware status indicator that records that a particular interrupt condition has occurred.

Depending on the microcontroller, the firmware or hardware may clear the flag when the interrupt is handled.

What Is an Interrupt Enable Bit?

An interrupt enable setting determines whether a particular interrupt source is allowed to generate an interrupt request to the processor.

A peripheral can sometimes set an interrupt flag even when its interrupt is disabled, depending on the hardware design.

What Happens When an Interrupt Occurs?

The processor generally saves information about its current execution state, identifies the interrupt handler, and transfers execution to that handler.

After the interrupt service routine finishes, the processor restores the necessary state and continues the interrupted program.

The exact registers and hardware operations involved depend on the processor architecture.

What Is a Vector Table?

Many microcontroller architectures use an interrupt vector table containing addresses or information that identifies handlers for different exceptions and interrupt sources.

When an interrupt occurs, the processor uses the appropriate vector to determine where the corresponding handler is located.

What Is a Nested Interrupt?

Nested interrupts occur when one interrupt handler is interrupted by another interrupt with sufficient priority.

This can be useful when a critical event must receive immediate attention, but it also increases software complexity.

Why Should an ISR Be Short?

While an ISR is executing, normal program execution may be delayed, and other interrupts may be blocked or affected depending on the configuration.

Long ISRs can therefore increase latency, reduce system responsiveness, and make timing behavior harder to predict.

What Should an ISR Usually Do?

An ISR should generally perform a small amount of urgent work, such as reading a hardware register, storing received data, clearing an interrupt condition, incrementing a counter, or setting a flag.

The main program can then perform more complicated processing outside the ISR.

Example: Sensor Data Interrupt

Imagine a sensor connected to a microcontroller that produces a data-ready signal whenever a new measurement is available.

The GPIO or communication peripheral can generate an interrupt when the signal occurs.

The ISR can record that new data is available, and the main program can then read and process the sensor data.

Interrupts and Low-Power Systems

Interrupts are particularly useful in low-power embedded systems.

A microcontroller can enter a sleep mode and wait for an interrupt from a timer, button, sensor, communication interface, or another permitted wake-up source.

When the event occurs, the processor wakes and executes the required code.

Interrupts in Real-Time Systems

Real-time systems often need to respond to events within defined timing requirements.

Interrupts can provide a mechanism for responding quickly to hardware events, although predictable real-time behavior also depends on processor architecture, interrupt priorities, software design, memory behavior, and the operating environment.

Interrupts and RTOS Systems

In systems using a real-time operating system, interrupts can be used to notify tasks that an event has occurred.

For example, an ISR may place received data into a buffer and signal a task to process the data.

This separates time-sensitive hardware handling from larger application-level processing.

Interrupts and Shared Data

When both normal program code and an ISR access the same variable or data structure, special care may be required.

The programmer must consider whether operations can be interrupted, whether data can change unexpectedly, and whether synchronization mechanisms are required.

What Is a Race Condition?

A race condition occurs when the behavior of software depends on the timing or ordering of operations that access shared data.

Interrupts can create race conditions if the main program and an ISR modify shared data without appropriate synchronization.

What Does volatile Mean in Embedded C?

In embedded C, the volatile keyword can be used for objects whose values may change unexpectedly from the perspective of ordinary program flow, such as variables modified by an ISR or hardware.

However, volatile does not by itself make complex operations atomic or provide complete synchronization.

What Is an Atomic Operation?

An atomic operation is an operation that cannot be observed in a partially completed state by another execution context.

Whether an operation is atomic depends on the processor architecture, data size, compiler behavior, and the specific operation being performed.

Common Interrupt Mistakes

Common mistakes include writing very long ISRs, forgetting to clear interrupt conditions, using shared data incorrectly, ignoring button bounce, assigning inappropriate priorities, and performing blocking operations inside interrupt handlers.

These mistakes can cause missed events, unexpected behavior, timing problems, or system instability.

Can Every GPIO Pin Generate an Interrupt?

Not necessarily. GPIO interrupt capabilities vary between microcontrollers.

Some chips allow interrupts on many or most GPIO pins, while others provide more limited routing or interrupt functionality.

The microcontroller's datasheet and reference manual should be checked before designing around a particular interrupt source.

Interrupt Example: Digital Door Sensor

Consider a device that monitors whether a door is open or closed.

The door sensor can be connected to a GPIO input configured to generate an interrupt when its state changes.

The ISR can record the change, and the main application can update a display, activate an alarm, or send a notification.

Interrupt Example: Motor Control

A motor-control system may use timer interrupts to execute control calculations at regular intervals.

Other interrupts can be used to capture sensor events, detect faults, or process communication with external controllers.

Interrupts vs Continuous Loops

A continuous loop is simple and can work well when the application is small and timing requirements are straightforward.

Interrupts become valuable when the system must react to events independently of the main program's current activity.

When Should You Use Interrupts?

Interrupts are useful for asynchronous events, periodic timing, incoming communication, hardware state changes, sensor notifications, and situations where the processor should not constantly poll a peripheral.

When Might Polling Be Better?

Polling can be appropriate when the system is simple, events are predictable, response time is not critical, or the additional complexity of interrupts is unnecessary.

There is no universal rule that interrupts are always better than polling.

Why Interrupts Are Important

Interrupts provide an efficient connection between hardware events and software execution.

They allow microcontrollers to react to buttons, timers, sensors, communication interfaces, and other peripherals without requiring the main program to continuously check every possible event.

The Future of Interrupt-Based Embedded Systems

As microcontrollers become more capable, they include increasingly sophisticated interrupt systems, event-routing hardware, DMA controllers, timers, communication peripherals, and low-power wake-up mechanisms.

These features allow embedded systems to respond efficiently to complex combinations of hardware events while reducing processor workload and energy consumption.

An interrupt is essentially a way for a microcontroller to say, 'Something important happened; handle it now.'

By understanding interrupts, developers can build firmware that responds efficiently to buttons, timers, sensors, communication events, and other hardware signals.

The simplest way to understand an interrupt is this: polling means the CPU repeatedly asks whether something happened, while an interrupt allows the hardware to notify the CPU when something actually happens.

Interrupts are especially useful for GPIO events, timers, communication, sensors, low-power systems, and real-time applications. Good interrupt design usually means keeping interrupt handlers short and moving larger processing tasks into the main program or an appropriate task.

Note: Tip: After learning interrupts, explore timers and counters, PWM, ADC, UART, I2C, SPI, DMA, interrupt priorities, volatile variables, atomic operations, real-time operating systems, and embedded C.