Timer/Counter 1 Control Register A (TCCR1A)
7 6 5 4 3 2 1 0
COM1A1 COM1A0 COM1B1 COM1B0 FOC1A FOC1B WGM11 WGM10
Specify Waveform Generation Mode used with
WGM13, WGM12
WGM13 ... WGM10 = 0000 for normal mode.
1 to force output compare on channel B
1 to force output compare on channel A
Output compare mode for channel B
Output compare mode for channel A
Timer/Counter 1 Control Register B (TCCR1B)
7 6 5 4 3 2 1 0
ICNC1 ICES1 - WGM13 WGM12 CS12 CS11 CS10
clock select (next slide)
Specify Waveform Generation Mode used with
WGM13, WGM12
WGM13 ... WGM10 = 0000 for normal mode.
input capture edge select: 1 will select rising edge,
0 will select falling edge
1 to activate input capture noise canceller
Clock select
CS12 CS11 CS10 Description
0 0 0 No clock source (timer stopped)
0 0 1 CLKI/O/1 (no prescaling)
0 1 0 CLKI/O/8 (from prescaler)
0 1 1 CLKI/O/64 (from prescaler)
1 0 0 CLKI/O/256 (from prescaler)
1 0 1 CLKI/O/1024 (from prescaler)
1 1 0 External clock source on T1 pin, clock on falling edge
1 1 1 External clock source on T1 pin, clock on rising edge
▪ For ATmega16, the default internal clock is CLKI/O = 1MHz
▪ Timer 1 can use the internal or external clock
▪ If using the internal clock, we can set Timer 1 to run 8, 64, 256, or 1024 times slower than the
internal clock
Timer/Counter Interrupt Mask Register (TIMSK)
7 6 5 4 3 2 1 0
OCIE2 TOIE2 TICIE1 OCIE1A OCIE1B TOIE1 OCIE0 TOIE0
For Timer 0
Timer 1 Overflow Interrupt Enable
Timer 1 Output Compare B Match Interrupt Enable: 1 to enable
Timer 1 Output Compare A Match Interrupt Enable: 1 to enable
Timer 1 Input Capture Interrupt Enable: 1 to enable
For Timer 2
Timer/Counter Interrupt Flag Register (TIFR)
7 6 5 4 3 2 1 0
OCF2 TOV2 ICF1 OCF1A OCF1B TOV1 OCF0 TOV0
For Timer 0
Timer 1 Overflow Interrupt Flag: set to 1 when overflow
Timer 1 Output Compare B Match Flag: set to 1 when match
Timer 1 Output Compare A Match Flag: set to 1 when match
Timer 1 Input Capture Flag: set to 1 when capture event occurs
For Timer 2
▪ This register has flags that indicate when a timer interrupt occurs
▪ It is not often used in ATmega16 programs
Example: Creating an accurate delay
Write a C program for ATmega16 to toggle PORTB every 2 seconds. It should use Timer 1
overflow interrupt to create delays of 2 seconds each.
▪ Analysis
❑ Internal system clock: 1MHz
❑ With no pre-scaler, Timer 1 increments every 1 μs
❑ Timer 1 is 16-bit counter, so it will overflow every 216 μs
❑ For a 2s delay, we need Timer 1 to overflow for 2s/216 μs = ~31 times
▪ Implementation
❑ Write code to enable Timer 1 overflow interrupt
❑ Use ISR to count the number of overflows
❑ When the number of overflows is 31, invert port B
Example: Creating an accurate delay
#include <avr/io.h>
#include <avr/interrupt.h> 1
volatile int overflow_count; // declare a global variable
ISR(TIMER1_OVF_vect) { // ISR for Timer1 overflow interrupt
overflow_count++; // increment overflow count
if (overflow_count >= 31) { // when 2s has passed
overflow_count = 0; // start new count 2
PORTB = ~PORTB; // invert port B
}
}
int main(void) {
DDRB = 0xFF; // set port B for output
PORTB = 0x00; // initial value of PORTB
overflow_count = 0; // initialize overflow count
TCNT1 = 0x00; // initial value of counter register
TCCR1A = 0b00000000; // normal mode 4
TCCR1B = 0b00000001; // no pre-scaler, internal clock
TIMSK = 0b00000100; // enable Timer 1 overflow interrupt 3
sei(); // enable interrupt subsystem globally 5
while (1){;} // infinite loop
return 0;
}