Arduino DUE Hardware Pin Frequency varriaiton

Hello community!

I need a way to change the pwm frequency, while maintaining full 12bit resolution of the duty cycle on my Due.
I run a Voice Coil motor with an H-Bridge and have problems with the noisy 4kHz sound thats created by the pwm.
I need the pwm-Pins, because i need ongoing processing of a PID-Controller and several analog reads meanwhile.

I Am searching for an easy way to increase the pwm-Frequency to above 20kHz so that its not noticable for the ear.
The best would be some Code i could add into my Code sothat the frequency increases.

I dont rly understand the Manual, though i understand the principle how the pwm triggering works cause i read the pages 867 to 871 of the manual. Still i dont have enought insight to create a code.
I would realy appreciate it if you can share your knowledge with me :smiley:
I think a lot of ppl. have a simmilar issue, because how manny simmilar threads are out there.

Greetings!

Scully

I have tested the pwm_lib, but it seems to be just for the digital pins?

You need the pinout diagram and the datasheet to follow stepwise PWM programming. See below a minimal code for a 20 KHz PWM frequency with a 50% duty cycle on pin 39 (PWMH2) :

void setup () {
  //  see Datasheet chap. 38.5.1 page 973
  // Select Instance=PWM; Signal=PWMH2 (channel 2); I/O Line=PC7 (PC7, Arduino pin 39, see pinout diagram) ; Peripheral type=B
  // PWM Set-up on pin PC7 (Arduino Pin 39(PWMH2) : see Datasheet chap. 38.5.1 page 973
  
  PMC->PMC_PCER1 |= PMC_PCER1_PID36;                   // PWM power On (see datasheet page 39)
  
  PWM->PWM_DIS = PWM_DIS_CHID2;                         // Disable PWM channel 2

  PIOC->PIO_PDR |= PIO_PDR_P7;                          // Disable the PIO from controlling the corresponding pin 
                                                        // ===> Enable PWM peripheral control of the pin

  PIOC->PIO_ABSR |= PIO_PC7B_PWMH2;                     // Set PWM pin peripheral type B


  PWM->PWM_CLK = PWM_CLK_PREA(0) | PWM_CLK_DIVA(1);    // Set the PWM clock rate to 84 MHz

  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 = 4200;                 // Channel 2 : Set the PWM frequency to 84MHz/CPRD = 20 KHz

  PWM->PWM_CH_NUM[2].PWM_CDTY = 2100;                 // Channel 2: Set the PWM duty cycle to (CDTY/ CPRD)  * 100 % = 50 %


  PWM->PWM_ENA = PWM_ENA_CHID2;                       // PWM channel 2 enable

  // Alternately, you can use this format :  REG_PWM_CPRD2 = 4200;

}


void loop() {


}

Thank you a lot.
Actualy your example did not work. But i found another way to change it.
I changed the variant.h file that is located in

User/AppData/Local/Arduino15/packages/arduino/hardware/sam/1.6.11/variants/arduino_due_x/variant.h

In the file I changed #define PWM_FREQUENCY 20000 // from 1000

Changing this file was my first attemt, but I could not could not find it.
Im still wondering, why your code-example does not work :S

This is realy easy. Is there a way to change the frequency in the programmcode or even while the program is running by this? A function like analogWriteFrequency(); would be great.

Anyway, thank you Sir!

Hi there @D_Scully,

Have a look to pwm_lib at GitHub - antodom/pwm_lib: This is a C++ library to abstract the use of the eight hardware PWM channels available on Arduino DUE's Atmel ATSAM3X8E microcontroller..

This library abstract the use of the eight hardware PWM channels available on Arduino DUE's Atmel ATSAM3X8E microcontroller. You can change easily the frequency of PWM outputs, even dynamically, usin g pwm_lib. Have a look to the examples that come with the library, and if in doubt just ask me.

I hope it helps.