Meeting Timing Constraints
Certain tasks must be performed on time for correct operation
•
Sampling audio/video
•
anti-lock braking
•
avionics
Wait for time (I.e. sampling) or events (I.e. ABS)
May require an understanding of the HW/SW specifics
•
Clock frequency of microcontroller
•
Understand the assembly code
•
Understand the microcontroller architecture (I.e. pipelining)
Slides created by:
Professor Ian G. Harris
Busy-Wait Loops
Write a loop which just waits for fixed time, or for event
for (I=0; I<25000; I++);
while (!GODONE);
Wait loops waste processor resources
•
Doing nothing useful while waiting
•
This is not reasonable for complicated systems
Timing loops are sensitive to compiler and to HW parameters
•
What if clock frequency is changed?
•
What about compiler optimizations?
Slides created by:
Professor Ian G. Harris
Interrupts
An interrupt is an interesting event which can occur and needs to
be handled by a program
Interrupt service routine (ISR) is a function which is
automatically executed when an event occurs
•
Timer expires, input set to 1, ADC completes, etc.
Main program can continue to execute until the event occurs
•
No time is wasted waiting
Main program is not aware of the interrupt
•
Interrupt is invoked by the HW, not the main program
• Programmer does not need to worry about triggering the
interrupt
Slides created by:
Professor Ian G. Harris
Interrupt Sources
Interrupts can be triggered by many soruces
•
•
•
•
•
•
•
•
External Interrupt - RA2 assigned to 1
PORTChange Interrupt - A change on any PORTA pin
Timer0 Overflow - Timer 0 expires
A/D Converter - Conversion completes
Comparators - Comparators return 1
Oscillator fail - System oscillator no longer detected
EEPROM - EEPROM write operation completes
Timers 1 and 2 - Timers expire
Interrupts are grouped into primary and peripheral
Primary interrupt sources are External, PORTChange, and Timer0
Slides created by:
Professor Ian G. Harris
Interrupt Masks and Flags
Interrupts are often disabled so that uninteresting events can be
ignored
• Disable timer interrupt when the timer is not needed
• Disable external interrupt when RA2 is not used for interrupts
An interrupt is masked if it is disabled
Each interrupt source is associated with an enable bit and a flag
bit
Flag bit is set to 1 when the event occurs
Ex. When Timer0 overflows the Timer0 flag bit is automatically
set
Enable bit must be set by your code on order to have the interrupt
service routine (ISR) invoked when the interrupt event occurs
Ex. If Timer0 enable bit is set then ISR will start when Timer0
overflows
Slides created by:
Professor Ian G. Harris
Interrupt Registers
INTCON register contains enable bits and flag bits for the primary
interrupts
Bit
Name
Description
7
GIE
Global Interrupt Enable
6
PEIE
Peripheral Interrupt Enable
5
T0IE
TMR0 Overflow Interrupt Enable
4
INTE
RA2/INT External Interrupt Enable
3
RAIE
PORTChange Interrupt Enable
Peripheral interrupts are controlled by other registers
Slides created by:
Professor Ian G. Harris
More Interrupt Register Bits
INTCON register contains enable bits and flag bits for the primary
interrupts
Bit
Name
Description
2
T0IF
TMR0 Overflow Interrupt Flag
1
INTF
External Interrupt Flag
0
RAIF
PORTChange Interrupt Flag
Interrupt flags must be cleared in software (your C code)
Flags are set when condition occurs, regardless of enable
Slides created by:
Professor Ian G. Harris
Using Interrupts in C
1. Decide which interrupts you want to enable (timer,
external, etc.)
2. Clear interrupt flags by setting flag bits in the
INTCON register
3. Enable the interrupts by setting appropriate bits in the
INTCON register
4. Write code for your interrupt service routine
Slides created by:
Professor Ian G. Harris
Interrupt Example
Problem: Make LED1 blink, but when a button is pressed light LED2
immediately
Vcc
RA0
RA1
RA2
PIC
LED1
RA3
RA4
LED2
RA2 = 1 when button is pressed, 0 otherwise
Slides created by:
Professor Ian G. Harris
Code to Blink LED1
Some lines are omitted for simplicity (ANSEL, CMCON, #include)
int i;
main () {
TRISA = 0b000100; // RA2 is an input, all
// others are outputs
PORTA = 0; // All outputs are 0
while (1 == 1) {
for (i=0; i<25000; i++);
RA0 = RA0 ^ 1;
}
}
Slides created by:
Professor Ian G. Harris
Additions to Enable Interrupts
Interrupt must occur when RA2 is set to 1
Use the RA2/INT External Interrupt
Add the following code in the main, before the while loop
INTCON = 0; // Disable all interrupts, clear flags
GIE = 1; // Enable interrupts
INTE = 1; // Enable RA2/INAT interrupt
Slides created by:
Professor Ian G. Harris
Interrupt Service Routine
ISR is function called when ANY interrupt occurs
ISR must check the interrupt flag bits to see which interrupt occurred
Takes no arguments, returns no values
void interrupt button_int(void) {
int j;
if (INTF && INTE) {
INTF = 0;
RA3 = 1;
for (j=0; j<25000; j++);
RA3 = 0;
}
return;
}
Slides created by:
Professor Ian G. Harris
Impact of Interrupts
Interrupts allow high priority tasks to be serviced quickly
Interrupts make timing difficult to guarantee
- Can happen at any time, in the middle of a program
for(i=0; i<25000; i++);
This code is usually ~half second delay
Interrupts can occur in the middle of loop, making it longer
Interrupts can interrupt interrupts
- Should disable interrupts at appropriate times
Slides created by:
Professor Ian G. Harris
Using a Timer (TMR0)
TMR0 can be used as an interrupt source
TMR0 is an 8-bit up counter
T0IF (INTCON bit 2) is set when TMR0 overflows (FF to 00)
Need to relate the clock to real time
System Clock - Clock used to drive all operations
• 4MHz is the default value
Instruction Clock - Clock used to drive the counter
• 1/4 the system clock frequency (1MHz)
• Instruction clock period = 1us
Slides created by:
Professor Ian G. Harris
Timer Control
Three ways to control timer behavior:
1. Prescaler value - the number of instruction clocks required to
increment the timer
Ex. Prescaler = 1, timer increments after 1us
Prescaler = 4, timer increments after 4us
2. Initialization - Timer value can be initialized in your code
Ex. TMR0 = 22;
3. Clock Source - The internal (4MHz) clock can be used, or an
external clock
Slides created by:
Professor Ian G. Harris
OPTION Register
5
T0CS
TMR0 clock source
4
T0SE
TMR0 source edge select
3
PSA
Prescalar assignment bit
2:0
PS2:PS0 Prescalar rate select bits
T0CS - 1: RA2 pin, 0: Internal instruction clock
T0SE - 1: falling edge, 0: rising edge
PSA - 1: Watchdog timer (not TMR0), 0: TMR0
PS2:PS0 - Prescalar = 2 (PS2:PS0) + 1
Ex. PS2:PS0 = 001, Prescalar = 4
Slides created by:
Professor Ian G. Harris
Prescalar/Init. Examples
Example 1: Interrupt should be triggered after 30 us
Use internal clock - instruction clock period = 1us
Timer must overflow every 30 instruction clocks
Use no prescalar (PSA = 1;)
Initialize counter to 256 - 30 = 226 (TMR0 = 226;)
Example 2: Interrupt should be triggered after 1000us
Use internal clock with prescalar 4 in order to count to 1000
PSA = 0 (use prescalar) and PS2:PS0 = 011
Timer must overflow every 1000 instr. clocks, 250 with prescalar
Initialize counter to 256 - 250 = 6
Slides created by:
Professor Ian G. Harris
Timer Code Example
Interrupt after 30 us
TMR0 = 226; // Initialize timer value
T0IF = 0; // Clear existing interrupt flag
T0IE = 1; // Enable timer0 interrupt
GIE = 1; // Enable interrupts
OPTION = 0b 0 1 0 0 1 000
Prescalar value
T0CS = 0: Use internal clock
No prescalar
Slides created by:
Professor Ian G. Harris
© Copyright 2026 Paperzz