There is a DC motor that requires a PWM frequency between 5 to 10 kHz to drive it. Low PWM frequency generates noise while driving the motor.
So,
Note: If you don’t have DSO to analyze the output PWM frequency, you can use simulation tools like Proteus, Wokwi, or any other platform.
PWM (Pulse Width Modulation) is varying the pulse width to control the amount of power delivered.

PWM is used for dimming LEDs, controlling motor speed, and generating sounds like beeps in a buzzer.
The percentage of time the signal is "ON" during one cycle.
Duty Cycle (%) = (Time ON / Total Period) × 100

The number of cycles (Time ON + Time OFF) per second. It is measured in Hertz (Hz).

If the PWM frequency is too low, the human eye can detect the LED flickering as it turns ON and OFF.
Thus, use PWM frequency >100 Hz to avoid flicker, but 500 Hz–5 kHz for high-power LEDs.
Similarly, in motor, for smoother motion 1–20 kHz, but adjust based on motor type and driver limits.
PWM resolution refers to the number of discrete steps (levels) available to adjust the duty cycle of a PWM signal.
For example:

| Bits (n) | Resolution (Steps) | Duty Cycle change per step ( % ) |
|---|---|---|
| 1 bit | 2^1=2 (0 ,1 ) | 100% / 1 = 100% |
| 2 bits | 2^2=4 (0 to 3) | 100% / 3 = 33.33% |
| 4 bits | 2^4=16 (0 to 15) | 100% / 15 = 6.66% |
| 16 bits | 2^16 = 65,536 | 100% / 65535 ≈ 0.0015% |
Resolution defines how finely you can control the output.

Dithering in PWM is the technique of rapidly toggling between different duty cycles for smoother analog output.
If you want a duty cycle of 12.5%, but PWM can only do 12% or 13%. Dithering alternates between these values:
cycle 1: 12%
cycle 2: 13%
cycle 3: 12%
cycle 4: 13%
This averages out to 12.5% over time.
Considering AVR microcontrollers
| Register | Purpose |
| TCCRnA | Select PWM mode and compare output behavior. |
| TCCRnB | Sets clock source and prescaler. |
| OCRnx | Sets the PWM duty cycle (compare value). |
| ICRn | Used to set TOP value in some modes (like Fast PWM with ICRn). |
| TIMSKn | Enables PWM interrupts (optional). |
Where,
n = Timer number (0, 1, or 2)
x = Channel (A or B)
NOTE: ARM and RISC-based 32-bit microcontrollers may have more PWM-related registers (like frequency control, dead time insertion, synchronized updates, etc).
The hardware generates the PWM signal without CPU intervention.
analogWrite(pin, value)
Generates a PWM signal on the specified pin. The value ranges from 0 (0% duty cycle) to 255 (100% duty cycle).
On Arduino Uno, 6 pins can generate a PWM waveform (marked with ~):
These default frequencies can be changed by modifying timer settings, but doing so may affect other functions like delay() or millis().
1. LED Fade

// Fade an LED using PWM
int ledPin = 9; // Pin with PWM (marked ~ on Arduino Uno)
void setup() {
pinMode(ledPin, OUTPUT);
}
void loop() {
// Increase brightness
for (int brightness = 0; brightness <= 255; brightness++) {
analogWrite(ledPin, brightness); // Set PWM duty cycle
delay(10);
}
// Decrease brightness
for (int brightness = 255; brightness >= 0; brightness--) {
analogWrite(ledPin, brightness);
delay(10);
}
}
2. Changing PWM Frequency (50Hz, 7.5%)

void setup() {
pinMode(9, OUTPUT);
// Set Fast PWM on Timer1, change prescaler
TCCR1A = _BV(COM1A1) | _BV(WGM11); // non-inverting mode, Fast PWM
TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS11); // Prescaler 8
ICR1 = 40000; // TOP value -> ~50Hz
OCR1A = 3000; // Duty cycle
}
void loop(){
}