Sorry late reply.
You can use the PWM module if you break up the 50 Hz (20 msec) period into multiple PWM 'frames' but you need a bit of ISR 'helper' code to setup each upcoming PWM 'frame'. Resulting 'helper' code is reasonably interrupt tolerant as you have up to almost 1000 usecs (in this example) to service the Timer 2 PWM 'frame' interrupt.
Not sure there's any advantage using the PWM mode this way instead of 'compare' or 'special event trigger' modes. All three modes require a bit of ISR code. You could however achieve much finer pulse width resolution using PWM mode if needed.
Mike
Code:
;******************************************************************
;
; // setup a 1000 usec PWM period with PR2 = 249 and prescaler
; // 4:1 (4 MHz clock) for 20 PWM 'frames' per 20 msec Servo
; // period and 1 usec pulse width resolution
;
; int servo = 1500; // pulse width in 1 usec ticks
; int pulse = 0; // ISR work variable
; int frame = 1; // frame number 1..20
;
; void ISR()
; { PIR1bits.TMR2IF = 0; // clear Timer 2 interrupt flag
; if (--frame == 0) // if end of the 20 msec period
; { frame = 20; // reset for new 20 msec period
; pulse = servo; // reset 'pulse' work variable
; }
; if ((pulse > 1000) // if pulse > 1000 usecs
; { CCPR1L = 250; // do a 100% duty cycle frame
; CCP1CONbits.CCP1Y = 0; //
; CCP1CONbits.CCP1X = 0; //
; pulse -= 1000; // subtract 1000 usecs
; }
; else
; { CCP1CONbits.CCP1Y = (pulse & 1);
; CCP1CONbits.CCP1X = (pulse & 2);
; CCPR1L = (pulse >> 2); // 0..249 (0..999 usecs)
; pulse = 0; // remaining frames are 0%
; }
; }