2.1 Bare Metal Implementation
- The CLKCTRL peripheral must be configured for using the high-resolution feature of the TCE0. The following registers settings are required:
- 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;
- 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 a Dual-Slope
PWM
mode.
TCE0.CTRLB |= (TCE_CMP0EN_bm | TCE_CMP1EN_bm | TCE_CMP2EN_bm | TCE_CMP3EN_bm);
TCE0.CTRLB |= TCE_WGMODE_DSBOTH_gc;
- 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;
Enable the Scaling mode amplitude and offset register usage, and set scaling method to bottom. The values of the duty cycles 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, the values are first multiplied with the amplitude and then the offset is added. 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 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 with high resolution 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:
EQ3.2:
EQ3.3:
EQ3.4
The CMPfrac uses four different values that can be found in the AVR16EB16/20/28/32 AVR® EB Family Data Sheet, table 23-6.
Scaled value using the Top-Bottom Scale mode
- PER is the buffer of the Period
register. It is used to set the frequency of the PWM signal using EQ3.5:
TCE0.PER = 0xFA0;
- 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
0 in initialize to show the difference between writing values between 0 and PER and
writing fractional values in 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 of 10 kHz frequency or 100 μs period, and high resolution X4. The value
written in CMP0 for 20% duty cycle PWM with scaling mode 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;
- Set the amplitude by writing a
desired value to the AMP
register.
TCE0.AMP = 0x8000;
- Set the offset by writing a desired
value to the OFFSET
register.
TCE0.OFFSET = 0x00;
- 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;
- 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;
- 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;
- 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.