This is an old revision of the document!


Interrupts

Interrupt is a signal that stops the normal execution of a program in the processor and starts the function assigned to a specific source of it. Such a function usually is called Interrupt Service Routine (ISR) or interrupt handler. The ISR can be recognized as a task with higher priority than the main program. Interrupt signals can be generated by the external source, like a change of value on the pin, and by the internal source, like a timer or any other peripheral device. When the interrupt signal is received, the processor stops executing the code and starts the ISR. After completing the interrupt handler, the processor returns to the normal program execution state.

ISR should be as short as possible, good practice is to avoid delays and long code sequences in it. If there is a need to trigger execution of a long part of the code with an incoming interrupt signal the good practice is to define the synchronization variable, modify this variable in the ISR with a single instruction, and handle all other steps in the main program. Interrupt handler does not have arguments and does not return any value so its type is void. To ensure fast execution of the programs some of the Arduino functions do not work or behave differently in the ISR, for example, delay() function does not work inside the ISR. Variables, used in the ISR must be declared as volatile.

Interrupts are used to detect important real-time events, which occur during the normal code execution of the code. ISR is executed only when there is a need to do it.

Polling vs. interrupts

Interrupts can help in efficient data transmission. Using interrupt there is no need to periodically check if some situation occurred. Such continuous checking is named polling. For example, a serial port interrupt is executed only when new data came, without polling the incoming buffer in a loop. This approach saves the processor time and in many situations preserves energy.

Interrupt handling example

Because interrupts need support from the hardware layer of the microcontroller, the availability of specific interrupt sources depends heavily on the microcontroller model. For example, different Arduino models have different external interrupt pin availability. In most Arduino boards pins numbered 2 and 3 can be used for interrupts, in Arduino Uno only these two, while in ESP32 any digital pin is valid.

Very often interrupts are used together with hardware timers to generate stable frequency signals. It ensures accurate timing independent of the main loop content and delays. Because internal peripherals are very different for different microcontrollers in this chapter the example for external interrupt is shown.

To attach an interrupt to the handler the function attachInterrupt(digitalPinToInterrupt(pin), ISR, mode) is called. This function has 3 arguments.

  1. pin – the pin number where the interrupt signal-generating device will be attached.
  2. ISR – the name of an ISR function.
  3. mode – defines when an interrupt signal is triggered. There are five basic mode values:
    • LOW – interrupt is triggered when the pin value is LOW,
    • HIGH – interrupt is triggered when the pin value is HIGH,
    • RISING – interrupt is triggered when the pin value is changed from LOW to HIGH,
    • FALLING – interrupt is triggered when the pin value is changed from HIGH to LOW,
    • CHANGE – interrupt is triggered when the pin value is changed in any direction.

The example program that uses external interrupt:

volatile bool button_toggle = 0; //A variable to pass the information from ISR to the main program
 
void setup() {
  //Define LED pin
  pinMode(13,OUTPUT);       
  //Define button pin
  pinMode(2,INPUT_PULLUP);  
  //Attach interrupt to button pin
  attachInterrupt(digitalPinToInterrupt(2),ButtonIRS,FALLING); 
}
 
void ButtonIRS() {  //IRS function
  button_toggle =!button_toggle;
}
 
void loop() {
  digitalWrite (13,button_toggle);
}

In this example, the code needed to handle the interrupt signal is just one instruction but it shows how to use the synchronization variable to pass information from ISR to the main program keeping the ISR very short.

en/iot-open/introductiontoembeddedprogramming2/cppfundamentals/interrupts.1687717258.txt.gz · Last modified: 2023/06/25 15:20 (external edit)
CC Attribution-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0