Ryan Robucci
Mostly derived from Atmel Datasheet
One your your primary end-goals is to understand the "Register Description" at the end of each section of the data sheet
For example:
In addition to part datasheets, many times you'll want to look for "App Notes"/
Application note describing many use cases for timers, which modes to use, and what bits should be set. It is a bit friendlier read as compared to the data sheet: AVR1306: Using the XMEGA Timer/Counter App Note
http://ww1.microchip.com/downloads/en/Appnotes/doc8045.pdf
Example:
6.5 Event Counting
Task: Configure TCC0 to count the number of switch presses on PC0, using event
channel 0. Generate interrupt after 5 key presses that toggle PC1.
1. Configure PC0 as input, sense on falling edge.
2. Configure PC1 as output.
3. Select PC0 as multiplexer input for event channel 0.
4. Enable filtering on event channel 0.
5. Set the period of TCC0 to 4 (to generate overflow interrupt after 5 switch presses).
6. Enable TCC0 overflow interrupt at low level.
7. Select event channel 0 as clock source for the TC.
In the TCC0 overflow interrupt service routine, toggle PC1.
In this configuration, the CNT[H:L] register will contain the number of times a switch
connected to PC0 has been pressed. After 5 presses, an overflow interrupt service
handler will be triggered, toggling PC1 while CNT[H:L] wraps around to 0.
AVR timers has a few important modes of operation:
Signal | Comment |
---|---|
count | trigger Increment or decrement TCNT0 by 1. |
direction | Select between increment and decrement. |
clear | Clear TCNT0 (set all bits to zero). |
clkTn | Timer/Counter clock, referred to as clk T0 |
in the following. | |
top | Signalize that TCNT0 has reached maximum value...determined by 0xFF or |
match to compare register OCRn | |
bottom | Signalize that TCNT0 has reached minimum value (zero). |
(Writing a one to clear a flag is a common practice.)
To implement a software clock, you may select the external clock source on the T0 pin AND CONFIGURE THE PIN AS AN OUTPUT PIN.
Always count up
Non counter clear, just rollover from 0x00 to 0xFF
T/C overflow flag (TOV0) set the same cycle that TCNT0 becomes 0
Can treat TOV0 like 9th bit on first count run, but it is not cleared upon
second counter rollover (0x1FF -> 0x100)
Can use TOV0 with software to extend the count Either
By setting the configuration bits COM0A[1:0], a designated output pin can
be modified when the counter matches the value of the Output Compare
Register (OCR0A)
The normal mode is limited to count periods of 2N , where N is the number
counter bits. To create a variable count period, the CTC modes can be used.
Caution: if computing a new OCR0A value in software after the Compare Flag is set, if the value is too small and the software is too slow, the
counter will pass the value before it is set and the comparison event not happen on that cycle. The counter will count to 0xFF rolloever, and the
match will occur on the next count cycle and may result in an irregular waveform. This also why timers (TCNT0) should be set to 0 initially.
A frequency (with 50% duty cycle) waveform output in fast PWM mode can be achieved by set-ting OC0A to toggle its logical level on each compare match (COM0A1:0 = 1). The waveform generated will have a maximum frequency of fOC0 = fclk_I/O/2 when
OCR0A is set to zero. This feature is similar to the OC0A toggle in CTC mode, except the double buffer feature of the Out-put Compare unit is enabled in the fast PWM mode.
At the very start of period 2 in Figure 14-7 on page 99 OCn has a transition from high to low
even though there is no Compare Match. The point of this transition is to guarantee symmetry
around BOTTOM. There are two cases that give a transition without Compare Match.
Similar to 8 bit timers see documentation for details
Note all 16-bit reads and writes involve a high-byte buffer.
If using 8-bit access, Read Low Byte First and Write it last
If using 16-bit register names, C compiler take care of the order
They share the prescaler unit but have separate selection
Synchronizer -- minimizes chance of metastable states
(where input is captured around the time of a transition, violating setup/hold requirements
causing invalid operation)
Modes are similar to 8-bit T/C 0, but use dual-purpose register Input Capture Register / Count Top Register (ICR).
In PWM modes ,
In this final mode, updates to the OCR and top registers are
buffered and not propagated until the counter reaches the
bottom so that values are not changed in the middle of a pulse.
It is recommended to use the phase and frequency correct
mode instead of the phase correct mode when changing the
TOP value while the Timer/Counter is running. When using a
static
TOP value there are practically no differences between the two
modes of operation.
TCNT1, OCR1A/B, and ICR1 are 16-bit registers
When the low byte of a 16-bit register is written by the CPU, the high byte stored in the temporary register,
and the low byte written are both copied into the 16-bit register in the same clock cycle.
When the low byte of a 16-bit register is read by the CPU, the high byte of the 16-bit register is copied into
the temporary register in the same clock cycle as the low byte is read.
ASM
... ; Set TCNT1 to 0x01FF ldir17,0x01 ldir16,0xFF outTCNT1H,r17 outTCNT1L,r16 ; Read TCNT1 into r17:r16 in r16,TCNT1L in r17,TCNT1H ...
In C, the compiler takes care of the byte order
unsigned int i; ... /* Set TCNT1 to 0x01FF */ TCNT1 = 0x1FF; /* Read TCNT1 into i */ i = TCNT1; ...
But each access is still multiple clock cycles. To avoid interaction with other code accessing the
timer registers in the middle of the multi-bit write, atomic access should be implemented.
But each access is still multiple clock cycles. To avoid interaction with other code accessing the timer registers in the middle of the multi-bit write, atomic access should be implemented.
Atomic access (uninterrupted access) requires disabling interrupts.
ASM
TIM16_ReadTCNT1: ; Save global interrupt flag in r18,SREG ; Disable interrupts cli ; Read TCNT1 into r17:r16 in r16,TCNT1L in r17,TCNT1H ; Restore global interrupt flag outSREG,r18 ret
C
unsigned int TIM16_ReadTCNT1( void ) { unsigned char sreg; unsigned int i; /* Save global interrupt flag */ sreg = SREG; /* Disable interrupts */ __disable_interrupt(); /* Read TCNT1 into i */ i = TCNT1; /* Restore global interrupt flag */ SREG = sreg; return i; }
Atomic Write
ASM
TIM16_WriteTCNT1: ; Save global interrupt flag in r18,SREG ; Disable interrupts cli ; Set TCNT1 to r17:r16 outTCNT1H,r17 outTCNT1L,r16 ; Restore global interrupt flag outSREG,r18 ret
C
void TIM16_WriteTCNT1( unsigned int i ) { unsigned char sreg; unsigned int i; /* Save global interrupt flag */ sreg = SREG; /* Disable interrupts */ __disable_interrupt(); /* Set TCNT1 to i */ TCNT1 = i; /* Restore global interrupt flag */ SREG = sreg; }
As discussed, a capture unit and register (ISR) is provided to save the counter value
precisely at the time of some external event, the follow details are provided for your
reference.
15.6.1
Input Capture Trigger Source
The main trigger source for the Input Capture unit is the Input Capture pin (ICP1). Timer/Counter1 can alternatively use the Analog
Comparator output as trigger source for the Input Capture unit. The Analog Comparator is selected as trigger source by settin g the Analog
Comparator Input Capture (ACIC) bit in the Analog Comparator Control and Status Register (ACSR). Be aware that changing trigg er source
can trigger a capture. The Input Capture Flag must therefore be cleared after the change. Both the Input Capture pin (ICP1) a nd the Analog
Comparator output (ACO) inputs are sampled using the same technique as for the T1 pin (Figure 16-1 on page 135). The edge detector is
also identical. However, when the noise canceler is enabled, additional logic is inserted before the edge detector, which inc reases the delay
by four system clock cycles. Note that the input of the noise canceler and edge detector is always enabled unless the Timer/C ounter is set in
a Waveform Generation mode that uses ICR1 to define TOP. An Input Capture can be triggered by software by controlling the por t of the
ICP1 pin.
113
8018P–AVR–08/10 ATmega169P
The Timer/Counter Overflow Flag (TOV1) is set according to the mode of
operation selected by the WGM13:0 bits. TOV1 can be used for generating a
CPU interrupt.
15.6 Input Capture Unit
The Timer/Counter incorporates an Input Capture unit that can capture external
events and give them a time-stamp indicating time of occurrence. The external
signal indicating an event, or multiple events, can be applied via the ICP1 pin or
alternatively, via the analog-comparator unit. The
time-stamps can then be used to calculate frequency, duty-cycle, and other
features of the signal applied. Alternatively the time-stamps can be used for
creating a log of the events.
The Input Capture unit is illustrated by the block diagram shown in Figure 15-3.
The elements of the block diagram that are not directly a part of the Input
Capture unit are gray shaded. The small “n” in register and bit names indicates
the Timer/Counter number.
Figure 15-3. Input Capture Unit Block Diagram
When a change of the logic level (an event) occurs on the Input Capture pin
(ICP1), alternatively on the Analog Comparator output (ACO), and this change
confirms to the setting of the edge detector, a capture will be triggered. When a
capture is triggered, the 16-bit value of the counter (TCNT1) is written to the
Input Capture Register (ICR1). The Input Capture Flag (ICF1) is set at the same
system clock as the TCNT1 value is copied into ICR1 Register. If enabled
(ICIE1 = 1), the Input Capture Flag generates an Input Capture interrupt. The
ICF1 Flag is automatically cleared when the interrupt is executed. Alternatively
the ICF1 Flag can be cleared by software by writing a logical one to its I/O bit
location.
Reading the 16-bit value in the Input Capture Register (ICR1) is done by first
reading the low byte (ICR1L) and then the high byte (ICR1H). When the low
byte is read the high byte is copied into the high byte temporary register
(TEMP). When the CPU reads the ICR1H I/O location it will access the TEMP
Register.
The ICR1 Register can only be written when using a Waveform Generation
mode that utilizes the ICR1 Register for defining the counter’s TOP value. In
these cases the Waveform Genera-tion mode (WGM13:0) bits must be set before
the TOP value can be written to the ICR1 Register. When writing the ICR1
Register the high byte must be written to the ICR1H I/O location
before the low byte is written to ICR1L.
Only significant thing to note here is that T/C2 provides the option use an external 32kHz crystal, an accurate clock independent of the system clock. The following details are provided for reference.