# ATmega328P Fast PWM Theory to Practice with Examples

If you're anything like me, you probably started your journey into PWM (Pulse Width Modulation) with a simple curiosity and a desire to tinker with electronics. It all began with basic LED fading and motor speed control experiments, right?

As I delved deeper into the world of microcontroller programming, I stumbled upon the Fast PWM mode of the ATmega328P. Now, why did I venture into this? Well, simply put, I wanted more control. I wanted to fine-tune LED brightness and motor speeds with greater precision. And that's where Fast PWM came into play.

### The Quest for Understanding Fast PWM

Picture this: I had just learned the basics of PWM, and I was eager to take my projects to the next level. So, armed with determination and a handful of components, I set out to conquer Fast PWM on my trusty ATmega328P microcontroller.

### Making Sense of Fast PWM Programming

Now, let me tell you, diving into Fast PWM programming wasn't as daunting as I initially thought. In fact, it was surprisingly straightforward. With a bit of trial and error (okay, maybe more error at first!), I began to grasp the concepts.

### Putting Theory into Practice

#### Controlling LED Brightness

But enough talk, let's get practical! Here's a simple example of how I used Fast PWM to control the brightness of an LED:

#include <avr/io.h>

int main() {
DDRB |= (1 << PB1); // Set Pin 9 as output

// Fast PWM mode, non-inverting mode
TCCR1A |= (1 << COM1A1) | (1 << WGM11);
TCCR1B |= (1 << WGM12) | (1 << WGM13) | (1 << CS10);

ICR1 = 0xFFFF; // Set TOP value for desired frequency
OCR1A = 0x7FFF; // Adjust duty cycle (50%)

while (1) {
}
return 0;
}


### The Joy of Control

Ah, the satisfaction of seeing that LED glow just the way I wanted it to! And it didn't stop there. Fast PWM opened up a world of possibilities, from precise motor speed control to creating dazzling lighting effects.

#### Speed Control of Servo Motor

Another useful practical example of using Fast PWM is the control of servo motor speed.

Below is circuit diagram to connnect ATmega328p microcontroller to the servo motor.

Below is the servo motor control code to smoothly rotate a servo motor across its entire range, from its minimum angle to its maximum angle (either 0 degrees to 180 degrees or -90 degrees to +90 degrees), and then back to its minimum position. Achieving this requires configuring Timer 1 in Fast PWM mode. Within this mode, we'll set the output to either non-inverted PWM or inverted PWM. For this particular application, we'll opt for non-inverted PWM.

#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
DDRB |= (1<<PB1); // Set PB1 as output

TCCR1A |= (1<<COM1A1) | (1<<WGM11); // Fast PWM, non-inverting mode
TCCR1B |= (1<<WGM13) | (1<<WGM12) | (1<<CS11); // Fast PWM, prescaler = 8
ICR1=39999;   //20ms PWM period
//OCR1A = 1999; // Set initial position to 90 degrees

while (1){
OCR1A = 1999; // Set position to 0 degrees
_delay_ms(1000);
OCR1A = 2999; // Set position to 90 degrees
_delay_ms(1000);
OCR1A = 3999; // Set position to 180 degrees
_delay_ms(1000);
}
}

Likewise we can control speed of a dc motor. For tutorial on controlling dc motors with pwm see the examples codes speed control of dc motor with fast pwm.

### Conclusion: Fast PWM Unleashed!

So, there you have it – my journey into the realm of Fast PWM programming on the ATmega328P. It's been a thrilling ride, filled with discoveries and ah-ha moments. And the best part? You don't need to be a programming wizard to harness the power of Fast PWM. With a bit of curiosity and a sprinkle of determination, you too can embark on your own PWM adventures.

Happy coding!

Previous: ATmega328P PWM basics