MEAM.Design - ATmega32 Programming - Timers/Counters - Timer 1 Configuration Details


Timer 1 is a 16-bit free-running timer with three independent output compare units, a single input capture unit, and extensive PWM support. The output compare pins are OC1A, OC1B, and OC1C, which are multiplexed to B5, B6, and B7, while the input capture pin is IPC1, which is multiplexed to D4.

Important Registers

TCNT1H + TCNT1L   timer/counter 1 value (high + low byte)
TCCR1A   timer/counter 1 control register A
TCCR1B   timer/counter 1 control register B
OCR1AH + OCR1AL   timer/counter 1 output compare register A (high + low byte)
OCR1BH + OCR1BL   timer/counter 1 output compare register B (high + low byte)
OCR1CH + OCR1CL   timer/counter 1 output compare register C (high + low byte)
ICR1H + ICR1L   timer/counter 1 input capture register (high + low byte)
TIFR1   timer/counter 1 interrupt flags



Clock Source - The default clock source for Timer 1 is the system clock. You can set the prescaler by modifying CS10, CS11, and CS12 in TCCR1B:

TCCR1B:
CS12
TCCR1B:
CS11
TCCR1B:
CS10
0 0 0  OFF
0 0 1  /1
0 1 0  /8
0 1 1  /64
1 0 0  /256
1 0 1  /1024



Timer Modes (Waveform Generation) - The timer can operate in one of sixteen modes, the most useful of which are listed here. The operation is controlled by setting WGM10, WGM11, WGM12, and WGM13 bits spread across TCCR1A and TCCR1B. The mode controls how the timer will count (either UP or UP/DOWN), what the maximum value will be, and whether to drive the output compare pin(s). Once the maximum value is reached, the timer will either reset to 0x00 and continue counting (UP modes), or will reverse direction (UP/DOWN modes).

TCCR1B:
WGM13
TCCR1B:
WGM12
TCCR1A:
WGM11
TCCR1A:
WGM10
Normal: Timer UP to a value, reset to 0x0000:
0 0 0 0  (mode 0) UP to 0xFFFF (16-bit)
0 1 0 0  (mode 4) UP to OCR1A
1 1 0 0  (mode 12) UP to ICR1
Single-Slope: Timer UP to a value, reset to 0x0000 (set/reset PWM):
0 1 0 1  (mode 5) UP to 0x00FF (8-bit), PWM mode
0 1 1 1  (mode 7) UP to 0x03FF (10-bit), PWM mode
1 1 1 1  (mode 15) UP to OCR1A, PWM mode
1 1 1 0  (mode 14) UP to ICR1, PWM mode
Dual-Slope: Timer UP to a value, DOWN to 0x0000 (set/reset PWM):
0 0 0 1  (mode 1) UP to 0x00FF, DOWN to 0x0000, PWM mode
0 0 1 1  (mode 3) UP to 0x03FF, DOWN to 0x0000, PWM mode
1 0 1 1  (mode 11) UP to OCR1A, DOWN to 0x0000, PWM mode
1 0 1 0  (mode 10) UP to ICR1, DOWN to 0x0000, PWM mode



Channel A Compare Output (OC1A) Options - OC1A is multiplexed onto B5, which means that you must first set bit 5 of DDRB to enable output. The behavior of the OC1A output is then controlled in the TCCR1A register and is subject to one of the following:

When operating in modes 0 or 12, a match between TCNT1 and OCR1A will yield the following:

TCCR1A:
COM1A1
TCCR1A:
COM1A0
0 0   no change
0 1   toggle
1 0   clear
1 1   set


When operating in modes 5, 7, or 14, a match between TCNT1 and OCR1A will yield the following:

TCCR1A:
COM1A1
TCCR1A:
COM1A0
0 0   no change
1 0   clear at OCR1A, set at rollover
1 1   set at OCR1A, clear at rollover


When operating in modes 1, 3, or 10, a match between TCNT1 and OCR1A will yield the following:

TCCR1A:
COM1A1
TCCR1A:
COM1A0
0 0   no change
1 0   clear at OCR1A during UP, set at OCR1A during DOWN
1 1   set at OCR1A during UP, clear at OCR1A during DOWN



Channel B Compare Output (OC1B) Options - OC1B is multiplexed onto B6, which means that you must first set bit 6 of DDRB to enable output. The behavior of the OC1B output is then controlled in the TCCR1A register and is subject to one of the following:

