Skip to main content
Arduino

Return to Answer

replaced http://arduino.stackexchange.com/ with https://arduino.stackexchange.com/
Source Link

I am posting this second answer since I realized it is possible to have 4 PWM channels at 25 kHz with 161 steps on a single Arduino Uno. This involves changing the main clock frequency to 8 MHz changing the main clock frequency to 8 MHz, which has some side effects since the whole program will run half as fast. It also involves reconfiguring the three timers, which means loosing the Arduino timing functions (millis(), micros(), delay() and delayMicroseconds()). If these trade-offs are acceptable, here is how it goes:

Unlike the other answer other answer, this does not need a modified version of analogWrite(): the standard one will work fine. Only care should be taken that:

I am posting this second answer since I realized it is possible to have 4 PWM channels at 25 kHz with 161 steps on a single Arduino Uno. This involves changing the main clock frequency to 8 MHz, which has some side effects since the whole program will run half as fast. It also involves reconfiguring the three timers, which means loosing the Arduino timing functions (millis(), micros(), delay() and delayMicroseconds()). If these trade-offs are acceptable, here is how it goes:

Unlike the other answer, this does not need a modified version of analogWrite(): the standard one will work fine. Only care should be taken that:

I am posting this second answer since I realized it is possible to have 4 PWM channels at 25 kHz with 161 steps on a single Arduino Uno. This involves changing the main clock frequency to 8 MHz, which has some side effects since the whole program will run half as fast. It also involves reconfiguring the three timers, which means loosing the Arduino timing functions (millis(), micros(), delay() and delayMicroseconds()). If these trade-offs are acceptable, here is how it goes:

Unlike the other answer, this does not need a modified version of analogWrite(): the standard one will work fine. Only care should be taken that:

Source Link
Edgar Bonet
  • 45.1k
  • 4
  • 42
  • 81

I am posting this second answer since I realized it is possible to have 4 PWM channels at 25 kHz with 161 steps on a single Arduino Uno. This involves changing the main clock frequency to 8 MHz, which has some side effects since the whole program will run half as fast. It also involves reconfiguring the three timers, which means loosing the Arduino timing functions (millis(), micros(), delay() and delayMicroseconds()). If these trade-offs are acceptable, here is how it goes:

void setup()
{
 // Set the main system clock to 8 MHz.
 noInterrupts();
 CLKPR = _BV(CLKPCE); // enable change of the clock prescaler
 CLKPR = _BV(CLKPS0); // divide frequency by 2
 interrupts();
 // Configure Timer 0 for phase correct PWM @ 25 kHz.
 TCCR0A = 0; // undo the configuration done by...
 TCCR0B = 0; // ...the Arduino core library
 TCNT0 = 0; // reset timer
 TCCR0A = _BV(COM0B1) // non-inverted PWM on ch. B
 | _BV(WGM00); // mode 5: ph. correct PWM, TOP = OCR0A
 TCCR0B = _BV(WGM02) // ditto
 | _BV(CS00); // prescaler = 1
 OCR0A = 160; // TOP = 160
 // Same for Timer 1.
 TCCR1A = 0;
 TCCR1B = 0;
 TCNT1 = 0;
 TCCR1A = _BV(COM1A1) // non-inverted PWM on ch. A
 | _BV(COM1B1) // same on ch. B
 | _BV(WGM11); // mode 10: ph. correct PWM, TOP = ICR1
 TCCR1B = _BV(WGM13) // ditto
 | _BV(CS10); // prescaler = 1
 ICR1 = 160;
 // Same for Timer 2.
 TCCR2A = 0;
 TCCR2B = 0;
 TCNT2 = 0;
 TCCR2A = _BV(COM2B1) // non-inverted PWM on ch. B
 | _BV(WGM20); // mode 5: ph. correct PWM, TOP = OCR2A
 TCCR2B = _BV(WGM22) // ditto
 | _BV(CS20); // prescaler = 1
 OCR2A = 160;
}
void loop()
{
 analogWrite( 3, 1); // duty cycle = 1/160
 analogWrite( 5, 53); // ~ 1/3
 analogWrite( 9, 107); // ~ 2/3
 analogWrite(10, 159); // 159/160
}

Unlike the other answer, this does not need a modified version of analogWrite(): the standard one will work fine. Only care should be taken that:

  1. The value written should be between 0 (meaning always LOW) and 160 (always HIGH), inclusive.
  2. Only pins 3, 5, 9 and 10 are available. Attempting to analogWrite() to pins 6 or 11 will not only fail to deliver a PWM output, it will also change the frequency on pin 5 or 3 respectively.

AltStyle によって変換されたページ (->オリジナル) /