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).
- Fast PWM
- 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
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).
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.
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.
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
@ AM
You are Welcome!
Right now I do not have that kind of I2C code. 🙁 Sorry
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
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?
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
Hello Percy,
🙂 Nice to meet you !
Enjoy .
And If you need any help do ask me. 😉
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
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
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 !!! 🙂
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.
In phase correct PWM the Counter goes from 0 – 255 and then from 255 to 0 (in fast PWM it becomes 0 after 255)
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
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 ..
@ 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.
Hi,
Thanks for your very helpful tutorials.
Where is the continuation of the above Tut.?
thanks
Cy
can u mail me d link to d next tutorial…….n keep up ur gd work
….thanks
@Curious
link to next article is
https://extremeelectronics.co.in/avr-tutorials/pwm-signal-generation-by-using-avr-timers-part-ii/
Hi..
Thanks for the PWM concepts.
can you give some explanation about Optocouplers?
How exactly it behaves as a isolator in electronic circuit.
Superb Explanation!!! Avinash great!!! Keep it up!!!
You are really Brilliant!!!
Belated Happy Birthday Wishes!!!
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 🙂
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
thanks again for this tutorial
thanks nice work
you helped us thats great
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
i lyk the explanation ………specially animated partnow its vry easy 2 write a code
sir,
please publish article on servo motor control with delay and timers
@sudarshan
Yes , sure. Let me finish some other article first.
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?
@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.
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
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
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
@Harish
For servo control see
https://extremeelectronics.co.in/avr-tutorials/servo-motor-control-by-using-avr-atmega32-microcontroller/
@ avinash
ho thanks but i need it by using avr atmega8 and can u guide us how to debug codevisionavr code using avr studio
is it possible to program an atmega32 to an accurate clock such that one can control other functions without using an external timing chip
Thank you very much man! you saved my sumo robot.
Thanks!
@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
thank you very much for this simple explanation
Hi, can you explain to me why pwm with zero dutycycle still has a small pulse? Why is it not really 0%?
@Martin
For 0% duty their is a clean low output. Their is no pulse at all!
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.
@dcormier
Will be done shortly …
Thanks..!!
Nice tutorial..it helped me a lot..:)
I have a better understanding of PWM now. Looking forward to the next tutorial where I could actually set up timer0 for PWM.
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??
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
Dear Sir
thanks for your excellent explanation about the pulse width modulation , full respect .
Hi, thanks for atcile.
I hvae a problem,
atmega32 with four channel pwm output not working
, How i do?
sir,
could u plz help me to generate 2 pwm at a time having different period.
@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.
Hi Avinash
thanks for your excellent tutoriels; i have somme problems with PWM for servomotors
elmiri mohamed
Morocco
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?
Again, thumbs up. I’m EXTREMELY impressed. Keep it up…
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 ?
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.
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.
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 .
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!
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..!!
d/S. We have required one pwm single phase generator.Pl contact as soon as possible.
G Datta
9051183655
A D mechanics
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?
Dear Avinash i need code to generate PWM with Atmel STK 600
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