Skip to main content
2 of 3
+ example code.
Edgar Bonet
  • 45.2k
  • 4
  • 42
  • 81

The Arduino Uno is based on an ATmega382P microcontroller. This chip has two 8-bit timers, driving two PWM channels each, and one 16-bit timer, driving the last two channels.

You cannot increase the resolution of the 8-bit timers. You can, however, put the 16-bit timer in 16-bit mode, instead of the 8-bit mode used by the Arduino core library. This will give you two 16-bit PWM channels, with a reduced frequency of 244 Hz (maximum). You will probably have to configure the timer yourself, and will not benefit from the easy to use analogWrite() function. For details, see the section on Timer 1 in in the ATmega328P datasheet.

Edit: Here is an example code illustrating this, I just tested it on my scope.

void setup() {
    DDRB |= _BV(PB1) | _BV(PB2);        /* set pins as outputs */
    TCCR1A = _BV(COM1A1) | _BV(COM1B1)  /* non-inverting mode PWM */
           | _BV(WGM11);                /* mode 14: fast PWM, TOP = ICR1 */
    TCCR1B = _BV(WGM13) | _BV(WGM12)
           | _BV(CS10);                 /* no prescaling */
    ICR1 = 0xffff;                      /* TOP counter value */
}

void loop() {
    static uint16_t i;
    OCR1A = i;          /* output on digital 9 */
    OCR1B = 0xffff-i;   /* output on digital 10 */
    i++;
    delay(1);
}
Edgar Bonet
  • 45.2k
  • 4
  • 42
  • 81