Changing Arduino Zero PWM Frequency

Hi Johnyrobot,

The timers TCC0 and TCC1 are being clocked by generic clock 4 (GCLK4) at 48MHz.

The formula for calculating the PWM frequency (in the SAMD21 datasheet) is:

PWM frequency = GCLK frequency / (N * (PER + 1))

where:
GCLK frequency => generic clock frequency fed to the timer, (in our case: 48MHz)
N => timer prescaler (in our case: 1)
PER => the value of the timer's period (PER) register

Rearranging the formula:

PER = GCLK frequency / (N * PWM frequency) - 1

therefore:

PER = 48000000 / (1 * 30000) - 1 = 1599

The timers count up from 0 up to 1599, before being reset back to 0, then from 0 to 1599 oncemore and so on. There's a single PER register for each timer.

The counter compare or CC registers determine the PWM waveform's duty-cycle. There is one CC register for each timer channel. Timer TCC0 has 4 channels: (0..3) and TCC1 has 2: (0..1).

The duty-cycle can be set between 0 (0%) and the value in the PER register (100%).

Therefore, for a 50% duty-cycle the CC register is simply set to half the PER register, in our case 1599/2 = 799.

By the way, if you want to change the duty-cycle or period during operation, then it's best to use the buffered PERB and CCBx registers. The buffered registers are loaded into their PER and CC counterparts only at the beginning of the timer cycle (know as an update), thereby preventing glitches from appearing on your outputs.

TCC1->CCB[0].reg = 399;                           // Set the duty cycle of the PWM on TCC1 to 25%
while (TCC1->SYNCBUSY.bit.CCB0);                  // Wait for synchronization

Kind regards,
Martin