Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

CCP (compare mode)

Status
Not open for further replies.

crys

New Member
does anyone have a sample program in c language about CCP compare mode

PWM mode cant seem to generate a 50hz signal for the servo, i coulde get a minimum of 4.5ms period or lower

im using a PIC16f877a
 
If you look at this thread it has sample code to drive a servo. Although it is for the 18 series, it should work on the 16 series with slight modification.

Mike.
 
thanks!

got my simulation working, cant test it yet, i forgot to bring my power supply!

^_^
 
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%
;    }
;  }
 
Status
Not open for further replies.

Latest threads

Back
Top