Professional Documents
Culture Documents
ISR(TIMER0_OVF_vect, ISR_NAKED) {
// do something each time timer 0 overflows
reti();
}
Handling interrupts (cont'd)
● The ISR macro takes attributes to specify
its behaviour
– ISR_BLOCK: run with interrupts disabled
– ISR_NONBLOCK: don't disable interrupts
● (nested interrupts needs more careful
analysis)
ISR(some_vect, ISR_BLOCK) {
// do something
// NB! No reti(). That is done in the epilogue
// inserted by the macro.
}
External interrupts
● PCINT
– generates an interrupt when a pin changes
– available on all pins
– three sets of pins (controlled by PCICR)
● many pins can trigger the same interrupt
● may be handy for the two encoder signals
– pins masked by PCMSKn (n = [0,2])
● INT0, INT1
– pin change, edge or level trigged
– controlled by EICRA
– masked by EIMSK
Example, PCINT for pin 24
● Consult data sheet
● pin 24 → PCINT9
● PCICR: PCINT14..8 → PCIE1
● Find the bit in PCMSK1
volatile int counter;
ISR(PCINT1_vect) {
// count positive edges
if(PINC & (1<<PINC1)) counter++;
}
void setup_interrupt(){
PCICR = (1<<PCIE1);
PCMSK1 = (1<<PCINT9);
sei();
}
Timers
● A counter, clocked from the system clock
or externally
● Prescaler (clk/8, clk/64, … clk/1024)
● Gives two (three) types of interrupts
– overflow
● when the conter wraps
– output compare
● when the counter reaches a set value
● more programmable, two compare values
● also used for waveform generation
– (input capture)
Timer usage
● Required configuration
– set prescaler for desired frequency range
– set mode of operation
– enable any interrupts
● PWM mode(s)
– usually better to use the built-in PWM
modes if possible. (typically fast PWM)
● CTC mode
– Clear Timer on Compare match
– allows more fine-grained control over
interrupt frequency
Fast PWM mode
● Single slope counting
● OCRnx controls duty cycle
● OCRnx is double buffered
Fast PWM: Setting period time
● TOP can be fixed, or set using OCRnA
(or ICR1)
Tips...
● Avoid using many interrupts concurrently
– prototype by polling, then switch to ISR.
● Usually a good idea to turn off interrupts
in ISRs (e.g., ISR_BLOCK)
– to avoid data races
– running out of stack space
● Try to keep ISRs very short
– if possible, do just store data or set a flag
and do actual processing elsewhere
● Shared data must be volatile and global
Tips... (cont'd)
● Check if interrupt flags are reset by the
hardware of if you need to do it in code
● If not, nonblocking ISRs will get called
over and over.
– UART interrupts
– level triggered external interrupts