Lecture 5's Sequence: Review of C Programming
Lecture 5's Sequence: Review of C Programming
5.1 Introduction
Review of C Programming
▪ Overflow interrupt:
❑ triggered when timer reaches its top limit
❑ for measuring time that is longer than one timer cycle
❑ for finding the elapse time, creating a time delay, etc.
▪ Input capture:
❑ an interrupt is triggered when there’s a change in pin ICP1
❑ value of Timer 1 is automatically stored in register ICR1
❑ for finding period, frequency, pulse width of a signal
Output Compare
▪ In this lecture, we’ll study another important functionality of a timer: output compare
▪ Output compare allows custom processing to be done when the timer reaches a preset
target value
▪ Output compare pins: These dedicated pins can be automatically changed (set,
reset, toggled) when there is an output compare match
5.1 Introduction
▪ When a match occurs, we have a compare match event. Flag OCF1x is also set,
where x = ‘ ‘ A’ or ‘B’
Timer/Counter registers
ATmega16 chip
Output Compare Unit ─ Main aspects
▪ When a timer event (compare match, or timer = 0) occurs, pins OC1x can be automatically updated:
❑ inverted
❑ set to 1
❑ cleared to 0, or
❑ unchanged
▪ The type of update is controlled by two flags in register TCCR1A: {COM1x1, COM1x0} where x = ‘A’
or ‘B’
▪ The exact update change depends also on the operation mode of Timer 1
Operations modes of Timer 1
▪ Discussed in Lecture 3
CTC modes
COM1A1/ COM1A0/
COM1B1 COM1B0
Description
0 0 -
0 1 -
Used in the
example - Clear OC1A/OC1B on compare match
1 0 - Set OC1A/OC1B when timer = 0
below
1 1 -
Phase Correct PWM modes
▪ Timer counts up and down between 0 and TOP, where TOP is equal to
❑ 0xFF (for 8-bit mode, WGM = 1000)
❑ 0x1FF (for 9-bit mode, WGM = 0010)
❑ 0x3FF (for 10-bit mode, WGM = 0011)
❑ value in ICR1 (for WGM = 1010)
❑ value in OCR1A (for WGM = 1011)
COM1A1/ COM1A0/
Description
COM1B1 COM1B0
0 0 -
0 1 -
Used in the Clear OC1A/OC1B on compare match when up-counting
1 0
Example below Set OC1A/OC1B on compare match when down-counting
1 1 -
Steps for producing a custom waveform
Use Timer 1 to create a signal with period = 1000μs, high time = 200μs, Fcpu = 1MHz
Example 1: Determining registers
#include <avr/io.h>
int main(void) {
DDRD=0b00100000; // set port D for output (D.5 is OC1A)
// Set register TCCR1A
// WGM11:WGM10 = 10: with WGM13-WGM12 to select timer mode 1110
// Fast PWM, timer 1 runs from 0 to ICR1
// COM1A1:COM1A0 = 10: clear OC1A when compare match, set OC1A when 0
// compare match occurs when timer = OCR1A
TCCR1A = 0b10000010;
// Set register TCCR1B
// WGM13:WGM12 = 11
// CS12:CS0 = 001: internal clock 1MHz, no pre-scaler
TCCR1B = 0b00011001;
ICR1 = 1000; // period of output signal
OCR1A = 200; // pulse width of output signal
while(1){;}
return 0;
}
Example 1: Testing
7 6 5 4 3 2 1 0
OCIE2 TOIE2 TICIE1 OCIE1A OCIE1B TOIE1 OCIE0 TOIE0 TIMSK
For Timer 0
For Timer 2
Use Timer 1’s output compare interrupt to toggle pin B.1 every 1000μs.
Example 2: Programming
#include <avr/io.h>
#include <avr/interrupt.h>
ISR(TIMER1_COMPA_vect){
PORTB = PORTB ^ 0b00000010; // invert B.1 using XOR operator
}
int main(void) {
DDRB = 0xFF; // set port B for output
PORTB = 0xFF; // initial value of port B
// WGM11:WGM10 = 00: with WGM13-WGM12 to select timer mode 0100
// CTC, timer 1 runs from 0 to OCR1A
TCCR1A = 0b00000000;
// WGM13:WGM12 = 01
// CS12:CS0 = 101: internal clock 1MHz, pre-scaler = 1024
TCCR1B = 0b00001001;
OCR1A = 976; // interrupt is triggered every 976 x 1024 = 1,000,000us
TIMSK = (1<< OCIE1A); // enable Timer 1 Output Compare A interrupt
sei(); // enable interrupt subsystem
while(1){;}
return 0;
}