Professional Documents
Culture Documents
Developed by:
Krishna Nand Gupta
Prashant Agrawal
Mayur Agarwal
PWM (pulse width Modulation)
What is PWM?
m
co
o.
ob
Frequency = (1/T)
R
Duty Cycle = (Thigh/T)
n
What is need of PWM?
io
IanswerthisinrespecttoourROBOThereyouarehaving300RPMmotorandvoltageratingis
12Voltsoifyouwanttorunmotorto150RPMthenwhatwillyoudo??Reducevoltageto6
is
voltbutthatsnotgoodideaRPMisnotlinearfunctionofvoltageandasvoltagedecreasefrom
specifiedratingTorquewillalsogetreduce.SoherecomePWMconceptwhatyoucandoisyou
.V
canswitchonandswitchoffthemotorrepetitivelysuchthateffectivelyyouget50%ONtimeif
youdoitreasonablyfastthenmotorseemsrunningcontinuous.
What do you exactly need? A constant time period square wave whose duty cycle we can
w
controlincode,right?
Clockperiodofamicrocontrolleris:
Tclk =1/(clock frequency)
~1~
E.g.InATmega8defaultclockfrequencyisnearabout1MegaHz.
Tsystem-clk=1/(1M Hz)=1 s
Togetdesirefrequencyyouneedtochangeclockingoftimerthatisdonebyprescalerso
m
ToimplementPWMthesevariablesarerequired:
co
TOP=NumberofclockcyclesforonetimeperiodofPWM
Nt=T/Tclk
OCR=NumberofclockcyclesforOnTimeofPWM
o.
OCR(outputcompareregister)
OCR=Ton/Tclk
Timer_value=Itisvalueoftimer,thatcountsfromTOPtozeroandZerotoTOPineach
ob
cycle.
** TocontrolDCmotorneeddualslopephasecorrectPWMthiscomplicatedterm
R
onlymeanthatcounterwillcountfromTOPtozeroandZerotoTOPintimeperiod.So
timeperiodof
n
Time period of the square wave is decided by 2 variables
io
Tclk
TOP
is
T= Tclk*TOP
or
.V
We adjust both variables to get desired time period by changing some control bits in control
w
registers.
HereinthistutorialwewillsetTOP=255
w
DutycycleisdecidedbyonlyonevariableOCR
Dutycycle=(OCR/TOP)
w
~2~
m
And if Timer_value < OCR then PWM Output=High
co
o.
TOP
Timer
ob
R
value
n
io
is
.V
w
w
w
~3~
m
co
o.
Youmustbewonderingwherewherewillthissqurewavewill
ob
appear.InavrmicrocontrollerthereiscertainPWMpinswhere
thesewavewillapear.LikeinATmega8PIN15,16and17.Ifyou
want to control only 2 DC motor then 15 and 16 pins are
sufficient.
R
Now suppose you want to generate a square wave that has
n
50%dutycycleatpin15(OC1A)Thenhowyourcodewilllooklike
Intmain()
io
{
Step1SetPB1(OC1A)asoutputpin;
Step2EnablePWM;
is
Step3SelectPhasecorrectPWMmodeandTOPvalue;
Step4SetOCRvalueTOP/2;
.V
Step5Setprescalervalueandclocksource;
Step6StartPWM;
While(1)
w
{
//doanyjobhere
w
}
Return0;
w
NowifyouconnectOscilloscopeatpin15youcanseeasquarewavewith50%dutycycle
~4~
YouhavelearntPWMjustcrazysyntaxpartofAVRPWMsettingisleft.
NOTE:forthesakeofsimplicityofthistutorialhereIwillconsideronlyphasecorrectPWMtolearnmore
aboutTimerandPWMgothroughdatasheetofATmega8
m
Timer/Counter 1 Control Register A TCCR1A
co
o.
ob
Bit 7:6 COM1A1:0: Compare Output Mode for channel A
Bit 5:4 COM1B1:0: Compare Output Mode for channel B
TheCOM1A1:0andCOM1B1:0controltheOutputComparePins(OC1AandOC1B(respectively)
R
behavior.IfoneorbothoftheCOM1A1:0bitsarewrittentoone,theOC1Aoutputoverrides
thenormalportfunctionalityoftheI/Opinitisconnected.SimilarlyforCOM1B1:0.However,
notethattheDataDirectionRegister(DDR)bitcorrespondingtotheOC1AorOC1Bpinmustbe
n
written1inordertoenabletheoutputdriver.
io
Compare Output Mode, Phase Correct and Phase and Frequency Correct PWM
is
.V
w
w
m
Bit 7, BIT 6, BIT5
ThesebitsisnotusedinPWMsimplywritethesebit0;
co
Bit 2:0 CS12:0: Clock Select
The three clock select bits select the clock source to be used by the Timer/Counter,
o.
ob
n R
io
is
Default No clock source is selected. as you select clock PWM will start
WGM stand for Wave generation mode. There are several PWM and time
mode here we want to do setting for phase correct PWM for TOP=255 and
for that you need to write
w
0 0 0 1
w
~6~
m
co
Output Compare Register 1 A OCR1AH and OCR1AL
o.
ob
R
Output Compare Register 1 B OCR1BH and OCR1BL
n
io
is
.V
w
w
w
~7~
m
Step3SelectPhasecorrectPWMmodeandTOPvalue;
Step4SetOCRvalueTOP/2;
co
Step5Setprescalervalueandclocksource;
Step6 StartPWM;
o.
While(1)
{
//doanyjobhere
ob
}
Return0;
}
R
Step1SetPB1(OC1A)asoutputpin;
Fordetailchecki/otutorial
n
Code:
DDRB|=(1<<PORTB1);
io
Step2EnablePWM;
For this you need to write COM1A10=0 and COM1A11=1
is
Code:
TCCR1A=0xA1;
.V
Step3SelectPhasecorrectPWMmodeandTOPvalue;
Here we will go for TOP=255
0 0 0 1
w
Step4SetOCRvalueTOP/2;
Code:
w
OCR1A=128;
Step5Setprescalervalueandclocksource;
Herewewillsetprescaler1024forthatweneedtowriteCS12=1,CS11=0,CS10=1
****FordetailseeClockSelectBit
~8~
Code:
TCCR1B=0x05;
Step6StartsPWM;
Step5willdothisjob
m
#include<avr/io.h>
intmain()
co
{
DDRB|=(1<<PORTB1);
TCCR1A=0xA1;
OCR1A=128;
o.
TCCR1B=0x05;
ob
While(1)
{
//anyjob
R
}
n
Return0;
}
io
YoucanalsocheckPWMwithmultimeterhereyouwillsevoltagechanginginmultimeterbutif
is
setsquarewavetimeperiodsufficientlow.youwillseeaveragevalueinmultimeter
.V
HAPPYPWMCODING
w
w
~9~