LabC4 Pulse Width Modulation
LabC4 Pulse Width Modulation
Pulse-width modulation (PWM) uses a rectangular pulse wave whose pulse width is
modulated resulting in the variation of the average value of the waveform.
The PWM carrier (see figure) has a time-base (period) and the time that the output
stays high (duty cycle).
We shall use the 16F877A to generate a PWM carrier making use of the PWM mode
of the Capture and Compare module (CCM) . The CCM1 module (the 16F877A has
two CCMs) can be configured to provide a PWM output on the pin RC2. In this mode
it generates up to a 10-bit resolution PWM carrier, the period of which is determined
by the value in PR2, the Timer2 module’s period register. The value of the PWM
period is given by
CCPR1L:CCP1CON,5:4>
Although the registers CCPR1L and CCP1CON,<5:4> can be written to at all times,
the new Duty Cycle value will not take effect until the start of the next period. A new
period starts with Timer2 counter being reset to zero. This forces the output pin of
the CCM1 high and latches the value of the Duty Cycle. When the Timer 2 16-bit
counter reaches the value stored in the PR2 register the cycle ends. The Timer2
counter is automatically cleared and if the output pin is still high it will be re-set.
1
P. Klimo Jan 2012
The average of the PWM carrier represents an analogue voltage of the binary
modulation signal. Thus in order to implement a DAC, the PWM waveform needs to
be passed through a low pass filter. This removes the components of the high
frequency carrier leaving only the low frequency modulation signal.
Consider an example where we wish to implement DAC on an 8-bit signal that has a
bandwidth from 0Hz to 1000Hz. According to the Nyquist we need to select filter’s
stop band at twice the highest signal component i.e. 2kHz. A first order RC Low Pass
filter will provide a 6dB/octave roll off. Now choose a PWM carrier frequency of 30
kHz. The RC filter will suppress the high frequency components by (30000/2000)x 6
dB = 90 dB which is a factor of about 16.
PR2 = Fosc/(4FPWM ) -1 = 66
but choose 64 as the nearest power of 2. Given the 8 bit signal value S we can apply
a duty cycle:
This means that only the six most significant bits of S are taken into account. Thus
the values of the two bits in the CCP1CON,<5:4> are zero and
CCPR1L = ¼ S
Code Development.
We now proceed to develop the code. The PWM mode initialization is done in the
function PWM_init:
void PWM_init(void){
TRISC &= ~0b00000100; // RC2 is CCM1 output
PR2 = 64; // Set the PWM period as 32.5 uS (30.8KHz)
T2CON = 0b000000100; // Enable Timer2 with Pre-scale=1, (no post-scale)
CCP1CON =0b000001100; // Turn the PWM mode on
}
void main(void){
PWM_init();
CCPR1L = value >>2; // Divide by 4 to set the Duty Cycle
while(1){;}
}
2
P. Klimo Jan 2012
Using a 1kHz PWM carrier, implement a DAC on a 10 bit binary value stored as a
variable in the Data Memory. Then design a suitable RC low pass filter to extract the
average value of the PWM carrier.
• Write a test program enabling you to change the binary value whilst the
program is running.
• Connect the RC2 pin to an oscilloscope and observe the waveform obtained.
Estimate the amplitude of the “ripple” superimposed on the DC level.
• Connect a DC voltmeter to the RC2 pin and plot the measured voltage values
against a range of binary values between 0 and 1024. Calculate the accuracy
in terms of standard and maximum deviation. Explain your findings.
Use the PWM module to generate a 100 Hz sinewave with 8 bit resolution with 20
values per period. Use a suitable Low Pass filter to remove high frequency
components.