Trouble with setting the PWM frequency for Arduino Due I'm using Arduino Due and I set the analog read and write resolution to 12-bit for better resolution. Basically all I do is to vary PWM duty cycle by controlling analog DC input voltage from 0 to 3.3V. The simple code as it is now works fine as follows:


int pwmPin9 = 9;      
int analogPin0 = 0;   
int val = 0;         


void setup() {

  Serial.begin(9600);

  pinMode(pwmPin9, OUTPUT);  // sets the pin as output    
  analogWriteResolution(12);
  analogReadResolution(12);

}

void loop() {

  val = analogRead(analogPin0);  // read the input pin    
  Serial.println(val);
  analogWrite(pwmPin9, val); 

}


My problem is I need to set the frequency of the PWM output to 25kHz or at least something nearest above 25kHz. 

I have been searching forums hours and couldn't find any solution. Here I came across a way but there is no library called variant.h in my folders. And that code if I include in my script doesn't change anything.
What could be a workaround for this?

(I used to achieve this via this site by using Arduino Uno but for Due couldn't find any working solution)

Edit: I found the file and made the following change in variant.h:

 * PWM
 */
#define PWM_INTERFACE       PWM
#define PWM_INTERFACE_ID    ID_PWM
#define PWM_FREQUENCY       20000
#define PWM_MAX_DUTY_CYCLE  4095
#define PWM_MIN_DUTY_CYCLE  0
#define PWM_RESOLUTION      12

/*
 * TC
 */
#define TC_INTERFACE        TC0
#define TC_INTERFACE_ID     ID_TC0
#define TC_FREQUENCY        20000
#define TC_MAX_DUTY_CYCLE   255
#define TC_MIN_DUTY_CYCLE   0
#define TC_RESOLUTION       8


But it only works for 20kHz. If I set to 25kHz or 30kHz I don't get any error but also don't get any output :((
There are a few things to do. I've used this successfully in the past with older projects. 

As a side note one can very easily change PWM settings on pins with the esp32, a single line of code being ledcSetup(PWM_Channel_Number, Frequency, resolution) without ever having to actually dive into modifying variant.h

To Quote Kerry D. Wong:


  If you take a look at the function PWMC_ConfigureClocks in pwmc.c, you will see that the highest PWM frequency can be accommodated as the function input is 42 MHz, this is because inside the function it calls FindClockConfiguration which in turn ensures that the frequency parameter passed in is less than the MCK frequency. Thus for integer dividers, the highest frequency we can pass in is 42 MHz (with divider 2).
  
  To achieve the highest output frequency, we can use a one bit PWM which essentially just outputs a square wave with a duty cycle of one. We can then set the prescaler to 2 to obtain an 84 MHz waveform.


#include &lt;Arduino.h&gt;

uint32_t pwmPin = 8;
uint32_t maxDutyCount = 2;
uint32_t clkAFreq = 42000000ul;
uint32_t pwmFreq = 42000000ul; 

void setup() {
  pmc_enable_periph_clk(PWM_INTERFACE_ID);
  PWMC_ConfigureClocks(clkAFreq, 0, VARIANT_MCK);

  PIO_Configure(
    g_APinDescription[pwmPin].pPort,
    g_APinDescription[pwmPin].ulPinType,
    g_APinDescription[pwmPin].ulPin,
    g_APinDescription[pwmPin].ulPinConfiguration);

  uint32_t channel = g_APinDescription[pwmPin].ulPWMChannel;
  PWMC_ConfigureChannel(PWM_INTERFACE, channel , pwmFreq, 0, 0);
  PWMC_SetPeriod(PWM_INTERFACE, channel, maxDutyCount);
  PWMC_EnableChannel(PWM_INTERFACE, channel);
  PWMC_SetDutyCycle(PWM_INTERFACE, channel, 1);

  pmc_mck_set_prescaler(2);
}

void loop() 
{



  Note that VARIANT_MCK is defined in /arduino-1.5.7/hardware/arduino/sam/variants/arduino_due_x/variant.h as 84000000. PWM_INTERFACE_ID and PWM_INTERFACE are defined in variant.h as ID_PWM and PWM which in turn are defined in /arduino-1.5.7/hardware/arduino/sam/system/CMSIS/Device/ATMEL/sam3xa/include/sam3x8e.h.
  
  So as the conclusion, the highest stable frequency we can generate using an Arduino Due is 84 MHz. The pictures below show the captured waveforms under different frequencies. For the 21 MHz waveform, pwmFreq is set to 21000000, no prescaler is used. For the 42 Mhz waveform, pwmFreq is set to 420000 with no prescaler. The 84 MHz waveform is generated with set to 42000000 and the prescaler set to 2.


Hope this helps.