Need help to set PWM frequency to 25kHz on pin 8 of Arduino Mega
easy.


find a copy of the datasheet for your mcu;
go to the section about your timer;
figure out a prescaler setting that yields the maximum roll-over count;
pick the timer mode that supports the roll-over count;
write your own analogWrite() function;
[optional] if you wish to reuse the stock analogWrite(), make sure that roll-over count calculated in 3) is a valid data type for the stock analogWrite(). If not, increase the prescaler in 3) until it is.
done.


edit: i decided to give it a try.

the following code:

void setup() {
  // put your setup code here, to run once:
  pwm1Set(TMR1_PS8x, F_CPU / F_PWM1 / 8);       //ps = 8x, top = F_CPU / F_PWM / 8 = 80
  analogWrite(9, 20);                           //dc = 20/80=25%
  analogWrite(10, 40);                          //dc = 40/80=50%
}

void loop() {
  // put your main code here, to run repeatedly:
}


produced the following output on an ATMega328p's TIMER1.



i'm reasonably sure that the output is indeed 25Khz.

the code itself however is capable of generating pwm at other frequencies.

edit2: the same code on mega2560 generating 25Khz pwm on pin6/7/8:



code used for that is as follows:

  //ps = 8x, top = F_CPU / F_PWM / 8 = 80
  //DC on Pin 6 = 20/80 = 25, 
  //DC on Pin 7 = 40/80 = 50,
  //DC on Pin 8 = 60/80 = 75,
  pwm4Set(TMR4_PS8x, F_CPU / F_PWM4 / 8); analogWrite(6, 20);  analogWrite(7, 40);  analogWrite(8, 60);


pwm4Set() is a copy of pwm1Set(). Both are simple enough: only 5 lines of code used.