PWM Signal Generation by Using AVR Timers.

In the last tutorial you saw how the PWM technique helps us generate analog signals from a microcontroller. In this tutorial we will see how PWM generation is implemented with microcontrollers.

Before you begin please see

Generation of PWM signals is such a common need that all modern microcontrollers like AVR has dedicated hardware for that. The dedicated hardware eliminates the load of generation of PWM signal from software (thus frees the CPU ). Its like asking the hardware to generate a PWM signal of a specific duty cycle and the task of CPU is over. The PWM hardware with start delivering the required signal from one of its PINs while the CPU can continue with other tasks.

In AVR microcontrolers PWM signals are generated by the TIMER units. (See AVR Timer Tutorials) . In this tutorial I will give you the basic idea of how PWM signals are generated by AVR timers. Their are two methods by which you can generate PWM from AVR TIMER0 (for ATmega16 and ATmega32 MCUs).

  1. Fast PWM
  2. Phase Correct PWM

Don’t worry from their names they will become clear to you as we go on. First we will be considering the Fast PWM mode.

PWM Generation Fundas

We will use the simplest timer, TIMER0 for PWM generation.(Note TIMER0 of ATmega8 cannot be used for PWM generation, these are valid for ATmega16 and ATmega32). In this part we won’t be dealing with any code, we would just analyze the concepts. So lets start!

We have a 8bit counter counting from 0-255 and the goes to 0 and so on. This can be shown on graph as

avr timer pwm generation tutorial

Fig. 1 – AVR Timer Count Sequence for Fast PWM.

 

 

The period depends upon the prescalar settings. Now for PWM generation from this count sequence we have a new "friend" named OCR0 (Output Compare Register Zero , zero because its for TIMER0 and there are more of these for TIMER1 & TIMER2). We can store any value between 0-255 in OCR0, say we store 64 in OCR0 then it would appear in the graph as follows (the RED line).

avr pwm generation tutoraia

Fig. 2 – AVR Timer Count Sequence for Fast PWM with OCR0=64

 

 

So how does this Output Compare Register generates PWM? Well, the answer follows.

When the TIMER0 is configured for fast PWM mode,while up counting whenever the value of TIMER0 counter (TCNT0 register) matches OCR0 register an output PIN is pulled low (0) and when counting sequence begin again from 0 it is SET again (pulled high=VCC). This is shown in the figure 3. This PIN is named OC0 and you can find it in the PIN configuration of ATmega32.

Fig. 3- AVR Timer Count Sequence for Fast PWM with OCR0=64

 

 

From the figure you can see that a wave of duty cycle of 64/256 = 25% is produced by setting OCR0=64. You can set OCR0 to any value and get a PWM of duty cycle of (OCR0 / 256). When you set it to 0 you get 0% dutycycle while setting it to 255 you get 100% duty cycle output. Thus by varying duty cycle you can get an analog voltage output from the OC0 PIN. The resolution of this PWM is 8BIT. Watch the animation below for a step by step explanation of PWM generation process.

pwm generation process with avr timer

Fig. 4 – PWM Generation Process from AVR Timers.

 

 

One note about OCR0 is that it is double buffered. But what does than means?

It is just for your help. Double buffering means that you cannot directly write to OCR0 when ever you write to OCR0 you are actually writing to a buffer. The value of buffer is copied to actual OCR0 only during start of cycle (when TCNT0 wraps from 255 to 0). This nice feature prevents update of OCR0 in between the cycles. The new value of OCR0 comes into effect only on beginning of a new cycle even if you write to it in between a cycle.

In next tutorial we will see how to setup the TIMER0 in fast PWM mode, actually generate some PWM signals and use this to control the brightness of a LED.

To be continued …

Facing problem with your embedded, electronics or robotics project? We are here to help!
Post a help request.

Avinash

Avinash Gupta is solely focused on free and high quality tutorial to make learning embedded system fun !

More Posts - Website

Follow Me:
FacebookLinkedInGoogle Plus

