Anda di halaman 1dari 9

A short introduction to PWM using PIC32MX250F128B

SYED TAHMID MAHBUB


www.tahmidmc.blogspot.com

PWM involves the generation of a (usually constant) frequency waveform. The waveform is
periodic with a frequency equal to the inverse of the time period:
=

The waveform consists of an amount of time where the signal is high (on time) and an amount
of time when the signal is low (off time).
= + = +
The ratio of the on-time to the period is known as the duty cycle:
=

The duty cycle is often expressed as a percentage:


=

100%

Why is this important? In short, this is used to control voltage/power in switching topologies.
For example, in a buck converter (step down switching regulator), the duty cycle dictates the output
voltage. You should expect there to be a feedback circuit which adjust the duty cycle to maintain the
output voltage with changing line (input voltage) and load.
For example, it is not uncommon to have a buck converter running at 100kHz. If you had a
constant input voltage of 10V and a duty cycle of 30%, you can expect an output voltage of 3V. This is of
course the output average voltage since the waveform is still pulses. You can convert this to a clean DC
level with an LC filter stage. If youre interested in this, look up buck converter or buck regulator in
Google.
PWM is used to control the speed of DC motors. For now Ill assume that there is no feedback.
So, the circuit will be operating open-loop (ie, no feedback). The duty cycle will control the speed of the
motor. Increasing the duty cycle will speed up the motor and vice versa. However, if you want to
maintain a constant RPM for example when loaded, youd want feedback circuitry. But open-loop will
also give a degree of speed control.

Page 1 of 9

Ill explore that now with the PIC32, specifically the PIC32MX250F128B.
To implement PWM in PIC32MX250F128B, youll use the Output Compare module in PWM
mode. The PIC32MX250F128B has 5 output compare modules, each of which can be used in multiple
modes such as single pulse generation, continuous pulse generation and PWM with and without fault
detection. Each of the Output Compare modules has a time base. All the Output Compare modules can
use Timer 2 or Timer 3 as 16-bit sources or Timer 2 and Timer 3 joint, as a 32-bit source.
A very nice feature here is that the PWM modules contains two duty-cycle registers the dutycycle register OCxR and a buffer register OCxRS. The real duty-cycle register is OCxR however you are
not allowed to modify its contents in PWM mode (except for specifying the initial duty cycle) OcxR is a
read-only register in PWM mode. You can write the value of duty-cycle in the OCxRS buffer register. The
value in this register is copied to the OCxR register (internally) whenever a period match occurs ie, at
the end of the time period. This allows glitch-free PWM operation.
The time period is set using the Timer period register PRx PR2 for Timer 2 and PR3 for Timer 3;
for the 32-bit Timer2/Timer3 combination PR2 sets the period register.
The Timers have configurable prescaler options: 1:1, 1:2, 1:4, 1:8, 1:16, 1:32, 1:64 and 1:256.
The period in PRx and the duty cycle in OCxRS are set in terms of Tpb cycles (peripheral bus
clock cycles). The prescaler allows the slowing down of the clock by the prescale factor.
So, for PWM:
= + 1 _
Where prescale_value is one of 1, 2, 4, 8, 16, 32, 64 and 256; Tpb is the period of the peripheral bus
clock and PRx is the period register.
Thus:
=

1
_

100%
+ 1

Page 2 of 9

From the datasheet, here are the registers for the Timer and the Output Compare modules:

Page 3 of 9

Page 4 of 9

Page 5 of 9

Output Compare modules 1 to 5 are all identical. Lets assume that for our purpose, were going
to use OC1 [Output Compare module 1] with Timer 2 as the time base. I want the frequency to be 10kHz
and the duty cycle to be 33%. Lets say the PIC32 is running off of a 40MHz clock and the PBCLK is also
40MHz.
Thus, we can set:
In OC1CON:

ON = 1 to turn output compare module 1 on.


SIDL doesnt matter now. Ill clear it to 0.
OC32 = 0 to select 16-bit time base
OCTSEL = 0 to select Timer 2 as the time base
OCM<2:0> = 110 to select PWM mode without fault protection

In T2CON:

ON = 1 to turn Timer 2 on you can also keep it off initially and turn it on later
SIDL = 0 doesnt matter now so I just cleared it
TGATE = 0 to disable Gated time accumulation
T32 = 0 to select 16-bit mode
TCS = 0 to select internal PBCLK
TCKPS<2:0> = 001 to select prescale value of 1:2

Set the period:


2 =

40
1 = 1999
10 2

Set the duty cycle:


1 = 0.33 2000 = 660
Now, the last thing is that you can change OC1RS anytime you want to change the duty cycle. If
OC1RS is greater than (PR2 + 1), duty cycle will be 100% (DC output). You can assign a value to OC1R at
the beginning of the code. However, this will be the initial duty cycle and the OC1R register becomes
read-only being updated only in hardware at the end of the period when the value in OC1RS is copied
to OC1R and used as the duty cycle value.
That was fairly simple. I assume you can easily do this yourself. So, Ill post an example of a
slightly more complicated (not too complicated though) example where you adjust the duty cycle by
adjusting a potentiometer. The duty cycle is displayed onto a three digit seven segment display.

Page 6 of 9

PICTURES:
(The oscilloscope is kinda crappy)
55% DUTY CYCLE

Page 7 of 9

80% DUTY CYCLE

Page 8 of 9

10% DUTY CYCLE

Page 9 of 9

Anda mungkin juga menyukai