You are on page 1of 29

Interrupt

Chapter 10

Sepehr Naimi

www.NicerLand.com
Contents
 Polling Vs. interrupt
 Interrupt unit
 Steps in executing an interrupt
 Edge trigger Vs. Level trigger in external
interrupts
 Timer interrupt
 Interrupt priority
 Interrupt inside an interrupt
 Task switching and resource conflict
 C programming
2
Polling Vs. Interrupt
 Polling  Interrupt
 Ties down the CPU  Efficient CPU use
 Has priority
 Can be masked

while (true) main( )


{ {
if(PIND.2 == 0) Do your common task
//do something; }
}
whenever PIND.2 is 0 then
do something

3
Interrupt Controllers

Peripherals
Timers
IRQ0
CPU IRQ1 I/Os
Interrupt IRQ2
Controller IRQ3 USART

….
IRQn
SPI

4
Interrupt control unit in AVR

SREG I T RAM
H S V EEPROM
N Z C Timers

PROGRAM
ROM

Program
Bus Bus
CPU

SREG

EIMSK
PCICR
PCMSK0
PCMSK1 Other
OSC PCMSK2 Ports
Peripherals
Interrupt Unit
TIMSK0
TIMSK1
TIMSK2 I/O
PINS

5
Interrupt vectors in ATmega328
Interrupt Address
(hex)
Reset 0000
External Interrupt Request 0 0002
External Interrupt Request 1 0004
Pin Change Interrupt Request 0 0006
Pin Change Interrupt Request 1 0008
Pin Change Interrupt Request 2 000A
Watchdog Time-out Interrupt 000C
Timer/Counter2 Compare Match A 000E
Timer/Counter2 Compare Match B 0010
Timer/Counter2 Overflow 0012
Timer/Counter1 Capture Event 0014
Timer/Counter1 Compare Match A 0016
Timer/Counter1 Compare Match B 0018
Timer/Counter1 Overflow 001A
Timer/Counter0 Compare Match A 001C
6
External Interrupts

7
External Interrupts
D7 D0
EIMSK: - - - - - - INT1 INT0

28 pin
(PCINT14/RESET) PC6 1 28 PC5 (ADC5/SCL/PCINT13)
(PCINT16/RXD) PD0 2 27 PC4 (ADC4/SDA/PCINT12)
(PCINT17/TXD) PD1 3 26 PC3 (ADC3/PCINT11)
(PCINT18/INT0) PD2 4 MEGA328 25 PC2 (ADC2/PCINT10)
(PCINT19/OC2B/INT1) PD3 5 24 PC1 (ADC1/PCINT9)
(PCINT20/XCK/T0) PD4 6 23 PC0 (ADC0/PCINT8)
VCC 7 22 GND
GND 8 21 AREF
(PCINT6/XTAL1/TOSC1) PB6 9 20 AVCC
(PCINT7/XTAL2/TOSC2) PB7 10 19 PB5 (SCK/PCINT5)
(PCINT21/OC0B) PD5 11 18 PB4 (MISO/PCINT4)
(PCINT22/OC0A/AIN0) PD6 12 17 PB3 (MOSI/OC2A/PCINT3)
(PCINT23/AIN1) PD7 13 16 PB2 (SS/OC1B/PCINT2)
(PCINT0/CLKO/ICP1) PB0 14 15 PB1 (OC1A/PCINT1)

Edge/level
PD2(INT0)
detector
EIMSK.INT0 PC=0x0002

I bit of SREG
EICRA.ISC0x
8
Edge trigger Vs. Level trigger in external interrupts
Bit D7 D0

EICRA: - - - - ISC11 ISC10 ISC01 ISC00

INT1 INT0

ISCx1 ISCx0

0 0

0 1

1 0

1 1

EICRA = 0x02; //INT0 on falling edges

9
External Interrupt Sample Code
 Write a program that whenever INT0 goes low, it
toggles PB5 once.

1 .ORG 0 ;location for reset 18 EX0_ISR:


2 JMP MAIN 19 IN R21,PORTB
3 .ORG 0x02 ;loc. for external INT0 20 LDI R22,(1<<5) ;for toggling PB5
4
INT0 21
JMP EX0_ISR EOR R21,R22
5 MAIN: ISR 22 OUT PORTB,R21
6 LDI R20,HIGH(RAMEND) 23 RETI
7 OUT SPH,R20 24
8 LDI R20,LOW(RAMEND) 25
9 OUT SPL,R20 ;initialize stack
10 LDI R20,0x2 ;make INT0 falling
11 STS EICRA,R20
12 SBI DDRB,5 ;PORTB.5 = output
13 SBI PORTD,2 ;pull-up activated
14 LDI R20,1<<INT0 ;enable INT0
Ex. INT0.
15 OUT EIMSK,R20
16 SEI ;enable interrupts
enable
17 HERE:JMP HERE

10
Steps in executing an interrupt
PC6 1 28 PC5
Code
PD0 2 27 PC4
Address .ORG 0
26 PC3
PD1 3 0000 JMP MAIN
(INT0) PD2 4 25 PC2 0002 .ORG 0x02

(INT1) PD3 5 0002 24 PC1 0002 JMP EX0_ISR

23 PC0 0004 MAIN: LDI R20,HIGH(RAMEND)


PD4 6 0005 OUT SPH,R20
VCC 7 22 GND 0006 LDI R20,LOW(RAMEND)
GND 8
ATmega328 21 PB7 0007 OUT SPL,R20

PB6 20 AVCC 0008 LDI R20,0x2 ;make INT0 falling


9
0009 STS EICRA,R20
PB7 10 PC: 0016
0015
0014
0013
0012
000D
0009
000A
000B
000C
0006
0008
000F
0004
000E
0007
0005
0000 19 PB5
000A SBI PORTD,2 ;pull-up activated
PD5 18 PB4 000B LDI R20,1<<INT0 ;enable INT0
11
PD6 12 17 PB3 000C OUT EIMSK,R20

PD7 16 PB2 000D SEI ;enable interrupts


13
000E SBI DDRB,5 ;PORTB.5 = output
PB0 15 PB1
14 000F HERE: INC R25
0010 JMP HERE
EX0_ISR:
0012 IN R21,PORTB
SP 0013 LDI R22,(1<<5) ;for toggling PB5
0014 EOR R21,R22
0015 OUT PORTB,R21
0016 RETI

Stack

11
Timer Interrupts

12
Timer Interrupts

- - - - - OCF0B OCF0A TOV0 TIFR0


D7 D0
TIMSK0: - - - - - OCIE0B OCIE0A TOI0E

- - ICF1 - - OCF1B OCF1A TOV1 TIFR1


D7 D0
TIMSK1: - - ICIE - - OCIE1B OCIE1A TOI1E

- - - - - OCF2B OCF2A TOV2 TIFR2


D7 D0
TIMSK2: - - - - - OCIE2B OCIE2A TOI2E

TOV0
TOIE0 PC=0x0020

I bit of SREG

13
Using Timer0 overflow interrupt
ATmega328
 This program uses Timer0 to generate a square +5

wave on pin PORTB.5, while at the same time PORTB.5

data is being transferred from PORTC to PORTD. PORTD PORTC

1 .ORG 0x0 ;location for reset 19 SBI DDRB,5 ;PB5 as an output


2 JMP MAIN 20 LDI R20,0x00
3 .ORG 0x20 ;location for Timer0 ov. 21 OUT DDRC,R20 ;make PORTC input
4 JMP T0_OV_ISR ;jump to ISR for T0 22 LDI R20,0xFF
5 ;-main program for initialization 23 OUT PORTC,R20 ;enable pull-up
6 MAIN: LDI R20,HIGH(RAMEND) 24 OUT DDRD,R20 ;make PORTD output
7 OUT SPH,R20 25 HERE:IN R20,PINC ;read from PORTC
8 LDI R20,LOW(RAMEND) 26 OUT PORTD,R20 ;give it to PORTD
9 OUT SPL,R20 ;initialize stack 27 JMP HERE
10 LDI R20,-32 ;value for 2 us 28 T0_OV_ISR:
11 OUT TCNT0,R20 ;load Timer0 Timer029 IN R16,PORTB ;read PORTB
12 LDI R20,0x00 ISR 30 LDI R17,(1<<5) ;for toggling PB5
13 OUT TCCR0A,R20 Timer
31 Init.
EOR R16,R17
14 LDI R20,0x01 32 OUT PORTB,R16 ;toggle PB5
15 OUT TCCR0B,R20 ;Normal, no scaler 33 LDI R16,-32 ;timer value for 2 us
16 LDI R20,(1<<TOIE0) 34 OUT TCNT0,R16;load Timer0 with -32
17 STS TIMSK0,R20 ;enable Timer0 Ov. 35Timer Int. ;return from interrupt
RETI
18 SEI ;set I (enable Ints) enable
14
Timer0 Compare Match Interrupt
 using Timer0 and CTC mode generate a square wave on pin PORTB.5, while at the
same time data is being transferred from PORTC to PORTD.
.ORG 0x0 ;location for reset
JMP MAIN
.ORG 0x1C ;ISR location for Timer0 compare match A
JMP T0_CM_ISR
;main program
MAIN:
LDI R20,HIGH(RAMEND)
OUT SPH,R20
LDI R20,LOW(RAMEND) Time (µs)
OUT SPL,R20;set up stack
SBI DDRB,5;PB5 as an output ;--------------- Infinite loop
LDI R20,239 HERE:
OUT OCR0A,R20 ;load Timer0 with 239 IN R20,PINC ;read from PORTC
LDI R20,(1<<WGM01) OUT PORTD,R20 ;and send it to PORTD
OUT TCCR0A,R20 JMP HERE
LDI R20,0x01 ;--ISR for Timer0 (executed every 40 µs)
OUT TCCR0B,R20 ;start Timer0, CTC mode, no scaler T0_CM_ISR:
LDI R20,(1<<OCIE0A) IN R16,PORTB ;read PORTB
STS TIMSK0,R20 ;enable Timer0 compare match interrupt LDI R17,1<<5 ;00100000 for toggling PB5
SEI ;set I (enable interrupts globally) EOR R16,R17
LDI R20,0x00 OUT PORTB,R16 ;toggle PB5
OUT DDRC,R20 ;make PORTC input RETI ;return from interrupt
LDI R20,0xFF
OUT DDRD,R20 ;make PORTD output

15
Pin Change Interrupts

16
Pin Change Mask Registers
Bit D7 D0
PCMSK0: PCINT7 PCINT6 PCINT5 PCINT4 PCINT3 PCINT2 PCINT1 PCINT0 0x6B
(for PORTB)

PCMSK1: PCINT15 PCINT14 PCINT13 PCINT12 PCINT11 PCINT10 PCINT9 PCINT8 0x6C
(for PORTC)

PCMSK2: PCINT23 PCINT22 PCINT21 PCINT20 PCINT19 PCINT18 PCINT17 PCINT16 0x6D
(for PORTD)
28 pin
(PCINT14/RESET) PC6 1 28 PC5 (ADC5/SCL/PCINT13)
(PCINT16/RXD) PD0 2 27 PC4 (ADC4/SDA/PCINT12)
(PCINT17/TXD) PD1 3 26 PC3 (ADC3/PCINT11)
(PCINT18/INT0) PD2 4 MEGA328 25 PC2 (ADC2/PCINT10)
(PCINT19/OC2B/INT1) PD3 5 24 PC1 (ADC1/PCINT9)
(PCINT20/XCK/T0) PD4 6 23 PC0 (ADC0/PCINT8)
VCC 7 22 GND
GND 8 21 AREF
(PCINT6/XTAL1/TOSC1) PB6 9 20 AVCC
(PCINT7/XTAL2/TOSC2) PB7 10 19 PB5 (SCK/PCINT5)
(PCINT21/OC0B) PD5 11 18 PB4 (MISO/PCINT4)
(PCINT22/OC0A/AIN0) PD6 12 17 PB3 (MOSI/OC2A/PCINT3)
(PCINT23/AIN1) PD7 13 16 PB2 (SS/OC1B/PCINT2)
(PCINT0/CLKO/ICP1) PB0 14 15 PB1 (OC1A/PCINT1)

17
Pin Change Interrupt
PCINT (8n+m)
PCIEn
IC Pin
Q D Q PCMSKn.m PCINTn

…..
Interrupt
LE clk
SREG.I Request
clk
Change detector

Bit D7 D0
PCICR: - - - - - PCIE2 PCIE1 PCIE0 0x68

PCIE0: Pin Change Interrupt Enable bit for PORTB


PCIE1: Pin Change Interrupt Enable bit for PORTC (0: disabled, 1: enabled)
PCIE2: Pin Change Interrupt Enable bit for PORTD (0: disabled, 1: enabled)

Bit D7 D0
PCMSK0: PCINT7 PCINT6 PCINT5 PCINT4 PCINT3 PCINT2 PCINT1 PCINT0 0x6B
(for PORTB)

PCMSK1: PCINT15 PCINT14 PCINT13 PCINT12 PCINT11 PCINT10 PCINT9 PCINT8 0x6C
(for PORTC)

PCMSK2: PCINT23 PCINT22 PCINT21 PCINT20 PCINT19 PCINT18 PCINT17 PCINT16 0x6D
(for PORTD)

18
Pin Change Int. Sample Code
 The PB0, PB2, and PB3 pins are connected ATmega328 Buzzer

to switches. Write a program that makes PB3 (PCINT3)


PB5

PORTB.5 high whenever any of the PB2 (PCINT2)


PB1 (PCINT1)
switches changes state. PB0 (PCINT0)

1 .ORG 0 ;location for reset 16 ;enable PORTB change interrupt


2 JMP MAIN 17 LDI R20,(1<<PCIE0)
3 .ORG 0x06 ;loc. for PCINT0 18 STS PCICR,R20
4 JMP PCINT0_ISR 19 SEI
5 MAIN: LDI R20,HIGH(RAMEND) 20 HERE: JMP HERE
6 OUT SPH,R20 21
7 LDI R20,LOW(RAMEND) 22 PCINT0_ISR:
8 OUT SPL,R20 23 SBI PORTB,5
9 SBI DDRB,5 24 RETI
10 CBI PORTB,5 25
11 ;enable pull-up resistors 26
12 OUT PORTB,R20 27
13 ;enable PB0, PB2, and PB3 PCINTs 28
14 LDI R20,0b00001101 29
15 STS PCMSK0,R20 30

19
Interrupt priority
Interrupt Address (hex)
Reset 0000
External Interrupt Request 0 0002 Highest
External Interrupt Request 1 0004 priority
Pin Change Interrupt Request 0 0006
Pin Change Interrupt Request 1 0008
Pin Change Interrupt Request 2 000A
Watchdog Time-out Interrupt 000C
Timer/Counter2 Compare Match A 000E
Timer/Counter2 Compare Match B 0010
Timer/Counter2 Overflow 0012
Timer/Counter1 Capture Event 0014
Timer/Counter1 Compare Match A 0016
Timer/Counter1 Compare Match B 0018
Timer/Counter1 Overflow 001A
Timer/Counter0 Compare Match A 001C
Timer/Counter0 Compare Match B 001E
Timer/Counter0 Overflow 0020
SPI Serial Transfer Complete 0022
USART Rx Complete 0024
USART Data Register Empty 0026 Lowest
USART Tx Complete 0028 priority
ADC Conversion Complete 002A
EEPROM ready 002C
Analog Comparator 002E 20
Interrupt inside an interrupt
 The I flag is cleared when the AVR begins
to execute an ISR. So, interrupts are
disabled.
 The I flag is set when RETI is executed.

21
Task switching and resource conflict
 Does the following program work?

1 .ORG 0x0 ;location for reset 18 SEI


2 JMP MAIN 19 LDI R20,0xFF
3 .ORG 0x1C ;Timer0 compare match 20 OUT DDRC,R20
4 JMP T0_CM_ISR 21 OUT DDRD,R20
5 ;---------main program------------------------------ 22 HERE: OUT PORTC,R20
6 MAIN: LDI R20,HIGH(RAMEND) 23 INC R20
7 OUT SPH,R20 24 JMP HERE
8 LDI R20,LOW(RAMEND) 25 ;--------------------------ISR for Timer0
9 OUT SPL,R20 ;set up stack 26 T0_CM_ISR:
10 LDI R20,159 27 IN R20,PIND
11 OUT OCR0A,R20 28 INC R20
12 LDI R20,(1<<WGM01) 29 OUT PORTD,R20
13 OUT TCCR0A,R20 30 RETI
14 LDI R20,0x01
15 OUT TCCR0B,R20
16 LDI R20,(1<<OCIE0A)
17 STS TIMSK0,R20

22
Solution 1: different registers
 Use different registers for different tasks.

1 .ORG 0x0 ;location for reset 18 SEI


2 JMP MAIN 19 LDI R20,0xFF
3 .ORG 0x1C ;Timer0 compare match 20 OUT DDRC,R20
4 JMP T0_CM_ISR 21 OUT DDRD,R20
5 ;---------main program------------------------------ 22
6 MAIN: LDI R20,HIGH(RAMEND) 23 LDI R20, 0
7 OUT SPH,R20 24 HERE: OUT PORTC,R20
8 LDI R20,LOW(RAMEND) 25 INC R20
9 OUT SPL,R20 ;set up stack 26 JMP HERE
10 LDI R20,159 27 ;--------------------------ISR for Timer0
11 OUT OCR0A,R20 28 T0_CM_ISR:
12 LDI R20,(1<<WGM01) 29 IN R21,PIND
13 OUT TCCR0A,R20 30 INC R21
14 LDI R20,0x01 31 OUT PORTD,R21
15 OUT TCCR0B,R20 32 RETI
16 LDI R20,(1<<OCIE0A)
17 STS TIMSK0,R20

23
Solution 2: Context saving
 Save the contents of registers on the stack before
execution of each task, and reload the registers at the
end of the task.
1 .ORG 0x0 ;location for reset 18 SEI
2 JMP MAIN 19 LDI R20,0xFF
3 .ORG 0x1C ;Timer0 compare match 20 OUT DDRC,R20
4 JMP T0_CM_ISR 21 OUT DDRD,R20
5 ;---------main program------------------------------ 22 LDI R20, 0
6 MAIN: LDI R20,HIGH(RAMEND) 23 HERE: OUT PORTC,R20
7 OUT SPH,R20 24 INC R20
8 LDI R20,LOW(RAMEND) 25 JMP HERE
9 OUT SPL,R20 ;set up stack 26 ;--------------------------ISR for Timer0
10 LDI R20,159 27 T0_CM_ISR:
11 OUT OCR0A,R20 28 PUSH R20 ;save R20
12 LDI R20,(1<<WGM01) 29 IN R20,PIND
13 OUT TCCR0A,R20 30 INC R20
14 LDI R20,0x01 31 OUT PORTD,R20
15 OUT TCCR0B,R20 32 POP R20 ;restore R20
16 LDI R20,(1<<OCIE0A) 33 RETI
17 STS TIMSK0,R20 34

24
Solution 3: Context saving using software stack
 Make a stack for yourself and use it to save the contents of registers.

1 .ORG 0x0 ;location for reset 19 LDI R20,(1<<OCIE0A)


2 JMP MAIN 20 STS TIMSK0,R20
3 .ORG 0x1C ;Timer0 compare match 21 SEI
4 JMP T0_CM_ISR 22 LDI R20,0xFF
5 ;---------main program------------------------------ 23 OUT DDRC,R20
6 MAIN: LDI R20,HIGH(RAMEND) 24 OUT DDRD,R20
7 OUT SPH,R20 25 LDI R20, 0
8 LDI R20,LOW(RAMEND) 26 HERE: OUT PORTC,R20
9 OUT SPL,R20 ;set up stack 27 INC R20
10 LDI YH, HIGH($100) 28 JMP HERE
11 LDI YL, LOW($100) 29 ;--------------------------ISR for Timer0
12 30 T0_CM_ISR:
13 LDI R20,159 31 ST Y+,R20 ;save R20
14 OUT OCR0A,R20 32 IN R20,PIND
15 LDI R20,(1<<WGM01) 33 INC R20
16 OUT TCCR0A,R20 34 OUT PORTD,R20
17 LDI R20,0x01 35 LD R20, -Y ;restore R20
18 OUT TCCR0B,R20 36 RETI

25
Saving SREG
 We should save SREG, when we change
flags in the ISR.

PUSH R20
IN R20,SREG
PUSH R20
...
POP R20
OUT SREG,R20
POP R20

26
C programming
 Using Timer0 generate a square wave on pin PORTB.5,Vector
Interrupt while at the
Name
same time transferring data External
from PORTC to PORTD.
Interrupt Request 0 INT0_vect
External Interrupt Request 1 INT1_vect
#include "avr/io.h"
Pin Change Interrupt Request 0 PCINT0_vect
#include "avr/interrupt.h"
Pin Change Interrupt Request 1 PCINT1_vect
int main ()
{ Pin Change Interrupt Request 2 PCINT2_vect
DDRB |= (1<<5); //DDRB.5 = output
Watchdog Time-out Interrupt WDT_vect
TCNT0 = -32; //timerTimer/Counter2
value for Compare
2 µs Match A TIMER2_COMPA_vect
TCCR0A = 0x00; Timer/Counter2 Compare Match B TIMER2_COMPB_vect
TCCR0B = 0x01; //Normal mode,
Timer/Counter2 Overflowint clk, TIMER2_OVF_vect
no prescaler
TIMSK0 = (1<<TOIE0); //enable
sei ( ); Timer0
//set overflow
I interrupt
Timer/Counter1 Capture Event TIMER1_CAPT_vect
sei (); //enable
cli ( ); interrupts
//clear I
Timer/Counter1 Compare Match A TIMER1_COMPA_vect
DDRC = 0x00; //make PORTC input
Timer/Counter1 Compare Match B TIMER1_COMPB_vect
DDRD = 0xFF; //make PORTD output
while (1) //wait Timer/Counter1
here Overflow TIMER1_OVF_vect
PORTD = PINC; Timer/Counter0 Compare Match A TIMER0_COMPA_vect
} Timer/Counter0 Compare Match B TIMER0_COMPB_vect
ISR (TIMER0_OVF_vect) //ISR for Timer0 overflow
Timer/Counter0 Overflow TIMER0_OVF_vect
{ SPI Serial Transfer Complete SPI_STC_vect
TCNT0 = -32;
USART Rx Complete USART_RX_vect
PORTB ^= 0x20; //toggle PORTB.5
USART Data Register Empty USART_UDRE_vect
}
USART Tx Complete USART_TX_vect 27
C programming Example 2
 Using Timer1 and CTC mode write a program that toggles pin
PORTB.5 every second, while at the same time transferring data
from PORTC to PORTD. Assume XTAL = 16 MHz.
#include <avr/io.h>
#include <avr/interrupt.h>
int main () {
DDRB |= (1<<5); //make DDRB.5 output

OCR1A = 15624;
TCCR1A = 0x00; //CTC mode, internal clk, prescaler=1024
TCCR1B = 0x0D;
TIMSK1 = (1<<OCIE1A); //enable Timer1 compare match A int.
sei (); //enable interrupts

DDRC = 0x00; //make PORTC input


DDRD = 0xFF; //make PORTD output
while (1) //wait here
PORTD = PINC;
}
ISR (TIMER1_COMPA_vect) { //ISR for Timer1 compare match A
PORTB ^= (1<<5); //toggle PORTB.5
}
28
C programming Example 3
 Assume that the INT0 pin is connected to a switch that is normally
high. Write a program that toggles PORTB.5, whenever INT0 pin
goes low.
#include <avr/io.h>
#include <avr/interrupt.h>
int main ()
{
DDRB = 1<<5; //PB5 as an output
PORTD = 1<<2; //pull-up activated
EICRA = 0x2; //make INT0 falling edge triggered

EIMSK = (1<<INT0); //enable external interrupt 0


sei (); //enable interrupts

while (1); //wait here


}

ISR (INT0_vect) //ISR for external interrupt 0


{
PORTB ^= (1<<5); //toggle PORTB.5
}

29

You might also like