I'm having issues finding examples on how to adjust the frequency of the PWM outputs on the Arduino Due. The PWM Libraries I have found are not compatible with the Due (nor Leonardo for that matter). Specifically, I'm trying to adjust Pin 9's frequency to at <= 60 Hz while still being able to control the duty cycle. I need this to control a pump motor and don't want the higher frequency to cause too much heat and unnecessary wear on the electrical components that drive the pump. From what I've read, it appears that Pin 9 uses Timer 2. I can't seem to find how to adjust the frequency of this without losing the ability to uses the normal pwm functions to adjust the duty cycle.
If you want to adjust duty cycle during operation, IMO the PWM peripheral is more suited than the Timer Counter peripheral because any duty cycle modification will be automatically implemeted right at the beginning of a new PWM period.
Once a PWM channel is enabled, you will UpDate the duty cycle Inside the loop() with the PWM_CDTUPD register. Idem for the frequency, you will be using PWM_CPRDUPD Inside the loop().
Here is an example sketch:
void setup () {
// PWM Set-up on pins PC7 (Arduino Pin 39(PWMH2): see Datasheet chap. 38.5.1 page 973
PMC->PMC_PCER1 |= PMC_PCER1_PID36; // PWM channel 2 power ON
PWM->PWM_DIS = PWM_DIS_CHID2; // Disable PWM channel 2
// Select Instance=PWM; Signal=PWMH2 (channel 2); I/O Line=PC7 (P7, Arduino pin 39, see pinout diagram) ; Peripheral type B
PIOC->PIO_PDR |= PIO_PDR_P7; // Set the pin to the peripheral PWM, not the GPIO
PIOC->PIO_ABSR |= PIO_PC7B_PWMH2; // Set PWM pin perhipheral type B
PWM->PWM_CLK = PWM_CLK_PREA(0b111) | PWM_CLK_DIVA(2); // Set the PWM clock rate to 328125 Hz (84MHz/2/128). Adjust DIVA for the resolution you are looking for
PWM->PWM_CH_NUM[2].PWM_CMR = PWM_CMR_CPRE_CLKA; // The period is left aligned, clock source as CLKA on channel 2
PWM->PWM_CH_NUM[2].PWM_CPRD = 5400; // Channel 2 : Set the PWM frequency 328125 Hz/CPRD = F ;
PWM->PWM_CH_NUM[2].PWM_CDTY = 1000; // Channel 2: Set the PWM duty cycle to x%= (CDTY/ CPRD) * 100 % ;
PWM->PWM_ENA = PWM_ENA_CHID2; // Enable PWM channel 2
}
void loop() {
// Modify the Duty Cycle inside the loop() with PWM_DTYUPD once
// the PWM channel has been enabled in setup().
// The new DTY is implemented exactly at the beginning of a PWM period
PWM->PWM_CH_NUM[2].PWM_CDTYUPD = 100; // 1< CDTYUPD < CPRD
}
Thanks for the reply, this seems to compile and I was able to control the frequency and duty cycle of pin 39. What would I need to change in order to make this work on pin PWM9, or any of the PWM pins for that matter? I noticed if I try to use the PWM pins while this code was implemented it caused the PWM frequencies to be around 1 KHz. Not completely sure what is causing that. Hopefully it won't affect the Analog and Digital inputs I'll need for this project.