When operating in mode 0, 4, or 12, a match between TCNT1 and OCR1B will yield the following:

TCCR1A:
COM1B1
TCCR1A:
COM1B0
0 0   no change
0 1   toggle
1 0   clear
1 1   set

When operating in modes 5, 7, 14, or 15, a match between TCNT1 and OCR1B will yield the following:

TCCR1A:
COM1B1
TCCR1A:
COM1B0
0 0   no change
1 0   clear at OCR1B, set at rollover
1 1   set at OCR1B, clear at rollover

When operating in modes 1, 3, 10, or 11, a match between TCNT1 and OCR1B will yield the following:

TCCR1A:
COM1B1
TCCR1A:
COM1B0
0 0   no change
1 0   clear at OCR1B during UP, set at OCR1B during DOWN
1 1   set at OCR1B during UP, clear at OCR1B during DOWN



Channel C Compare Output (OC1C) Options - OC1C is multiplexed onto B7, which means that you must first set bit 7 of DDRB to enable output. The behavior of the OC1C output is then controlled in the TCCR1A register and is subject to one of the following:

When operating in mode 0, 4, or 12, a match between TCNT1 and OCR1C will yield the following:

TCCR1A:
COM1C1
TCCR1A:
COM1C0
0 0   no change
0 1   toggle
1 0   clear
1 1   set

When operating in modes 5, 7, 14, or 15, a match between TCNT1 and OCR1C will yield the following:

TCCR1A:
COM1C1
TCCR1A:
COM1C0
0 0   no change
1 0   clear at OCR1C, set at rollover
1 1   set at OCR1C, clear at rollover

When operating in modes 1, 3, 10, or 11, a match between TCNT1 and OCR1C will yield the following:

TCCR1A:
COM1C1
TCCR1A:
COM1C0
0 0   no change
1 0   clear at OCR1C during UP, set at OCR1C during DOWN
1 1   set at OCR1C during UP, clear at OCR1C during DOWN



Input Capture - When not in use as the TOP value for the timer, the input capture feature allows you to store the timer value into the ICR1 register at the instant when the ICP1 pin changes value. ICP1 is multiplexed with D4, so you must clear bit 4 of DDRD to make this an input. You can select whether to capture rising or falling edges by setting the ICES1 bit in the TCCR1B register:

TCCR1B:
ICES1
0   store timer value on falling edge (default)
1   store timer value on rising edge



Flags - There are five flags within the TIFR1 register that can be used to monitor Timer 1:

TIFR1 : OCF1A   set when TCNT1 matches OCR1A
TIFR1 : OCF1B   set when TCNT1 matches OCR1B
TIFR1 : OCF1C   set when TCNT1 matches OCR1C
TIFR1 : ICF1   set whenever an input capture event takes place
TIFR1 : TOV1   set whenever TCNT1 returns to 0x0000

These can be cleared by writing a logic 1 to the register bit (e.g.: set(TIFR1,TOV1) to clear the overflow flag)



Interrupts

There are five interrupt vectors associated with Timer 1:

To call an interrupt whenever Timer 1 overflows (returns to 0x0000), set the TIMSK1 : TOIE1 bit, and write a handler for the TIMER1_OVF interrupt vector.

To call an interrupt whenever (TCNT1 matches OCR1A), set the TIMSK1 : OCIE1A bit, and write a handler for the TIMER1_COMPA interrupt vector.

To call an interrupt whenever (TCNT1 matches OCR1B), set the TIMSK1 : OCIE1B bit, and write a handler for the TIMER1_COMPB interrupt vector.

To call an interrupt whenever (TCNT1 matches OCR1C), set the TIMSK1 : OCIE1C bit, and write a handler for the TIMER1_COMPC interrupt vector.

To call an interrupt whenever an input capture event occurs, set the TIMSK1 : ICIE1 bit, and write a handler for the TIMER1_CAPT interrupt vector.

And do not forget to enable global interrupts, as discussed here.

Note that entering any of these interrupts will automatically clear the coresponding TIFR1 flag.



(A note on working with 16-bit concatenated registers: While the C compiler will handle all access issues for you, if you want to write code in assembly, you must write to the high byte first, then the low byte, and when reading, you must read the low byte first, then the high byte.)