3 Generating Two PWM Signals in One Ramp Mode
Use case description: The TCD will be initialized and configured to run in One Ramp mode, have the OSCHF as input clock running at 24 MHz, and generate two PWM signals – WOA on the PA4 pin, and WOB on the PA5 pin. The PWM signal on WOA will have a 25% duty cycle and the signal on WOB will have a 30% duty cycle.
Result: The TCD will generate one PWM signal with a 25% duty cycle on WOA (PA4 pin) and one PWM signal with a 30% duty cycle on WOB.
The TCD can be configured to run in One Ramp mode, where the counter’s value
increments until it reaches the CMPBCLR value. Then, the TCD cycle is completed and the
counter restarts from 0x000
, beginning a new TCD cycle. The TCD cycle
period is:
In this configuration example, nonoverlapping outputs will be generated, so the case where CMPASET < CMPACLR < CMPBSET < CMPBCLR will be used.
Configuring the Main Clock
There are four clock sources for the TCD:
- OSCHF
- PLL
- EXTCLK
- CLK_PER
In this example of the TCD configuration, the OSCHF clock source will be the input to CLK_MAIN and the TCD. The following configurations must be made to have the CPU and the TCD run at 24 MHz, having OSCHF as input clock.
In the example code available in Appendix,
the main clock initialization will be done in the CLK_Init()
function.
Setting the Default Clock Source to OSCHF (Optional)
This can be done by using Atmel Studio and following the steps below:
a. Click Tools → Device Programming.
b. Select the attached development board and click Apply.
c. Select the Fuses tab from the left-hand side and select 1-24
MHz internal oscillator OSCHF for OSCCFG.CLKSEL, and then click
Program.
Changing the clock source to OSCHF and the configuration for running at 24 MHz are described in the following three steps:
- Set OSCHF as clock source for the
main clock.
Figure 3-2. CLKCTRL.MCLKCTRLA Register Configuration The Main Clock Control A register is protected by the Configuration Change Protection (CCP) mechanism, requiring a timed-write procedure for changing the register content. To write to the CCP-protected registers, the following API must be used:
_PROTECTED_WRITE(register, value);
OSCHF must be selected, which means that the CLKSEL bit field must be set to value0x0
. This translates into the following code:_PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL_CLKSEL_OSCHF_gc);
- Wait for the clock switch process
to complete.
Figure 3-3. CLKCTRL.MCLKSTATUS Register The clock switching process is indicated by the SOSC bit. The program must halt during an undergoing switch of the clock source, so a wait until the switch is over will be implemented.
while (CLKCTRL.MCLKSTATUS & CLKCTRL_SOSC_bm) { ; }
- Set the OSCHF to run at 24
MHz.
Figure 3-4. CLKCTRL.OSCHFCTRLA Register Configuration The default Reset value of the FRQSEL bit field in the OSCHFCTRLA register is
0x3
, which means that the default frequency value is 4 MHz. To obtain the 24 MHz desired frequency, the content of the FRQSEL bit field must be changed to0x9
. This bit field uses the CCP mechanism, so a protected write must be performed. The following code will select 24 MHz output for OSCHF:_PROTECTED_WRITE(CLKCTRL.OSCHFCTRLA, CLKCTRL_FREQSEL_24M_gc);
Configuring PA4 and PA5 Pins as Output
The PA4 and PA5 pins must be configured as output pins for the WOA and WOB PWM signals. The following code snippet sets the PA4 and PA5 pins as output low.
PORTA.DIRSET |= PIN4_bm | PIN5_bm; PORTA.OUTSET |= PIN4_bm | PIN5_bm;
In the example code available in Appendix,
the pins initialization will be done in the PORT_Init()
function.
Configuring the TCD Input Clock and Operation Mode
- TCD0.CTRLA
- TCD0.CTRLB
- TCD0.CMPASET
- TCD0.CMPACLR
- TCD0.CMPBSET
- TCD0.CMPBCLR
In the example code available in Appendix,
the TCD initialization will be done in the TCD_Init()
function.
- Select the Waveform Generation
mode and configure the TCD.
Figure 3-5. TCD0.CTRLB Register Configuration To use TCD0 in One Ramp mode, the WGMODE bit field in the TCD0.CTRLB register must be set to
0x0
. The following code snippet configures TCD0 in One Ramp mode:TCD0.CTRLB |= TCD_WGMODE_ONERAMP_gc;
In One Ramp mode, the TCD0.CMPASET and TCD0.CMPACLR registers are used for setting the ‘Dead time A’ and ‘On time A’ for the WOA signal; in addition, the TCD0.CMPBSET and TCD0.CMPBCLR registers are used for setting ‘Dead time B’ and ‘On time B’ for the WOB signal.
As the TCD0 counter continuously increases and overflows, setting CMPASET < CMPACLR < CMPBSET < CMPBCLR will result in nonoverlapping outputs during the on time.
Since the TCD is a 12-bit timer/counter, it ranges from 0 to 4095 (4096 steps), corresponding to
0x000
to0xFFF
. For a 25% PWM duty cycle, WOA must have an on time of 1024 clock cycles (defined below by theON_TIME_CYCLES_WOA
macro), corresponding to0x400
in hexadecimal format:This means that the difference between the value of TCD0.CMPACLR and TCD0.CMPASET must be 1024. For the purpose of this use case exemplification, the start of the on time for WOA will be 1023 (defined below by the
ON_TIME_START_WOA
macro).For a 30% PWM duty cycle, WOB must have an on time of 1228 clock cycles (defined below by the
ON_TIME_CYCLES_WOB
macro), corresponding to0x508
in hexadecimal format:This means the difference between the value of TCD0.CMPBCLR and TCD0.CMPBSET must be 1288. For the purpose of this use case exemplification, the start of the on time for WOB will be 2457 (defined below by the
ON_TIME_START_WOB
macro).The following code snippet initializes TCD0.CMPASET, TCD0.CMPACLR, TCD0.CMPBSET, and TCD0.CMPBCLR with the corresponding values for generating the PWM signals with 25% and 30% duty cycles.
#define ON_TIME_START_WOA 0x3FF #define ON_TIME_CYCLES_WOA 0x400 #define ON_TIME_START_WOB 0x999 #define ON_TIME_CYCLES_WOB 0x508 TCD0.CMPASET = ON_TIME_START_WOA; TCD0.CMPACLR = ON_TIME_START_WOA + ON_TIME_CYCLES_WOA; TCD0.CMPBSET = ON_TIME_START_WOB; TCD0.CMPBCLR = ON_TIME_START_WOB + ON_TIME_CYCLES_WOB;
- Enable the waveform channels as
output.
Figure 3-6. TCD0.FAULTCTRL Register Configuration For generating the PWM signals, the two output channels, WOA and WOB, must be enabled. Additionally, to exemplify this use case, the Default state of the two waveform outputs will be high. Since the TCD0.FAULTCTRL register is under Configuration Change Protection, the CMPAEN, CMPBEN, CMPB and CMPA bits must be written using the
_PROTECTED_WRITE
API.The following code snippet enables the output channels and sets the waveform output to high:
_PROTECTED_WRITE(TCD0.FAULTCTRL, TCD_CMPAEN_bm | TCD_CMPA_bm | TCD_CMPBEN_bm | TCD_CMPB_bm);
- Check if the TCD is ready for
enabling.
Figure 3-7. TCD0.STATUS Register To enable the TCD, first, it must be checked if it is ready. The following code snippet implements a wait until the TCD is ready to be enabled:
while (!(TCD0.STATUS & TCD_ENRDY_bm)) { ; }
- Select the input clock source and
enable the TCD.
Figure 3-8. TCD0.CTRLA Register Configuration The following code snippet will select OSCHF for the input frequency and will enable the TCD:
TCD0.CTRLA |= TCD_CLKSEL_OSCHF_gc | TCD_ENABLE_bm;
Tip: The full code example is also available in Appendix.