PWM for the PIC Microcontroller (or any microcontroller).
PWM (Pulse Width Modulation) is the term used to describe using a digital
signal to generate an analogue output signal. This is usually used to control
the average power to a load in a motor speed control circuit.
You can also use it to generate a contunuously variable analogue output without using any other integrated circuits by smoothing the PWM signal using a capacitor.
As well as saving the costs of extra chips and interfaces the Pulse Width Modulation signal will not drift over time since it is generated from the time base of the processor i.e. a quartz crystal.
Using analogue circuits to generate accurate signals that don't drift is a difficult task so PWM is very effective and cheap.
It works by changing the average voltage level and this is done by generating a constant frequency signal but one where the pulse width is changed (or modulated).
For a moment if you think of the digital signal when it is at its extremes i.e. normal - it generates the maximum of 5V when the output is high and the minimum of 0V when the output is low. If you want to generate a 2.5V signal then you need to make the signal on for half of the time and off for the rest and then take the average.
In the diagram the digital signal (solid line) is at a constant frequency while the pulse width is changed (modulated). The dotted line represents the average signal (if the digital signal is converted to an average). The duty cycle represents the amount of time that the signal is high compared to the amount of time that the signal is low.
So the top signal is high for 10% of the period so the average is low, the
middle signal is high for 50% of the period so the average is half and the
bottom signal is high for 90% of the period so the average is high. For fully
off you use 0% and fully on you use 100%.
So the duty cycle is independent of the frequency of the PWM signal and you'll always see the same type of waveform for a specific duty cycle.
The frequency of the PWM signal is important depending on the device you are
driving. If the aim is to create a dc signal then you would want the
frequency high (kHz) so a low pass filter could remove the frequency component.
How high depends on how much frequency component is allowed at output and
depends on how it is used i.e. what error can be tolerated.
To convert the PWM signal to a usable analogue signal you need to average
it and you can do this by using a resistor capacitor filter (low pass). The
higher the PWM frequency the less that frequency will come through the filter
so you can design out the PWM frequency from the analogue output.
Note: In some cases a filter is not needed as the filtering is done by the device you are controlling e.g. a motor (is inductive anyway). Or in the case of an RGB ledyour eye averages out the signal (persistence of vision)!
Since the PWM signal is fully digital the only way noise can affect it is if
the noise is strong enough to change a digital 1 to a digital 0 and vice versa.
This immunity is much higher than a purely analogue signal that will be
affected by any noise.
For this reason changing an analogue signal into a digital one can improve either the signal transmission distance or its immunity to spurious noise.
For example you could encode an audio signal into PWM, send it over longer cables than a pure analogue signal could travel, and then remove the PWM frequency at the receiver.
Projects using PWM techniques :
Note: that the RGB led link above uses a software PWM method as it needed three PWMoutputs and the 16F877 only has 2.
The PIC microcontrollers are very easy to use with PWM as they have built in
PWM generators - all you do is set up the relevant control registers
// Timer 2
PR2=199; // 4 MHz clock -> 5kHz PWM frequency
T2CON = (1<<TMR2ON);
// Initialize Control PWM
CCPR1L = 30; // Initial Duty
CCP1CON = 0x0f; // PWM mode set and 5,4 duty = 0
...and then control the duty cycle:
CCPR1L = j;
Note that the above control only controls the upper 8 bits of the 10 bit PWM module (the other two bits are in a CCP1CON).
Note the above code was taken from the C programming course.
P.S. One PIC 'gotcha' is that the duty cycle for the PIC microcontroller is not the generic duty cycle measured as a percentage rather it is the number of basic oscillator cycles for the output to remain high. So its related only to the master clock not to the period of the PWM signal!
12F675 OSCCAL Calibration: How to reprogram the OSCCAl value.
Arduino Battery Charger: A very useful project that lets you charge 'un-rechargeable' alkaline batteries!
The Essential Guide to the 74HC595; What it is and how you can easily use one in any of your projects.