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"