Pulse Width Modulation (PWM) Output
PWM fakes an in-between voltage by switching a pin on and off very quickly. It's how microcontrollers dim LEDs and control motor speed without a true analog output.
A GPIO pin can only be fully on or fully off — there's no register setting for "half voltage." Pulse Width Modulation (PWM) works around that limit by switching the pin on and off rapidly, many thousands of times per second, and varying the proportion of time it spends on versus off. To anything with some inertia — an LED and your eye, a motor and its armature, a filter capacitor — that rapid switching averages out to feel like a genuine in-between voltage.
The proportion of time a PWM signal spends high is called its duty cycle, usually expressed as a percentage. A 25% duty cycle spends one quarter of each cycle high and three quarters low; a 75% duty cycle is the reverse. An LED driven at 25% duty cycle looks noticeably dimmer than one at 75%, even though both are, at any single instant, either fully on or fully off.
Most PIC chips include a dedicated PWM peripheral that generates this switching in hardware, without any CPU involvement once configured — you set a frequency and a duty cycle in a couple of registers, and the pin toggles on its own from then on, freeing the CPU entirely.
void main(void) {
TRISC2 = 0; // PWM output pin as output
PR2 = 249; // sets PWM frequency
T2CON = 0b00000100; // enable Timer2 (drives PWM)
CCP1CON = 0b00001100; // enable PWM mode
while(1) {
for (unsigned int duty = 0; duty < 1000; duty++) {
CCPR1L = duty >> 2; // raise duty cycle: LED brightens
__delay_ms(3);
}
}
}