Skip to main content
Library homepage
Engineering LibreTexts

28.1: Introduction

  • Page ID
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)\(\newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    Virtually all microcontrollers contain one or more hardware timer/counter function blocks. These can be used for a variety of functions including generating time delays, counting input events, generating simple pulse or PWM waveforms, and triggering software interrupts. In general, there are multiple ways to configure these blocks. Often, they are set up as simple up counters that are clocked by the system clock. In some instances they may be run asynchronously from an external clock source.

    The ATmega 328P contains three of these blocks: two eight bit units named TC0 and TC2 (Timer Counter 0 and 2), and one 16 bit unit, TC1. A functional block diagram of an eight bit unit is shown in Figure \(\PageIndex{1}\). The 16 bit unit is similar but offers extended abilities.

    Timer/counter functional block diagram (eight bit).
    Figure \(\PageIndex{1}\): Timer/counter functional block diagram (eight bit).

    First, there are a couple of registers used to program the operation of the block. These are TCCRnA and TCCRnB (Timer Counter Control Registers A and B) where n is the timer/counter number (0, 1 or 2 here, although other microcontrollers in the series may have more). These bits are usually “set and forget”, that is, they are set/cleared for a given use and not touched again unless the unit needs to be reprogrammed for a different use. More detail on these will be presented momentarily. There are also two registers that are used with software interrupts, TIFRn and TIMSKn (Timer Interrupt Flag Register and Timer Interrupt MaSK register) that aren’t shown here. We will examine these in the section on software interrupts. The other key registers are TCNTx (Timer CouNT) along with OCRnA and OCRnB (Output Compare Registers A and B).

    In its most basic operation the unit increments the TCNTn register with each tick of the system clock. Eventually, this register will reach its maximum value and overflow, resulting in zero, effectively resetting the register and the count continues up from there. This maximum value is 255 for an eight bit unit (i.e., 11111111 binary) and 65535 for a 16 bit unit. Optionally, the unit may be programmed to inspect the values contained in the OCRn registers and compare them to the current contents of TCNTn to see if they match. Both the overflow and the compare match can be used trigger some action, e.g., a waveform level change or software interrupt. The compare match section feeds a pulse waveform generator that in turn feeds an output pin. This section is shown in Figure \(\PageIndex{2}\).

    Timer/counter compare match output circuitry.
    Figure \(\PageIndex{2}\): Timer/counter compare match output circuitry.

    The box marked “OCnx Pin” is a physical pin on the microcontroller. As it would be impractical to have single purpose pins for every function in the microcontroller, the waveform function is mapped onto the general purpose IO pins. Compare this section to the GPIO block diagram discussed in chapter 19. Note the PORT and DDR flip-flops in particular. The waveform generator feeds a flip flop which then feeds a multiplexer along with the PORT flip flop. This signal is then fed to a tri-state buffer controlled by the DDR which leads to the physical output pin. As there are three timer/counters and each has two compare match registers, there are a total of six physical output pins available for waveform generation. The mapping assignments are shown in Table \(\PageIndex{1}\).

    Table \(\PageIndex{1}\): Waveform pin assignments.
    OCnx PORT.bit Arduino Pin
    OC0A D.6 6
    OC0B D.5 5
    OC1A B.1 9
    OC1B B.2 10
    OC2A B.3 11
    OC2B D.3 3

    The following discussion will focus on timer/counter number two. This is because timer/counter units zero and one are already used for common Arduino system calls such as delay(). Reprogramming the timer/counters could alter the operation of those functions and procedures. Timer/counter number two is a little safer to experiment with in that regard although be aware that all three units are used to cover the six PWM capable output pins on the Uno (i.e., via analogWrite()).

    The two control registers (TCCRnA/B) indicate the mode of operation. The registers are shown in Tables \(\PageIndex{2}\) and \(\PageIndex{3}\) for unit number two. The control registers for the other timer/counter units are similar and details may be found in the Appendix.

    Table \(\PageIndex{2}\): TCCR2A register (Atmel 2014).
    Bit 7 6 5 4 3 2 1 0
    Function COM2A1 COM2A0 COM2B1 COM2B0 - - WGM21 WGM20
    Table \(\PageIndex{3}\): TCCR2B register (Atmel 2014).
    Bit 7 6 5 4 3 2 1 0
    Function FOC2A FOC2B - - WGM22 CS22 CS21 CS20

    The first items of interest are the CS bits. These are the Clock preScale bits and they allow for longer timer periods by dividing down the system clock before it feeds the counter. For example, if the controller is running at 16 MHz then each clock tick represents 1/16 MHz or 62.5 nanoseconds. Counting up from 0 to 255 would yield a maximum delay of only 62.5 nanoseconds times 256, or 16 microseconds. If the prescaler is set to eight, each tick is stretched by a factor of eight yielding a maximum delay of 128 microseconds in this example. The prescaler settings for TC2 are shown in Table \(\PageIndex{4}\).

    Table \(\PageIndex{4}\): Prescaler settings for TC2.
    CS22 CS21 CS20 Divide By
    0 0 0 TC Stopped
    0 0 1 1 (no prescale)
    0 1 0 8
    0 1 1 32
    1 0 0 64
    1 0 1 128
    1 1 0 256
    1 1 1 1024

    Turning to the Waveform Generation Mode (WGM) bits, there are normal mode, a compare mode (CTC or Clear Timer on Compare) and two forms of pulse width modulation. We will examine Normal and Fast PWM modes here and CTC mode in the chapter covering interrupts. Note that the WGM bits are spread across both control registers rather than residing in a single register. The WGM bits are detailed in Table \(\PageIndex{5}\).

    Table \(\PageIndex{5}\): Waveform generation mode bits for TC2.
    WGM22 WGM21 WGM20 Mode
    0 0 0 Normal
    0 0 1 Phase Correct PWM, Top=0xff
    0 1 0 CTC
    0 1 1 Fast PWM, Top=0xff
    1 0 0 Reserved
    1 0 1 Phase Correct PWM, Top=OCRA
    1 1 0 Reserved
    1 1 1 Fast PWM, Top=OCRA

    Finally let’s consider the Compare Output Mode (COM) bits found in TCCR2A. There are two bits for OC2A and two for OC2B, and although the settings are similar they are not identical (for details, see the Atmel documentation). The settings for OC2A are found in Tables \(\PageIndex{6}\) through \(\PageIndex{8}\) for three waveform generation modes and describe how the output pin signal responds. Note that in all three of these modes if both COM bits are clear then the output pin, OC2A, is disconnected from the timer/counter and operates in ordinary IO form. With other settings of the COM bits, OC2A is controlled by the waveform generator. It is important to note that the associated DDR must still be set for output mode in order for the waveform to reach the output pin. Examine the block diagram of Figure \(\PageIndex{2}\) for verification.

    Table \(\PageIndex{6}\): Non-PWM, Compare Output Mode for TC2.
    COM2A1 COM2A0 Description
    0 0 Normal, OC2A disconnected
    0 1 Toggle OC2A on Compare Match
    1 0 Clear OC2A on Compare Match
    1 1 Set OC2A on Compare Match
    Table \(\PageIndex{7}\): Fast PWM, Compare Output Mode for TC2.
    COM2A1 COM2A0 Description
    0 0 Normal, OC2A disconnected
    0 1 WGM22=0: Normal, OC2A disconnected
    WGM22=1: Toggle OC2A on Compare Match
    (Reserved operation for OC2B)
    1 0 Clear OC2A on Compare Match, Set OC2A on 0x00 (non-inverting mode)
    1 1 Set OC2A on Compare Match, Clear OC2A on 0x00 (inverting mode)
    Table \(\PageIndex{8}\): Phase Correct PWM, Compare Output Mode for TC2.
    COM2A1 COM2A0 Description
    0 0 Normal, OC2A disconnected
    0 1 WGM22=0: Normal, OC2A disconnected
    WGM22=1: Toggle OC2A on Compare Match
    (Reserved operation for OC2B)
    1 0 Clear OC2A on Compare Match when up-counting, Set when down-counting
    1 1 Set OC2A on Compare Match when up-counting, Set when down-counting

    This page titled 28.1: Introduction is shared under a CC BY-NC-SA 4.0 license and was authored, remixed, and/or curated by James M. Fiore via source content that was edited to the style and standards of the LibreTexts platform; a detailed edit history is available upon request.