Hi @meso2
Your code looks good to me. The only thing I'd suggest is using the buffered PERB register rather than the unbuffered PER. It just requires adding a "B" to the end of the register name.
The reason for using the buffered CCBx and PERB registers, is that they only take effect at the end of the timer cycle, whereas changes to the unbuffered CCx and PER register take effect immediately at the timer output. This prevents glitches from occuring on the timer output waveform.
To prevent slight possibility that CCBx and PERBx register updates occur either side of a timer update, it's possible to temporarily block updates using the Lock Update bit in the timer's CTRLB register like this:
TCC0->CTRLBSET.reg = TCC_CTRLBSET_LUPD; // Set the Lock Update bit
while (TCC0->SYNCBUSY.bit.CTRLB); // Wait for synchronization
TCC0->PERB.reg = 47999; // Set the frequency of the PWM on TCC0 to 1000Hz
while(TCC0->SYNCBUSY.bit.PERB); // Wait for synchronization
TCC0->CCB[3].reg = 24000; // Set the duty-cycle to 50%
while(TCC0->SYNCBUSY.bit.CCB3); // Wait for synchronization
TCC0->CTRLBCLR.reg = TCC_CTRLBCLR_LUPD; // Clear the Lock Update bit
while (TCC0->SYNCBUSY.bit.CTRLB); // Wait for synchronization