0% found this document useful (0 votes)
10 views48 pages

Lecture 11 Interrupts

Intro to micro electronics lecture slides

Uploaded by

serget1
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views48 pages

Lecture 11 Interrupts

Intro to micro electronics lecture slides

Uploaded by

serget1
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 48

The University of Texas at Arlington

Lecture 11
Interrupts

CSE 3442/5442
Embedded Systems 1
Based heavily on slides by Dr. Gergely Záruba and Dr. Roger Walker
External PIC Influence

• We don’t always just want data transfer from pin


connections (input or output)
– Regardless of the data’s value, the same actions are
performed
• Instead we can have the values on pin
connections influence or control which segments
of code/functions are used
– Based off input, we can handle things in a different
particular manner
• An Interrupt uses hardware to cause special
software execution 2
Polling vs. Interrupts
• Polling
– Continuously monitor the status of a device, bit, or pin
– When the condition is met, perform the service
– Wastes the PIC’s time and resources
• Only “looking” at a single location
– Can get stuck (infinite loop) if condition is never met
– Could miss other important input data or events

while(1)
{
if(PORTBbits.RB0 == 1)
break;
}
//or
while(PORTBbits.RB0 == 0); 3
Polling vs. Interrupts
• Interrupts
– Whenever a device (pin, peripheral) needs the PIC’s
service, it notifies by sending an interrupt signal
• Asynchronous (can happen at any time)
– When that signal is detected…
• PIC stops (pauses) its current actions
• Handles (serves) the source of the interrupt
• Returns exactly where the PIC left off (resumes)
– Doesn’t bog-down the PIC’s resources
– Can serve many devices (multiple interrupt sources)
• Each can get the PIC’s attention at any time
– Can assign priorities to each interrupt
• “Interrupt an interrupt”
– Can also ignore (mask) interrupt sources at any time
4
– When sleeping, they can wake up the microcontroller
Interrupt Handling
Main Program Main Program
(No Interrupts) (With Interrupts) (serves) Interrupt
Service
MOVLW 0x30 MOVLW 0x30 Routine
ADDLW 0x1F Interrupt ADDLW 0x1F Interrupt Inst 1
Occurs
Instruction 3 Instruction 3 Interrupt Inst 2
(pause)
Instruction 4 Interrupt Inst 3

Instruction 5 Instruction 4
return
Main
Instruction 6 Instruction 5
Program
Instruction 7 Continues Instruction 6
(resumes)
Instruction 8 Instruction 7
5
Instruction 8
Basic Example

• When PORTB pin B0 is brought HIGH (1)


– Go to function  Input_Detected()

6
Basic Example
(No Interrupts)
void main() void main()
{ {
int a, b, c = 0; int a, b, c = 0;
while(1) while(1)
{ //main program { //main program
… …

if(PORTBbits.B0 == 1) while(PORTBbits.B0 == 0);


Input_Detected(); OR //wait here until B0 is 1
Input_Detected();
//main program continues
… //main program continues
… …
} }
} }
void Input_Detected() void Input_Detected()
{ {
printf(“Pin B0 is 1!!!\n”); printf(“Pin B0 is 1!!!\n”);
return; return;
7
} }
Basic Example
(With an Interrupt)
void main()
{
int a, b, c = 0; • Can now detect B0 change at ANY POINT IN TIME
//set up and enable Interrupts • Interrupts are detected “in the background”
• Essentially: Hardware-controlled function calling
while(1)
{ //main program

… void interrupt ISR_HIGH()
{
//main program continues //Interrupt detected on pin B0
… …
… …
} Input_Detected();
} …
void Input_Detected() …
{ return;
printf(“Pin B0 is 1!!!\n”); }
return;
8
}
Interrupt Service Routines
• Where to “jump” when an interrupt is triggered?
– Need a sub-routine to handle interrupts
• Interrupt Service Routines (ISR) serve that purpose
• The ISRs have a fixed location in Program ROM
– If multiple ISRs, the group of locations is the interrupt vector table
• PIC18 only has three locations to handle interrupts but we
only have control of two of them for “normal” interrupts
– Program ROM: 0x0008 – HIGH Priority
– Program ROM: 0x0018 – LOW Priority

