You can use the ATmega internal PWM peripherals to generate faster PWM outputs than the software based analogwrite().

Fast PWM Resources

https://www.arduino.cc/en/Tutorial/SecretsOfArduinoPWM

Registers & Bits

Consult that datasheet for the ATmega used in the Arduino you are using as the exaxt bit usage varies between timers and between devices.

There are 2 fast PWM modes.

Fast PWM which will give you 62.5kHz, with prescaller options to slow it down by a factor of 8, 64, 256 or 1024.

This mode sounds complicated from the description but its just bog standard PWM, output high for set PWM period, going low when it gets to end of set period and then resetting high again when the timer resets by overflowing or hitting the TOP value.

Phase-Correct PWM which will give you 31.25kHz, with prescaller options to slow it down by a factor of 8, 64, 256 or 1024.


//The timer can either run from 0 to 255, or from 0 to a fixed value. (The 16-bit Timer 1 has additional modes to supports timer values up to 16 bits.)
//In the following "x" is "0", "1" or "2" for timer 0, 1 or 2.
//
//Setting the timer prescaller:
//  Setting                          Prescale_factor
//  TCCRxB = _BV(CS00);              1
//  TCCRxB = _BV(CS01);              8
//  TCCRxB = _BV(CS00) | _BV(CS01);  64
//  TCCRxB = _BV(CS02);              256
//  TCCRxB = _BV(CS00) | _BV(CS02);  1024
//
//WGM bits:
//  Control the overall mode of the timer (These bits are split between TCCRnA and TCCRnB registers)
//
//CS bits
//  Clock Select bits, these control the clock prescaler
//
//COMnA bits
//  Compare Match Output A Mode bits.  These enable/disable/invert output A
//
//COMnB bits
//  Compare Match Output B Mode bits.  These enable/disable/invert output B
//
//OCRnA and OCRnB registers
//  Output Compare Registers, set the levels at which outputs A and B will be affected. When the timer value matches the register value, the corresponding output will be modified as specified by the mode.

Arduino Uno


Timer output	Arduino output	Chip pin	Pin name
OC0A			6				12			PD6
OC0B			5				11			PD5
OC1A			9				15			PB1
OC1B			10				16			PB2
OC2A			11				17			PB3
OC2B			3				5			PD3

You can configure just one of the pins to be used for a particular PWM, the B one being the one used if the top count of the PWM frequency is programmable via the OCRxA register.

Timer0 PWM Output

Timer0 is used for general arduino timers so if you alter Timer 0 you need to use commands to alter its usage by arduino functions.

Changing the prescale factor on Timer0 will affect these functions:
millis(), micros(), delay(),…
You can either adjust your usage of these functions with compensating values or you can modify a line in the wiring.c function in the Arduino program files "hardware\arduino\cores\arduino\wiring.c"

USEFUL?
We benefit hugely from resources on the web so we decided we should try and give back some of our knowledge and resources to the community by opening up many of our company’s internal notes and libraries through mini sites like this. We hope you find the site helpful.
Please feel free to comment if you can add help to this page or point out issues and solutions you have found, but please note that we do not provide support on this site. If you need help with a problem please use one of the many online forums.