I've got an application where I need to vary the output of a square wave on pin PA30 (using TCC1/WO) from around 3kHz to around 32kHz.
Right now I'm using analogWrite() to initialize the pin at the SAMD21's base PWM frequency (about 192kHz on my core) and a 50% duty cycle. Once that's set up I am using the following function to allow the user to adjust the output frequency:
REG_TCC1_PER = myPer; // Set the frequency of the PWM on TCC1 to 50kHz while (TCC1->SYNCBUSY.bit.PER); REG_TCC1_CCB0 = myPer / 2; // Set the duty cycle of the PWM on TCC0 to 50% while (TCC1->SYNCBUSY.bit.CCB0);
This works fine, but I get discontinuities in the output as I change the frequency.
I've been using a different setup from Nebs Petrovic to control TC3 on another project. His code pulls the current values from the counter and then re-maps them to proportional values at the new frequency to ensure that the timer output is the same at the new frequency as it was at the old one.
int compareValue = (CPU_HZ / (TIMER_PRESCALER_DIV * frequencyHz)) — 1; TcCount16* TC = (TcCount16*) TC3; TC->COUNT.reg = map(TC->COUNT.reg, 0, TC->CC.reg, 0, compareValue); TC->CC.reg = compareValue; while (TC->STATUS.bit.SYNCBUSY == 1);
I've made an attempt to get this code working on TCC1 but I'm having troubles. I'm still unsure about the setup for reading the COUNT.reg for TCC1 as compared to TC3, so if anyone has an idea about how to implement this smooth change on TCC1 I'd appreciate some pointers.