Theory Lecture Week 3M MES DR RukonuzzamanV - 2 - 0
Theory Lecture Week 3M MES DR RukonuzzamanV - 2 - 0
Arduino Interrupts
2
Introduction
▪ Microcontroller normally executes instructions in an orderly fetch-execute sequence as dictated
by a user-written program. However, a microcontroller must also be ready to handle
unscheduled events that might occur inside or outside the microcontroller.
▪ The interrupt system onboard a microcontroller allows it to respond to these internally and
externally generated events. By definition, we do not know when these events will occur.
▪ When an interrupt event occurs, the microcontroller will normally complete the instruction it is
currently executing and then will transfer the program control to an Interrupt Service Routine
(ISR) that handles the interrupt.
▪ Once the ISR is complete, the microcontroller will resume processing where it left off before the
interrupt event occurred.
3
Interrupts
• A request for the processor to ‘interrupt’ the currently executing process, so the event
can be processed in a timely manner. Also referred to as ‘trap’
• If the request is accepted: the processor suspends current processes, saves its states,
and executes Interrupt Service Routine (ISR) or, Interrupt Handler
• Concept of ‘Interrupt’ is very useful when implementing any of the switch
debouncing methods.
• Scheduled events are not interrupts
4
Introduction
5
Why do we need it?
• Let’s think about a real-life example:
• You are heating up your food using the microwave.
• In this case, you can either:
▪ Stare at the microwave while it heats up the food
▪ Go about your life normally and go to the microwave when you get the signal that the food has been heated up
• Which of the above-mentioned options do you think is more efficient?
• Usually, we want to go about our life while the food is being heated up.
• This is because we want to make efficient use of our time.
• It is very similar for processors as well.
• We hear the ting sound from the microwave, stop what we are doing, and go to take out the heated food.
• This ‘ting’ sound is an interrupt.
• Similarly, if the processor is waiting for some conditions to be fulfilled to perform a specific task (task 1):
▪ It can wait and halt other processes till the conditions for that task is fulfilled.
▪ It can execute the normal instructions and halt them for a brief time once the conditions for task 1 have been fulfilled, finish task 1 and go
back to executing the main routine.
• Clearly, the 2nd option is better for maximizing the processor’s resource utilization.
• This is where interrupts come in handy.
• When the conditions for task 1 has been met, it can simply trigger an interrupt, stop the main routine to complete the task and
once finished go back to the main routine.
6
The Main Reasons You Might Use Interrupts
7
Interrupt Vector
• The interrupt vectors and vector table are crucial to the understanding of hardware
and software interrupts. Interrupt vectors are addresses that inform the interrupt
handler as to where to find the ISR (Interrupt Service Routine, also called Interrupt
Service Procedure).
• Misspelling the vector name (even wrong capitalization) will result in the ISR not
being called and it will not also result in a compile error.
• As per the datasheet, the minimal amount of time to service an interrupt is 82 clock cycles in
total. Assuming a 16 MHz clock, there would be 62.5 ns time needed per clock cycle. So, the
total time required is 5.125 ms.
▪ When an ISR is entered, interrupts are disabled. Naturally, they must have been enabled
in the first place, otherwise, the ISR would not be entered. However, to avoid having an
ISR itself be interrupted, the processor turns interrupts off.
▪ When an ISR exits, then interrupt are enabled again. The compiler also generates code
inside an ISR to save registers and status flags, so that whatever you were doing when
the interrupt occurred will not be affected.
▪ However, you can turn interrupts on inside an ISR if you absolutely must.
// Interrupt Service Routine (ISR)
void pinChange (){
// handle pin change here
interrupts (); // allow more interrupts
} // end of pinChange
• The ATmega328P provides support for 25 different interrupt sources. These interrupts and
the separate Reset Vector each have a separate program vector located at the lowest
addresses in the Flash program memory space.
• The complete list of “Reset and Interrupt Vectors” in ATMega328P is shown in this table.
Each Interrupt Vector occupies two instruction words.
• The list also determines the priority levels of the different interrupts. The lower the address
the higher is the priority level. RESET has the highest priority, and next is INT0 – the
External Interrupt Request 0.
13
Atmega328p Interrupt Vector Table
14
List of interrupts, priority order in ATmega328p
15
Trigger
Remember, the ISR is a separate routine and requires a separate flowchart to represent.
• Keep it short
• Don't use delay ()
• Don't do serial prints
• Make variables shared with the main code volatile
• Variables shared with the main code may need to be protected by "critical sections" (see
below)
• Don't try to turn interrupts off or on
Variables shared between ISR functions and normal functions should be declared
"volatile". This tells the compiler that such variables might change at any time, and thus
the compiler must reload the variable whenever you reference it, rather than relying
upon a copy it might have in a processor register.
void loop ()
{
if (flag)
{
// interrupt has occurred
}
} // end of loop
• When an interrupt occurs, the microcontroller completes the current instruction and stores
the address of the next instruction on the stack.
• It also turns off the interrupt system to prevent further interrupts while one is in progress. This is
done by clearing the SREG Global Interrupt Enable I-bit.
• The Interrupt flag bit is cleared for Type 1 Interrupts only (see the next Slide for Type
definitions).
22
Atmega328p Interrupt Processing
• The execution of the ISR is performed by loading the beginning address of the ISR specific
for that interrupt into the program counter. The processor starts running the ISR.
• Execution of the ISR continues until the Return from Interrupt instruction (RETI) is
encountered. The SREG I-bit is automatically set when the RETI instruction is executed
(i.e., Interrupts enabled).
• When the processor exits from an interrupt, it will always return to the interrupted program
and execute one more instruction before any pending interrupt is served.
• The Status Register is not automatically stored when entering an interrupt routine, nor
restored when returning from an interrupt routine. This must be handled by software.
23
Atmega328p Interrupt Processing – Type 1
• The user software can write logic one to the I-bit to enable nested interrupts. All enabled
interrupts can then interrupt the current interrupt routine.
o The SREG I-bit is automatically set to logic one when a Return from Interrupt instruction
(RETI) is executed.
24
Atmega328p Interrupt Processing – Type 1
▪ If the same interrupt condition occurs while the corresponding interrupt enables bit is
cleared, the Interrupt Flag will be set and remembered until the interrupt is enabled, or the
flag is cleared by software (interrupt canceled).
▪ Interrupt Flag can be cleared by writing a logic one to the flag bit position(s) to be cleared.
o If one or more interrupt conditions occur while the Global Interrupt Enable (SREG I)
bit is cleared, the corresponding Interrupt Flag(s) will be set and remembered until the
Global Interrupt Enable bit is set on return (RETI) and will then be executed by order
of priority.
25
Atmega328p Interrupt Processing – Type 2
The second type (Type 2) of interrupts will trigger as long as the interrupt
condition is present. These interrupts do not necessarily have Interrupt Flags. If
the interrupt condition disappears before the interrupt is enabled, the interrupt will
not be triggered.
26
TIMSK0 – Timer/Counter0 Interrupt Mask Register
27
TIMSK0 – Timer/Counter0 Interrupt Mask Register
30
TIFR0 – Timer/Counter0 Interrupt Flag Register
31
TIMSK1 – Timer/Counter1 Interrupt Mask Register
32
TIMSK1 – Timer/Counter1 Interrupt Mask Register
33
TIMSK1 – Timer/Counter1 Interrupt Mask Register
34
TIFR1 – Timer/Counter1 Interrupt Flag Register
36
TIFR1 – Timer/Counter1 Interrupt Flag Register
• Bit 1 – OCF1A: Timer/Counter1, Output Compare A Match Flag
This flag is set in the timer clock cycle after the counter (TCNT1) value matches the Output
Compare Register A (OCR1A). Note that a Forced Output Compare (FOC1A) strobe will not set
the OCF1A Flag. OCF1A is automatically cleared when the Output Compare Match A
interrupt Vector is executed. Alternatively, it can be cleared by writing a logic one to its bit
location.
37
500 ms Blink Example Code using Timer1 Interrupts
Timer 1 is used here. The values of TCCR1A and 1B are reset to 0 to make sure everything is
clear. TCCR1B was set equal to 00000100 for a prescalar of 256. If you want to set ones, an OR
operation can be used. If you want to set zeros, an AND operation can be used. The compare
match mode for the OCR1A register is enabled. For that, the OCIE1A bit was set to be a 1 and
that’s from the TIMSK1 register. So, we equal that to OR and this byte 00000010.
The OCR1A register was set to 31250 value so that we will have an interruption each 500ms.
Each time the interrupt is triggered, we go to the related ISR vector. Since we have 3 timers, we
have 6 ISR vectors, two for each timer and they have these names:
38
500 ms Blink Example Code using Timer1 Interrupts
Timer 1 and compare register A was used so we need to use the ISR TIMER1_COMPA_vect.
So below the void loop, the interruption routine is defined. Inside this interruption, the state of
the LED was inverted, and a digital write was created. But first, the timer value was reset.
Otherwise, it will continue to count up to its maximum value. So, for each 500 ms, this code
will run and invert the LED state and that creates a blink of the LED connected to pin D5, for
example.
39
500 ms Blink Example Code using Timer1 Interrupts and Pre-scalar values of 256
• We use the pre-scalar value of 256 to reduce the timer clock frequency to 16 MHz/256 = 62.5 kHz, with a
new timer clock period = 1/62.5 kHz = 16 μs. Thus, the required timer count = (500,000 ms/16 μs) – 1 =
31,250 – 1 = 31,249. So, this is the value that we should store in the OCR register.
void loop() {
// put your main code here, to run repeatedly.
}
// With the settings above, this ISR will trigger each 500 ms.
ISR(TIMER1_COMPA_vect){
TCNT1 = 0; // First, set the timer back to 0 so that it resets for the next interrupt
LED_State = !LED_State; // Inverting the LED State
digitalWrite(13, LED_State); // Writing this new state to the LED connected to pin D5
}
41
External Interrupts
• External Interrupts activated by the external pin INT1 or INT0 if the SREG I-flag and
the corresponding interrupt mask are set.
• Level/edge on INT1/INT0 pin which activates interrupts:
• PCINT 23:16 –
▫ PD7:PD0 on ATMega328P
▫ Pins D7:D0 (GPIO) on Arduino Uno board
• PCINT 14:8 –
▫ PC6:PC0 on ATMega328P
▫ PC5:0 – Pins A5:A0 on Arduino Uno board
▫ PC6 – Reset pin on Arduino Uno Board
• PCINT 7:0 –
▫ PB7:PB0 on ATMega328P
▫ PB5:0 – Pins D13:D8 on Arduino Uno board
▫ PB6 and PB7 are not available externally on the Arduino Uno board
• ATMega328 Datasheet
• Arduino Uno Datasheet
• Chapter 5: Microprocessors, Advanced Industrial Control Technology by Peng Zhang
• http://www.ganssle.com/debouncing-pt2.htm
• https://mansfield-devine.com/speculatrix/2018/04/debouncing-fun-with-schmitt-triggers-and-capacitors/
• https://www.arxterra.com/10-atmega328p-interrupts/
• https://www.arxterra.com/11-atmega328p-external-interrupts/
• http://www.gammon.com.au/forum/?id=11488