68 thoughts on “PWM Signal Generation by Using AVR Timers.

  • By AM - Reply

    very good explanation of PWM I like it…
    Do oyu have any code for I2C without using TWI registers,
    where you can freely select pins of SCL and SDA for WinAVR?

    Thanks, Andrej

  • By Avinash - Reply

    @ AM
    You are Welcome!
    Right now I do not have that kind of I2C code. 🙁 Sorry

  • By percy villegas t - Reply

    How can I help you, because you home side help very much????

    I have used your code and built bigger code. In PWM, USART, TIMER, ADC.

    I have done that because I must use Atmega32 for drive a DC motor.

    Perhaps later in the project a can ask you same question about atmega32.

    Aninash you most present you for the people how read you page??

    Where you come from?
    How old are you?
    What you have study?
    And a photo is also always good?

    However thank friend??

    Percy Villegas

  • By Avinash - Reply

    Hello Percy,

    🙂 Thanks for your nice response! I am very happy that my work helped you and many more.

    I live in Jamshedpur a small city in India. And I am 22 years old (Yesterday was my birthday 21 Jan!)

    [More about Jamshedpur
    http://en.wikipedia.org/wiki/Jamshedpur ]

    Well friend tell me something about you. .)

    From your email (live.se) I think you are from Sweden (.se), am I right?

  • By percy villegas t - Reply

    Yes I live in Sweden Stockholm!!!!

    Now I do a project in Flen a small city in Sweden.

    I can tell you, we use AVR ATmega32 “STK500”and all the code we do is in CodeVisionAVR and we debugging in AVR Studio. All your code are do for AVR Studio so to use that a have do same change.

    I have do a program in C# how has start and stop button and a text field how show the speed.

    See below.

    Of course I have done other thinks for test.

    For send data and receive I have event functions, all work perfect in C#.
    In atmega32 I useUsart for receive and to send data and all is ok.

    I have also change duty cycle in a PWM with constant frequency, also I change the duty cycle from the C# program.

    .

    I have also done a program how read (INT0) pin 17 Atmega32, also External Interrupt how can read the two flank positive and negative, because a have a sensor how only give 5 and 0 V.

    It for see the speed of the motor, and could use that or regulate the motor.

    But now I most do a PID for de motor, the project is to drive a motor with the Atmega32.

    PID help the motor keep the constant speed in different situation, the motor we drive most go up to a stable speed and try to hold that.

    If you have same good tips send!!!

    Now you know what I do these days.

    What of course I’m body builder to, so I train tree to four days of the week. Here in Sweden it is normal.

    I’m happy because I now know Avinash one of the India best sons!!!!

    Ok friend God blesses you!!!

    Percy Villegas

  • By Avinash - Reply

    Hello Percy,

    🙂 Nice to meet you !
    Enjoy .

    And If you need any help do ask me. 😉

  • By percy villegas t - Reply

    Have you same example code there they use PID in C code, or perhaps you now one god page about it?

    Thanks for now and remember Mahatma Ghandi “only with help each other we change the world”

    Ok have a god day and of course a long live my friend!!!!

    Percy villegas

  • Pingback: PWM Signal Generation using AVR Timers | eXtreme Electronics

  • By vishal - Reply

    Hello,

    i have seen a tutorial on pwm generation. but i am working on
    atmega8 so, i need a code for controlling led intensity on atmega8.

    vishal labde

  • By Avinash - Reply

    Hello Vishal,
    🙂

    The code (on next tutorial) will not work with ATmega8 because TIMER0 does not has the “Compare Unit” and thus no PWM. So u have to use TIMER1 which is 16bit and has 2 PWM channels!

    But for begening I used simpler timer,TIMER0 which is 8Bit with one PWM.

    I will also give code for PWM on ATmega8 , till then try to get a ATmega32 and try simpler PWM technique on it using TIMER0.

    The complete code is given in next tutorial.

    Have Fun !!! 🙂

  • By priyaranjan - Reply

    well….nice explanation..easy to understand tthe concept pwm.
    i have one doubt on which basis we catagorise the 2 types of pwm i.e fast pwm & phase correct pwm.

  • By Avinash - Reply

    In phase correct PWM the Counter goes from 0 – 255 and then from 255 to 0 (in fast PWM it becomes 0 after 255)

  • By nicola - Reply

    Hi,
    I’d like to control the Timer Counter1 of an ATMega 32 on STK500. I want to use it as a chronometer with a start/reset and a stop pin. I’m working at 8 MHz. Which is the right value of prescaler.
    Thank you

  • By Siddhartha Raizada - Reply

    can u please explain the concept of buffer ..what it is actually ? for makin a uc burner we use a buffer but what we have studied in some books is that it is used to increase the magnitude of source n sink current??? so what is it actually ..

    • By Avinash - Reply

      @ Siddhartha

      In software a buffer is a piece of memory used for temporary storage. While in electronics it help increase the source/sink capacity of a line. Describe ur requiremnt in details ! Just telling “explain buffer” is not enough.

  • By Cy# - Reply

    Hi,
    Thanks for your very helpful tutorials.
    Where is the continuation of the above Tut.?

    thanks

    Cy

  • By curious - Reply

    can u mail me d link to d next tutorial…….n keep up ur gd work
    ….thanks

  • By Sangeetha - Reply

    Hi..
    Thanks for the PWM concepts.
    can you give some explanation about Optocouplers?
    How exactly it behaves as a isolator in electronic circuit.

  • By R.Prem Sunder - Reply

    Superb Explanation!!! Avinash great!!! Keep it up!!!
    You are really Brilliant!!!
    Belated Happy Birthday Wishes!!!

  • By Arunito - Reply

    Hi

    Percy Villegas…I search for you email adress..its about the trip for tommorow…I cant reach u on phone..so if u see this call me immediatlly..if u guys know his email..please give it to mee, thanks 🙂

  • By opportunity - Reply

    hats off to you avinash!!
    what i had been asking people around i got to
    know from your simple and clear explanation of
    the timer.

    thank you very very much.
    any tips to improve our knowlegde of electronics?

  • Pingback: Sound Generation by AVR Micro - Tutorial I | eXtreme Electronics

  • By chandan - Reply

    thanks again for this tutorial

  • By bhavin - Reply

    thanks nice work
    you helped us thats great

  • By Ming - Reply

    Hi Avinash,

    You did great job. Your tutorial is very helpful to me.

    In my project, a pwm of 1Hz (period=1sec) with duty cycle of 14ms is required. I am using atmega88pa.

    Is there any suggestion that I can generate this kind of pwm?

    I plan to do it by using 128K internal clock, but wonder that any side effects to the system.

    Thanks!

    Ming

  • By deepika - Reply

    i lyk the explanation ………specially animated partnow its vry easy 2 write a code

  • By sudarshan - Reply

    sir,
    please publish article on servo motor control with delay and timers

  • By avinash - Reply

    @sudarshan

    Yes , sure. Let me finish some other article first.

  • By sazawal - Reply

    Hi avinash,

    Thanks for the nice tutorial.

    I have some problem with my wheeled bot that i am going to start. I am using stepper motors. So, as far as I searched on the internet, I think an L293(H-Bridge) is needed to drive each bipolar stepper motor, is it?
    Another thing is the speed control that I think giving PWM on enable pin will work just like normal DC motors?

    • By Avinash - Reply

      @Sazawal,

      Your bit confused about steppers. Speed control mechanism is NOT line DC motors!

      You need to tie ENABLE pic to 5v. You need to change the frequency of output to control speed.

  • By sazawal - Reply

    Thanks for the reply.

    You mean changing frequency of output by changing the frequency of input signals? But in usual practice in DC motors we use to connect enable pin to PWM because it doesnt give braking effect.I mean input pin can be used to provide PWM but its avoided, right?

  • Pingback: Servo Motor Control by Using AVR ATmega32 Microcontroller | eXtreme Electronics

  • By sravani - Reply

    hai

    the theory for pwm generation using timers helped me alot but for better understanding its good if you include the example for pwm generation that includes the enabling of registers

  • By harish - Reply

    Hai
    hi friends i need help to generate pwm using timer2 in atmega8 for controlling servo motor please can you suggest any method or can you post the code for it we can generate the pwm wave of 50hz from timer1 and i face some difficulty in generating from timer2 because we cannot get specific frequency from it so please suggest me any thing in this

  • By harish - Reply

    @ avinash
    ho thanks but i need it by using avr atmega8 and can u guide us how to debug codevisionavr code using avr studio

  • By drew - Reply

    is it possible to program an atmega32 to an accurate clock such that one can control other functions without using an external timing chip

  • By paul - Reply

    Thank you very much man! you saved my sumo robot.
    Thanks!

  • By Samer - Reply

    @Avinash
    thank you for the very useful explantion.
    I have a question about my project on Butterfly board (using ATmega169): do you have any idea about the use of function Play_tune (this function come already installed on butterfly, but i have no idea about how to use is to generate tones on the attched piezo element).
    regards

  • By muhammad abo hegab - Reply

    thank you very much for this simple explanation

  • By Martin - Reply

    Hi, can you explain to me why pwm with zero dutycycle still has a small pulse? Why is it not really 0%?

    • By Avinash - Reply

      @Martin

      For 0% duty their is a clean low output. Their is no pulse at all!

  • By dcormier - Reply

    It would be nice if the “To be continued…” text at the end had been changed to a link to the next article for people like me who found this article through Google and want to read the next one.

    • By Avinash - Reply

      @dcormier

      Will be done shortly …

  • By Achut - Reply

    Thanks..!!
    Nice tutorial..it helped me a lot..:)

  • By Sam - Reply

    I have a better understanding of PWM now. Looking forward to the next tutorial where I could actually set up timer0 for PWM.

  • By jaspreet - Reply

    tooooooo gooodd and nice… got through in one go… no doubts.. xcept the programing part.. like the prescalars count etc…

    do u hv to use the specified pins OC1 necessarily… cant v use odr pins widout involving CPU??

  • By preeti - Reply

    hi sir…
    really a wonderful job by u… i wonder how i got the concepts well in my mind so soon by just single readng……. well thats all bcoz of u. gr8 job…. well i need a help from u… currently i am a enc final year student… i am working on brain machine interface as my final year project… so can u post me any of ur article on the same to preeti.toshniwal14@gmail.com ???? it would really be a great help from u… and one more help plzzzz ….. plzz help me in controlling of robotic arm …. the one i made has 7 servos in all… 5 normal and 2 mini… i will be waiting for ur reply…. do post it soon

  • Pingback: ATmega328 PWM | kevin's blog

  • By Ahmed Abo Elfadl - Reply

    Dear Sir
    thanks for your excellent explanation about the pulse width modulation , full respect .

  • By erdal - Reply

    Hi, thanks for atcile.
    I hvae a problem,
    atmega32 with four channel pwm output not working
    , How i do?

  • By deepak - Reply

    sir,
    could u plz help me to generate 2 pwm at a time having different period.

    • By Avinash - Reply

      @Deepak

      I will help you. I usually charge US$70 per hour. I think this would take 2 hours. Please pay my fees using Paypal. And I start your work.

  • By mohamed-el_miri - Reply

    Hi Avinash

    thanks for your excellent tutoriels; i have somme problems with PWM for servomotors

    elmiri mohamed
    Morocco

  • By peter kairu - Reply

    Hi sir, thanks for your tutorials they are very easy to understand since im learning how to programm AVR microcontrollers. I was going through you tutorial on servo motor control and in the sample code, i met this function:

    _delay_loop2(0);

    if i want to cycle a few times tor the servo to maintain a given position or angle, how does the function above work and how much time does it pass. does it pass the maximum time of 262.1ms for 1Mhz cpu clock?

  • By taiwofolu - Reply

    Again, thumbs up. I’m EXTREMELY impressed. Keep it up…

  • By su - Reply

    hey !! am doing a quadcopter using a stellaris ekclm4f232 microcontroller..have to program using sourcery code bench… can you help me in figuring out how to generate pwm signals for controlling the four motors of my quad using sourcery codebench ?

  • By Pappu Bag - Reply

    Thanks, It helps me to get the idea of using timers (though 32 bits) of Cortex M3 ARM, to generate PWM signals on GPIO pins.

  • By Ashu - Reply

    Hello Avinash Sir,

    I’m very new to embedded world but I love to make new things everytime. I know just basics of embedded system. will you help me whenever I need you. I have read my tutorials provided by you. i want to be your disciple. plz help me. Right now I’m studying about servo motors. bt not able to understand properly. plz help me.

  • By Yogesh kumar - Reply

    Hello Avinash this article is very usefull to clear basic concept about PWM.

    I started just doing embedded stuff and i am working on PWM charge controller,

    I am working on ATMEGA16 with the help of STK500 kit , i need some support
    plz would you help me to xplain about software side of charge controller project ,
    i learnt how to controll brightness of led by your article , now i want to know how can i make this fruitfull for charge controller .

  • By kamhagh - Reply

    keep up the good work! this is one of the finest tutorials i have ever seen!!!! but damn it too be continued :(( i gonna find some other tutorials! and if your website had more nice UI it would be great to like navigate trough tutorials!

  • By Prasath - Reply

    Bro,
    I’am workin on Atmega8,i need your help to get me through a coding for led brightness control using Atmega8.. Eagerly waitin fa your nxt tutorial..!!

  • By Gautam Datta - Reply

    d/S. We have required one pwm single phase generator.Pl contact as soon as possible.
    G Datta
    9051183655
    A D mechanics

  • By ardavan - Reply

    hi
    thanks for your help.
    i need to generate a pwm pulse train with a duty cycle of 30% at one cycle and 45% at the other.
    any ideas?

  • By Khalid - Reply

    Dear Avinash i need code to generate PWM with Atmel STK 600

  • By Suraj - Reply

    Hi Avinash,

    Thank you for the wonderful tutorials. In fast PWM mode i could generate time periods from the range of nano seconds to seconds. But for an application in need to exactly fire 25 PWM pulses of some time period. If i give a variable inside the while loop and increment it for 25 times and then stop the timer, will i exactly get 25 pulses or is there any other way to count the number of pulses using the code or the interrupt functions.

    Thank you in advance

  • Pingback: Penggunaan kursor untuk praktik Triac

Leave a Reply

Your email address will not be published. Required fields are marked *


− 2 = two

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>