2.1 Bare Metal Implementation

  1. The CLKCTRL peripheral must be configured for using the high-resolution feature of the TCE0. The following registers settings are required:
    Figure 2-3. MCLKCTRLA Register
    Figure 2-4. MCLKCTRLB Register
    Figure 2-5. PLLCTRLA Register
  2. The TCE corresponding register in Port Multiplexer can be set to route the module outputs to different ports. In this case, Port A is chosen, which is also the default port.
    PORTMUX.TCEROUTEA = 0x0;
    Figure 2-6. TCE PORTMUX Register
  3. The CTRLB register contains the Enable bits of the compare channels and the bit field determining the Waveform Generation mode. In this example, channels 0, 1, 2 and 3 are used with Dual-Slope PWM mode.
    TCE0.CTRLB |= (TCE_CMP0EN_bm | TCE_CMP1EN_bm | TCE_CMP2EN_bm | TCE_CMP3EN_bm);
    TCE0.CTRLB |= TCE_WGMODE_DSBOTH_gc;
    Figure 2-7. CTRLB Register
  4. Set the DIR bit of the CTRLECLR register to ‘1’ to set the timer to count clock ticks down (decrementing). The default value of the DIR bit is ‘0’.
    TCE0.CTRLECLR = TCE_DIR_bm;
    Figure 2-8. CTRLECLR Register
  5. Enable the Scaling mode amplitude and offset register usage, and set the scaling method to the bottom. The duty cycle values are scaled from 0% duty cycle up to 100% duty cycle. Instead of writing the absolute value to the Compare registers, it is possible to write this as a fractional value between 0 and 2.

    When writing a fractional value to the compare or compare buffer registers, first, the values are multiplied by the amplitude and then the offset is added. The high-resolution feature can increase the PWM’s resolution four times, with two extra bits, or eight times, with three. This feature is helpful at very low frequencies. The high-resolution feature shortens the clock period steps by four or eight times. For example, for a clock with a frequency of 20 MHz with high resolution set to off, one clock period is 50 ns (T[s] = 1/f[Hz] = 1/20,000,000). For this clock with high-resolution 4X, one clock period is 12.5 ns. This clock has, with a high resolution of 8X, one clock period is 6.25 ns.

    TCE0.CTRLD = TCE_HREN_4X_gc | TCE_SCALE_bm | TCE_AMPEN_bm | TCE_SCALEMODE_BOTTOM_gc;
    The formulas for scaling the values written in the Compare registers are explained below:

    EQ3.1:

    S c a l e d C M P = C M P f r a c × A M P + O F F S E T

    Scaled value using the Center Scale mode.

    EQ3.2:

    S c a l e d C M P = C M P f r a c × A M P

    Scaled value using the Bottom Scale mode.

    EQ3.3:

    S c a l e d C M P = C M P f r a c × A M P + O F F S E T

    Scaled value using the Top Scale mode.

    EQ3.4

    S c a l e d C M P = C M P f r a c × A M P

    Scaled value using the Top-Bottom Scale mode.

    The CMPfrac uses four different values mentioned in the AVR16EB16/20/28/32 AVR® EB Family Data Sheet, Table 23-6. Effective Compare Value in Scaled Mode.

    Figure 2-9. CTRLD Register
  6. PER is the buffer of the Period register. It is used to set the frequency of the PWM signal using EQ3.5:
    f D S P W M ( H z ) = N × f C L K ( H z ) 2 × T C E p r e s c a l e r × T C E p e r i o d
    N c a n h a v e t h e v a l u e s 1 , 4 o r 8 , d e p e n d i n g o n t h e r e s o l u t i o n f e a t u r e
    I f N = 1 , t h e h i g h r e s o l u t i o n f e a t u r e i s t u r n e d o f f
    I f N = 4 , t h e r e s o l u t i o n i s i n c r e a s e d b y 4
    I f N = 8 , t h e r e s o l u t i o n i s i n c r e a s e d b y 8

    In this example, the resolution is increased by four. Thus, the value written in the PER register is calculated using EQ3.6:

    T C E p e r i o d = 4 × f C L K ( H z ) 2 × T C E p r e s c a l e r × f D S P W M ( H z ) = 4 × 20000000 2 × 1 × 10000 4000 = 0 x F A 0
    TCE0.PER  = 0xFA0;
  7. The compare registers are used to set the duty cycle. The values in the Compare registers are 20%, 40%, 60% and 80% of the one in the Period register because 20%, 40%, 60% and 80% duty cycles are desired. When using the buffer registers to write fractional values inside the compare registers, these values will be overridden at run time. These values can be set to 0 during initialization to highlight the difference between writing values ranging from 0 to PER and writing fractional values in the CMP registers. For example, the value written in CMP0 for 20% duty cycle PWM without Scaling mode is 0x320 for the given PER of 0xFA0, equivalent to 10 kHz frequency or 100 μs period, and high-resolution 4X. The value written in CMP0 for 20% duty cycle PWM, with Scaling mode enabled, is 0x1999 - the duty is calculated in hardware using the value of PER, AMPLITUDE and OFFSET registers.
    TCE0.CMP0 = 0x320;
    TCE0.CMP1 = 0x640;
    TCE0.CMP2 = 0x960;
    TCE0.CMP3 = 0xC80;
  8. Set the amplitude by writing a desired value to the AMP register.
    TCE0.AMP = 0x8000;
  9. Set the offset by writing a desired value to the OFFSET register.
    TCE0.OFFSET = 0x00;
  10. Set the prescaler to 1 by changing the CLKSEL bit field in the CTRLA register. To start the counter, the user must set the Enable bit in the same register.
    TCE0.CTRLA = TCE_CLKSEL_DIV1_gc;
    TCE0.CTRLA |= TCE_ENABLE_bm;
    Figure 2-10. CTRLA Register
  11. Then, the Port A Pins 0-3 (PA0-3) are set as output by writing a ‘1’ to the corresponding bit in the Direction register of the port.
    PORTA.DIRSET = PIN0_bm | PIN1_bm | PIN2_bm | PIN3_bm;
  12. Add another pin as output to toggle it when a change in amplitude and compare values is happening. This way, the user will observe the changes. The pin toggles during run time.
    PORTD.DIRSET = PIN5_bm;
  13. To see the duty cycles scaling, the user must change the value of the Amplitude register during the run time. After writing a new value in the Amplitude register, the user must write the old values in the Compare registers. This because the duty cycle scaling update only happens when a new value is written in the Compare registers.