PWM in Atmega 16- Part 2

In the part one of this article, I have written about the introduction of PWM. In this article, you will learn in-depth knowledge of PWM and how to use PWM in atmega16.

Generating PWM using Timer in CTC mode

Well, you can generate the PWM signals by using “timer in CTC mode”. We can implement that by activating the interrupt of compare match and overflow in the timer control register. Here, I am not telling how to do that because I have already explained this here- Timer in CTC mode. Below is the program of generating PWM using timers.

#include <avr/io.h>
#include <avr/interrupt.h>

void timerinctcinit(int duty)
	OCR0=duty;//between 0 to 255 127 is almost half

int main(void)
    while (1) 	
		//nothing required here as all the working is done in interrupt
	PORTA = 0x00;	

Although the above program works fine, Atmega 16 has inbuilt PWM modes, let us learn how to use that.

Using PWM modes in Atmega 16

Now, the above program is good and works fine. But AVR controllers have all of these controls built-in. The only problem with that is it is pin constraint. So, if you are looking for much accuracy, and okay with pin constraint, you should follow the article.

PWM Modes

There are several modes of PWM in Atmega 16, these are

Fast PWM

This is the most useful and simplest of all the modes. In this mode, the timer counts from 0 to 255 and the output signal is high at the starting of the timer. When the match occurs between OCRx Register, the output signal becomes low. This gives us the control over duty cycle as we can vary the value of OCRx register.

Phase-correct PWM

In this mode, the timer starts from 0 and counts all the way up. The output signal Is high when the timer starts. When the compare occurs, the signal becomes low. Till now, it is the same as Fast PWM but when the catch starts now. The counter tarts decreasing the value when it reaches the top value and when the compare occurs backward, the signal becomes high. This gives us control over the phase of the output signal.

Now, both of these modes also has an additional mode that gives the control over output frequency. While we are at it, let us understand those two as well

Varying the timer top limit: fast PWM

In this mode, the timer starts from 0 and rather than going to 255, it goes up to the OCR. The gives us the more control of the frequency of the signal. You can toggle the signal each time the signal reaches the OCR value.

Varying the timer top limit: phase-correct PWM

Same as Varying the timer top limit, the timer I phase correct PWM can be configured to reset. Now you might be wondering the difference between these two?

Suppose the timer is set to fast PWM mode and is set to count up to an OCRnA value of 3. The timer will take on the values 012301230123… Note that there are 4 clock cycles in each timer cycle. Thus, the frequency will be divided by 4, not 3. The duty cycle will be a multiple of 25% since the output can be high for 0, 1, 2, 3, or 4 cycles out of the four. Likewise, if the timer counts up to 255, there will be 256 clock cycles in each timer cycle, and the duty cycle will be a multiple of 1/256. To summarize, fast PWM divides by N+1 where N is the maximum timer value (either OCRnA or 255).

Now consider phase-correct PWM mode with the timer counting up to an OCRnA value of 3. The timer values will be 012321012321… There are 6 clock cycles in each timer cycle (012321). Thus the frequency will be divided by 6. The duty cycle will be a multiple of 33% since the output can be high for 0, 2, 4, or 6 of the 6 cycles. Likewise, if the timer counts up to 255 and back down, there will be 510 clock cycles in each timer cycle, and the duty cycle will be a multiple of 1/255. To summarize, phase-correct PWM divides by 2N, where N is the maximum timer value.


Now that we know the modes, I think we know everything we need except about the configuration of the register.

Selecting the Modes of PWM

It depends on your project and how much control you need. If you just need the simpler control over duty cycle, fast PWM is better. But if you need more control over duty cycle and frequency of the output wave, select phase correct PWM.

The Program

In this program, I am using timer 0 of Atmega 16, which is an 8-bit register. The register we are looking for is TCCR0. Let’s look into its bits

TCCR0 Register

pwm in atmega16

BIT-6:3-WGM Bits

The value we can give to these bits are given below in the table.

tccr0 in atmega16

Bit 5:4 -Compare Output Modes

These bits are used to program the behavior of the controller when compare match occurs. You can set any one of these values according to your need. The pin it controls is PB3 of Atmega 16. Also, this is given for fast PWM. For more details about these bit- please see page 84 of the Atmega 16 datasheet. You can download the datasheet by clicking here.

Now there are prescaling bits left, I am assuming that you know about these bits here. If you don’t know about prescaling and it’ bits, I highly recommend you to visit this post first.

We have everything we need- let’s write a program it.

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

void InitPWM()
   TCCR0|=(1<<WGM00)|(1<<WGM01)|(1<<COM01)|(1<<CS00);     //Fast PWM, non-inverting mode and no prescaler.
   DDRB|=(1<<PB3);            //setting the output pin of 4th pin of Port B-PB3.
   										      //0 to 255 - 0 means 0% and 255 means 100% duty cycle

void setduty(char duty)

void main()
   setduty(127);							//setting the duty cycle to 50%
										//everything is already set in hardware, don't need to do anything

I hope this article helps you guys to understand about PWM in Atmega16. We will do some projects based on PWMs later on. Well, see you next time.


Share This