


Set the PWM signal to output 50% duty cycle While (TCC0->) // Wait for synchronization REG_TCC0_PER = 96 // Set the frequency of the PWM on TCC0 to 250kHz this determines the frequency of the PWM operation: Each timer counts up to a maximum or TOP value set by the PER register, TCC_WAVE_WAVEGEN_DSBOTH // Setup dual slope PWM on TCC0 REG_TCC0_WAVE |= TCC_WAVE_POL(0xF) | // Reverse the output polarity on all TCC0 outputs Dual slope PWM operation: timers countinuously count up to PER register value then down 0 GCLK_CLKCTRL_ID_TCC0_TCC1 // Feed GCLK4 to TCC0 and TCC1 REG_GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN | // Enable GCLK4 to TCC0 and TCC1 PORT->Group.ulPort].PMUX.ulPin > 1].reg = PORT_PMUX_PMUXO_F F & E specify the timers: TCC0, TCC1 and TCC2 Connect the TCC0 timer to digital output D7 - port pins are paired odd PMUO and even PMUXE PORT->Group.ulPort].PINCFG.ulPin].bit.PMUXEN = 1 Enable the port multiplexer for the digital pin D7 GCLK_GENCTRL_SRC_DFLL48M | // Set the 48MHz clock source REG_GCLK_GENCTRL = GCLK_GENCTRL_IDC | // Set the duty cycle to 50/50 HIGH/LOW While (GCLK->) // Wait for synchronization GCLK_GENDIV_ID(4) // Select Generic Clock (GCLK) 4 REG_GCLK_GENDIV = GCLK_GENDIV_DIV(1) | // Divide the 48MHz clock source by divisor 1: 48MHz/1=48MHz Output 250kHz PWM on timer TCC0 (6-bit resolution)
#Arduino pwm code code
Using my old multimeter I've sucessfully tested the code for 125kHz, however it's not capable of measuring 250kHz and I haven't got a scope, so I'm unable to test it at this higher frequency. To control the PWM output just load the REG_TCC0_CCB3 register with a value between 0 and 96. The TCC0 is set up for dual slope PWM operation and connected to ouput D7. The following code sets up GCLK 4 to feed timer TCC0 with 48MHz. Loading the CCBx register with 48 gives a 50% duty cycle. 0 outputs 0V (0% duty cycle), 96 outputs 3.3V (100% duty cycle). To change the PWM pulse width (phase), just load the timer's CCBx register with a value between 0 and 96. Resolution at 250kHz = log(96 + 1) / log(2) = 6.6 = 6 bits (rounding down) Resolution = log(PER + 1)/log(2), therefore: The resolution for dual slope PWM is given by: So the PER should be set at 96 (decimal). In your case N = 1 (as we'd like to clock the timer as fast as possible), therefore.įrequency = 48MHz / (2 * 1 * 96) = 250kHz The value in the PER register determines the maximum value the timer counts up to. The frequency for dual slope PWM is determined by:įrequency = GCLK frequency / (2 * N * PER) where N = prescaler value (CTRLA register)

However, due to the high speed of your 250kHz PWM signal in relation to the 48MHz clock frequency, you'll end up with poor resolution. It's possible to set up a given GCLK to feed a 48MHz (CPU clock frequency) signal to one of the timers.
#Arduino pwm code free
There are 8 GCLKs in total, 0 to 3 are used by Arduino, but you're free to use the others. These timers are clocked by one of the processor's generic clocks (GCLK). In dual slope PWM the timer counts up to a given value then counts back down to zero, and so on.ĭual slope PWM on the SAMD21 is provided by the timers TCC0, TCC1 and TCC2. If you're interested in reading further, it's detailed in the SAMD21 datasheet, page 660, under the heading “Dual Slope PWM Generation”. Both the AVR and the ARM processors are capable of controlling both the phase and frequency using dual slope PWM.
