16F Digital To Analogue Conversion Example
PWM, pulse wave modulation, is a
feature of some PIC's. Even PIC's without PWM can use a software
version of PWM, but the advantage
of having
hardware
PWM is that you don't have to
update the PWM cycle at all.
In a software PWM situation, you must continuously refresh the PWM
signal on the desired pin, and loose a lot of functionality with the
program. The 16F877 features a few HPWM outputs, and can be used for
many things (i.e. IR modulation), but in this example, its used for
DAC.
HPWM is a pulse train that a user can specify its frequency
and duty cycle. Duty cycle is the percentage of time that the
pulse stays high compared to the time it stays low. So a duty cycle
of 50% means it stays high for 50% of the time, and low for 50% of
the time. A duty cycle of 25% means the pulse is high for 25% of the
time, and low for 75% of the time.
50%
duty cycle (freq = 2Khz);

25%
duty cycle (freq = 2Khz);

No matter what the frequency, the duty cycle will be the same, just
that the pulses will be more squished / stretched. There are limits
with the frequency of the PWM, they are
XTAL frequency - Lowest useable PWM frequency
4MHz - 244Hz
8MHz - 489Hz
10MHz - 611Hz
12MHz - 733Hz
16MHz - 977Hz
20MHz - 1221Hz
24MHz - 1465Hz
33MHz - 2015Hz
40MHz - 2442Hz
And with all XTAL speeds, the fastest possible frequency is
32767Hz. So there are limitations with the PWM in regards to
the frequency that it can produce. The faster the frequency, the
better for this application, as it increases the outputs response.
The duty cycle is a value between 0 and 255 where 0 is 0% and
255 is 100%, i.e. a duty cycle of 63 would actually mean 25%
as 63 / 255 = .25 (25%). The RC circuit will average the pulses out
and turn them into near solid DC, a 50%(127) duty cycle will read as
2.5V, and a 25%(63) would read 1.25V. And this is how DAC is
performed with the PIC.
The
command in Proton+ is
HPWM Channel , Dutycycle , Frequency
As it so turns out, the channels on the 16F877 are CCP1 and CCP2,
but CCP1 is on PORTC.2 and CCP2 is on PORTC.1.. I have no idea why,
but you can declare the pins into what would seem the correct format
like so,
Declare CCP1_PIN = PORTC.1
Declare CCP2_PIN = PORTC.2
I'm using 1 channel for this example, and a simple RC circuit that
will average the PWM signal and turn it into a rather constant
analogue output. The op-amp is not required for all applications,
but it definitely is good practice to use it as a
buffer. The
frequency should always be on max, i.e. 32767Hz for DAC, a
lower frequency will make the output appear laggy / have a long
response time.
The following diagram is with a duty cycle of 25% (63) and a
frequency of 32767Hz on channel 1 (CCP1) eg: HPWM
1,
63,
32767 With a duty cycle of 25%, the output
will be 25% of 5V, or 1.25V. Note the
PSU/OSC are not shown.
Note the PIC's power supply/oscillator are not shown
The capacitor and RC will act as a filter, and slew the pulses
together, giving the impression of a stable output. On an
oscilloscope the ripple is clear, but in reality, to small to be of
any concern. Any duty cycle between 0 and 255 can will be converted
to 0-5V in this format.
Where you can get
the components;

 | Site Tutorial Index |
|  | 16F PIC Examples |
| |  | Motors |
| |  | Thermometers |
| |  | Code Snippets |
|  | 18F PIC Examples |
|  | Handy Tips |