9
As there is limited space at these
addresses it is a good idea to place
a GOTO instruction at the interrupt
vector jumping to a remote location

10
As there is limited space at these
addresses it is a good idea to place
a GOTO instruction at the interrupt
vector jumping to a remote location
ORG 0000H
GOTO MAIN

ORG 0008H
GOTO HP_ISR

ORG 0018H
GOTO LP_ISR

ORG 50H
HP_ISR …

ORG 150H
LP_ISR …

ORG 250H 11
MAIN …
As there is limited space at these
addresses it is a good idea to place
a GOTO instruction at the interrupt
vector jumping to a remote location 50H
ORG 0000H HP_ISR
GOTO MAIN 150H
LP_ISR
ORG 0008H 250H
GOTO HP_ISR MAIN

ORG 0018H
GOTO LP_ISR

ORG 50H
HP_ISR …

ORG 150H
LP_ISR …

ORG 250H 12
MAIN …
What Happens When an Interrupt Hits?

1. The current instruction’s execution is finished and


the next instruction’s address is pushed to the stack
– Interrupts are disabled for HP (GIE or GIEH or GIEL cleared)

2. The PC is loaded with the interrupt vector


– Jump to the ISR

3. The instructions in the ISR are executed until a


RETFIE instruction
– Return From Interrupt Exit

4. RETFIE will cause the microcontroller to pop the


PC from the stack and resume normal operations
– Interrupts are re-enabled (GIE or GIEH or GIEL set) 13
Sources of Interrupts

1. Timers
2. Hardware Interrupts (external pins, INT)
– PORTB: RB0, RB1, and RB2
3. Serial Communication
– Receive and Transmit
4. PORTB-Change
5. ADC
6. CCP/PWM
14
Simplified View of Interrupts

• We can easily think of an interrupt as two digital signals:


1. Enable bit can allow/disallow the actual interrupt from
happening (Enabled = Unmasked, Disabled = Masked)
2. Flag bit is set if interrupt should be invoked (something
happened)

15
Simplified View of Interrupts

• We can easily think of an interrupt as two digital signals:


1. Enable bit can allow/disallow the actual interrupt from
happening (Enabled = Unmasked, Disabled = Masked)
2. Flag bit is set if interrupt should be invoked (something
happened)
• To make things confusing, some peripherals can be masked
in a group by a PEIE mask

16
Masking Interrupts

• By default, all interrupts are masked (disabled)


– The PIC will not respond to any interrupts
• Up to the user to enable them if they are needed
• Enabling/disabling interrupts is done through
designated registers in the SFR:
– INTCON, INTCON2, INTCON3
– RCON
– PIR1, PIR2
– PIE1, PIE2
– IPR1, IPR2
• All interrupts can be masked by clearing the GIE
(Global Interrupt Enable) bit in INTCON (default) 17
Enabling Interrupts

1. Allow the specific interrupt to occur


– INTCONbits.TMR0IE = 1 (timer 0 can interrupt)
– INTCON3bits.INT1IE = 1 (INT 1 can interrupt)
– PIE1bits.ADIE = 1 (ADC can interrupt)
– …
2. If specific interrupt falls into Peripheral
category, must also enable another bit
– INTCONbits.PEIE = 1
3. Allow any interrupt to occur
– INTCONbits.GIE = 1 18
Two Levels of Priorities
RCONbits.IPEN
• The PIC18 has two levels of interrupts: HIGH and LOW
• By default (when reset) all interrupts are high priority (00008H)
• In RCON we can enable the two-level priority option

• Then we can assign low or high priority to interrupts by


setting/clearing an interrupt priority bit in the IPRx SFRs
• This means there really are three bits controlling each interrupt
– The INT0 (RB0) hardware interrupt can only be of high priority
• Most importantly: When handling a low priority interrupt,
high priority interrupts can steal the processor away 19
Logical View of High Priority Interrupts

