Interrupts: reacting without waiting
Let the hardware call your function when something happens, and the rules that keep that safe.
Read this first
So far the main loop checks everything by asking again and again: is the button pressed, has a byte arrived. That is called polling, and it stops working when the loop gets busy or the event is short. An interrupt turns it around: the hardware pauses the main loop, runs a function of yours called an interrupt handler or ISR, and resumes the loop exactly where it was.
On Cortex-M a handler is an ordinary C function with a fixed name that comes from the chip maker's startup file, such as TIM2_IRQHandler or EXTI0_IRQHandler on STM32, taking no arguments and returning nothing. You enable the interrupt in the peripheral and in the NVIC, the interrupt controller, and from then on the hardware calls it.
The one design rule: keep the handler short. Record what happened, set a flag, put a byte in a buffer, then return. Do the slow work in the main loop. Anything that waits inside a handler, a delay, a printf over a slow UART, stalls every interrupt at the same or lower priority and often the whole system.
The flag that a handler sets and the main loop reads must be declared volatile. Without it the compiler may read the flag once into a register and never look at memory again, so the loop waits forever on a value the handler already changed. Volatile tells the compiler that the value can change behind its back and must be read from memory every time. It does not make anything atomic; that is a separate topic for later.
To remember
- Polling asks. An interrupt is the hardware calling your function.
- A handler is a void function with no parameters and a fixed name.
- Keep handlers short: record the event, do the work in the main loop.
- A flag shared with a handler must be volatile, so every read goes to memory.
Check what you read
4 questions from the question bank on the ideas above. Each one comes with an explanation after you answer.
Sign in to answer the questions. Your answers count towards your level.
Sign inThe lesson text and the project are free to read without an account.
Build this
Button interrupt and a reaction timer
You need
- Your board, the debounced button and the LED.
- Serial output working.
Steps
- Configure the button pin to raise an interrupt on the falling edge. In the handler, only set a volatile flag and record the millisecond tick.
- In the main loop, when the flag is set, clear it. If the recorded tick is within 30 ms of the previous accepted press, ignore it: that is the bounce from lesson 3 arriving as several interrupts. Otherwise print the time and toggle the LED. Confirm a press is caught even while the loop is busy in a long delay.
- Build a reaction timer: turn the LED on after a random delay, then measure the time until the button interrupt fires. Print it in milliseconds.
- Remove the volatile keyword, build with optimization, and see whether the program still reacts. Put it back.
Done when
The reaction time prints correctly, the handler contains no delay and no print, and you saw what happens without volatile.