20
Logical View of
All Interrupts

21
Logical View of
All Interrupts
1

22
What Happens to Other
Important Registers?
• What happens to other important registers (WREG,
Status, BSR) that may be impacted by an interrupt
– especially as they should be found the same way as they
were left when returning
• The solution lies in the ISR having to save these
registers at the beginning and restoring at the end
• High-Priority
– PIC18 automatically stores them in shadow registers
– To restore registers use RETFIE 1
• Low-Priority
– Programmer must store them manually 23
What Happens to Other Important
Registers? – Fast Context Switching
• There is a one-deep shadow register set for WREG,
Status, and BSR (similar to CALL and RETURN)

When jumping to
High-Priority ISR

When
returning
from High-
Priority ISR

24
Shadow Registers
Main Program
(With Interrupts)

MOVLW 0x30 ISR


ADDLW 0x1F Interrupt Inst 1

Instruction 3 Interrupt Inst 2

Interrupt Inst 3

Instruction 4
RETFIE 1
Instruction 5

Instruction 6

Instruction 7
25
Instruction 8
Shadow Registers
Main Program
(With Interrupts)

MOVLW 0x30 ISR


ADDLW 0x1F Interrupt Inst 1

Instruction 3 Interrupt Inst 2

Interrupt Inst 3

Instruction 4
RETFIE 1
Instruction 5

Instruction 6

Instruction 7
26
Instruction 8
Shadow Registers
Main Program
(With Interrupts)

MOVLW 0x30 ISR


ADDLW 0x1F Interrupt Inst 1

Instruction 3 Interrupt Inst 2

Interrupt Inst 3

Instruction 4
RETFIE 1
Instruction 5

Instruction 6

Instruction 7
27
Instruction 8
External INT Interrupts
• INT0, INT1, and INT2 are all interrupts assigned to
digital I/O pins
– To use them the corresponding TRISB bits have to be set
• INT interrupts are edge triggered (not level), thus a
change must happen on the pins to trigger an interrupt
• Whether rising (default) or falling edge triggers the
interrupt is software (INTCON2.INTEDGx bits) selectable
• When triggered (like many other flags) the ISR should
explicitly clear the INTxIF flag
• INT0 is always of high priority, the other two can be set

28
External PORTB Interrupts

• Changes on RB4:RB7 can also cause interrupts but


are on the group of the bits not individual
– Leaves B3 as the only PORTB pin without interrupt capability
• Interrupt priority can be set HIGH or LOW
• When handling interrupt, PORTB should be read and
INTCON.RBIF should be cleared
• Great for…
– keyboard interfacing
– grouped input
– parallel input
29
INTCON

30
INTCON2

31
INTCON3

32
PIR1

33
PIR2

34
PIE1

35
PIE2

36
IPR1

37
IPR2

38
RCON

39
Interrupt Programming from Assembly

• Really just a quasi-tedious job of setting the right bits in the


right registers and “org”-ing the code at the right place
ORG 0000H
GOTO MAIN
ORG 200H
HP_ISR BTFSS INTCON, INT0IF
ORG 0008H
GOTO HP_ISR RETFIE 1
BTG PORTB, 7
ORG 00018H
BCF INTCON, INT0IF
GOTO LP_ISR
RETFIE 1


BSF INTCON, INT0IE
BCF INTCON2, INTEDG0 40
BSF INTCON, GIE
Interrupt Programming from C

• We need to define functions that are for high priority


and low priority ISRs
• We need to make sure that our ISRs are in the right
place
• We do not need to worry about context-switching,
the C compiler is going to make sure our registers are
properly handled and variables that need saving are
saved
• Interrupt handlers should start off with an “if” or a
“switch-case” complex to identify the source of the
interrupt
41
Defining ISRs in C18

• Defining functions that are for high priority


and low priority ISRs:
– At the beginning of the program, have a
prototype of all functions (including ISRs)

– Use #pragma interrupt function_name and


#pragma interruptlow function_name to tell
C18 compiler that a function is an interrupt
function (so it can use proper RETFIE returns
and fast context switching)
42
Placing ISRs in C18

• Make sure that our ISRs are in the right place


• At the beginning of the code insert goto
instructions to the interrupt vectors
• Use ASM to limit size and ensure it fits in ROM

#pragma code My_Hi_Priority_Int = 0x0008


void My_Hi_Priority_Int(void)
{
_asm
GOTO chk_isr
_endasm
}
43
Interrupt Handling in C18
#include <P18F452.h> void main()
{
void My_ISR_High(void); //main control code
void My_ISR_Low(void); //and Interrupt Settings
...
#pragma code My_Hi_Priority_Int = 0x0008 }
void My_Hi_Priority_Int(void)
{ //other functions
_asm ...
GOTO My_ISR_High
_endasm
} #pragma interrupt My_ISR_High
void My_ISR_High(void)
#pragma code My_Lo_Priority_Int = 0x00018 {
void My_Lo_Priority_Int(void) //interrupt handling for HIGH
{ ...
_asm }
GOTO My_ISR_Low
_endasm #pragma interruptlow My_ISR_Low
} void My_ISR_Low(void)
{
//interrupt handling for LOW
... 44
}
Placing ISRs in XC8

• Much simpler in XC8 compiler


• Only need to know two keywords
– “interrupt” and “low_priority”

• High-Priority
void interrupt My_ISR_High(void)
{
//interrupt handling for HP
}

• Low-Priority
void interrupt low_priority My_ISR_Low(void)
{
//interrupt handling for LP
45
}
Interrupt Handling in XC8

#include <P18F452.h> void interrupt My_ISR_High(void)


{
void My_ISR_High(void); //interrupt handling for HIGH
void My_ISR_Low(void); if(INT0IF == 1 && INT0IE == 1)
//INT0 interrupt tripped
void main() if(TMR0IF == 1 && TMR0IE == 1)
{ //Timer 0 interrupt tripped
//main control code ...
//and Interrupt Settings }
...
}
void interrupt low_priority My_ISR_Low(void)
//other functions {
... //interrupt handling for LOW
if(ADIF == 1 && ADIE == 1)
//ADC conversion done
if(INT1IF == 1 && INT1IE == 1)
//placing of interrupt code at the //INT1 interrupt tripped
correct locations is automatically if(RCIF == 1 && RCIE == 1)
handled by the XC8 compiler //Serial reception occurred
...
} 46
ADC Interrupt Example
#include <P18F452.h>
void My_ISR_High(void);

void main() void interrupt My_ISR_High(void)


{ {
ADCON1 = 0b11001110; //ADC settings //interrupt handling for HIGH
ADCON0 = 0b10000001; if(INT0IF == 1 && INT0IE == 1)
PIR1bits.ADIF = 0; //Clear ADIF flag bit //INT0 interrupt tripped
IPR1bits.ADIP = 1; //ADC is HIGH Priority if(ADIF == 1 && ADIE == 1)
PIE1bits.ADIE = 1; //Set ADIE enable bit {
INTCONbits.PEIE = 1; //Set PEIE enable bit //ADC conversion done
INTCONbits.GIE = 1; //Set GIE enable bit //Get result from ADRESH/L
PIR1bits.ADIF = 0; //clear flag
while(1) }
{ }
ADCON0bits.GO = 1; //Start ADC
...// go on with other code
...
}
}

47
Summary
• Interrupts are a great way to handle peripheral attention or
external happenings
• Some of the most used interrupts are timers (later),
external hardware, serial communications, and ADC ready
• All interrupts in the PIC18 can be masked in a group or
individually
• We can have two levels of priorities, with an almost fully
configurable what interrupt belong to what level
relationship
• Programming ISRs from C requires knowledge of how the
compiler is told about ISRs
– Consult the compiler’s user guide for specifics

48

You might also like