CCP PWM vs PWM SW with interrupts

Page: 123 > Showing page 1 of 3
Author
luigi.malago
Starting Member
  • Total Posts : 34
  • Reward points : 0
  • Joined: 2006/08/16 04:24:04
  • Location: 0
  • Status: offline
2006/10/09 17:01:37 (permalink)
0

CCP PWM vs PWM SW with interrupts

Hello!
I'm dealing with servo controlling and i have to generate a PWM wave with 20ms period.
I cannot use the CCP directly because of the low frequency. So i hav to find other solutions:

Many told me to use a timer, and implement the square wave using interrupts without CCP, using a normal pin.
I need only 1 timers, but some other people told me that this solution generates waves that can be affected by jitter.
I'm not sure about that, that's why i'm asking you.

Another fancy solution seems to use CCP and 1 timer. The idea is to divide the PWM period required by the servo into
several real PWM cycles generate by CCP, and using timers and couting the cycles, varying the duty cicle in order to "compose"
the PWM wave. (First cycles have duty cycle 100%, last cycles have duty cycles 0%)
This seems to be a little more complicated to be implemented, i need timer2 and CCP.
Maybe the fact that i use PWM as output can be better then using a normal pin.

Since i'm new to PIC programming i'd like to ask your opinion.

Thanks a lot.
Luigi

#1

50 Replies Related Threads

    tunelabguy
    Super Member
    • Total Posts : 1639
    • Reward points : 0
    • Joined: 2005/04/03 08:30:19
    • Location: Hopkins, MN USA
    • Status: offline
    RE: CCP PWM vs PWM SW with interrupts 2006/10/10 13:27:34 (permalink)
    0
    PWM mode is only one way to use the CCP. You can also use the CCP in Output Compare mode. This mode is more flexible then PWM mode for generating low-frequency signals, including PWM signals. But it requires more processor attention to every cycle. PWM mode is a set-it-and-forget-it mode and can be done with no on-going processor attention. But if you need to do something that standard PWM mode does not allow, then you might as well spend the time and learn about Output Compare mode. Basically what you need to do is plan for every transition and set up the compare registers before each transition. One problem that Output Compare mode has is for extremely low or high duty-cycles. If you need the software to get involved between every two transtions, then that sets a lower limit on how close transitions can be. But if you are looking for a 20 msec. period, I think you can achieve any reasonable duty cycle using Output Compare mode. If you really need to push it, you can handle the extremely short pulses as special cases in software - perhaps with instruction cycle timing.

    Robert Scott
    Real-Time Specialties
    #2
    luigi.malago
    Starting Member
    • Total Posts : 34
    • Reward points : 0
    • Joined: 2006/08/16 04:24:04
    • Location: 0
    • Status: offline
    RE: CCP PWM vs PWM SW with interrupts 2006/10/10 17:53:32 (permalink)
    0
    Hi tunelabguy,
    i'm a little bit confused, the solution you are mentioninig (CCP in Compare Mode + timer1) is the same as the first solution i mentioned, i mean using a regular output pin to generate the PWM wave?


    Many told me to use a timer, and implement the square wave using interrupts without CCP, using a normal pin.
    I need only 1 timers, but some other people told me that this solution generates waves that can be affected by jitter.
    I'm not sure about that, that's why i'm asking you.


    thanks a lot,
    Luigi

    #3
    dgiudici
    Starting Member
    • Total Posts : 33
    • Reward points : 0
    • Joined: 2006/06/03 01:30:35
    • Location: 0
    • Status: offline
    RE: CCP PWM vs PWM SW with interrupts 2006/10/13 22:00:57 (permalink)
    0
    A more basic solution that requires a bit of calculations is to have it with one timer.
    The pic 18f452 to has the ability to interupt on timer overflow. With this you can reset the count which it counts up to before it interupts again, and at each time it interupts you can change the state of your output pin.

    SO...for a 25 percent duty cycle

    program is running

    interupt after 10 ms (for example)
        set output pin high
        reset timer to interupt in 5 ms
    will now interupt after that 5 ms
        set output pin low
        reset time to interupt in 15 ms
    will now interupt after that 15 ms
        set output pin high again...
    etc
    etc

    what you can then do once you have that all done up you can reset the timer based off of some global parameter that you can change in the non interupt part of your code, making your duty cycle able to be controlled.

    I hope this helped

    Cheers

    DG
    #4
    K8LH
    Super Member
    • Total Posts : 1867
    • Reward points : 0
    • Joined: 2004/03/26 05:12:34
    • Location: Michigan, USA
    • Status: offline
    RE: CCP PWM vs PWM SW with interrupts 2006/10/14 14:17:21 (permalink)
    0
    Luigi,

    You could try CCP "compare" mode and a simple interrupt routine.  Your Main program would simply modify the Pulse variable when required and the interrupt driver would do the rest in the background.  Here's a C18 example;

    /*                                                               *
      *  set Pulse to some value between 600 and 2400 (usecs)         *
      *                                                               *
      *  TMR1 prescaler is 2:1 for 1-usec 'ticks' (8-MHz clock)       *
      *                                                               */

    unsigned int Pulse  =  1500;            // 1-usec TMR1 'ticks'

    /*****************************************************************
      *  setup interrupt vectors                                      *
      *****************************************************************/
    #pragma code high_interrupt = 0x08
    void high_interrupt (void)
    { _asm goto isr_hi _endasm
    }

    #pragma code
    /*****************************************************************
      *  K8LH CCP "compare" HiRez Servo Algorithm Interrupt Driver    *
      *****************************************************************/
    #pragma interrupt isr_hi

    void isr_hi ()
    { if (PIR1bits.CCP1IF == 1)             // if CCP1 interrupt
       { if (CCP1CONbits.CCP1M0 == 0)        // if CCP1 is 'hi'
         { CCPR1 += Pulse;                   // setup Pulse "on time"
           CCP1CONbits.CCP1M0 = 1;           // go 'lo' next interrupt
         }
         else                                // if CCP1 is 'lo'
         { CCPR1 += (20000-Pulse);           // setup Pulse "off time"
           CCP1CONbits.CCP1M0 = 0;           // go 'hi' next interrupt
         }
         PIR1bits.CCP1IF = 0;                // clr CCP1 interrupt flag
       }
    }
    post edited by K8LH - 2007/05/27 03:23:06
    #5
    luigi.malago
    Starting Member
    • Total Posts : 34
    • Reward points : 0
    • Joined: 2006/08/16 04:24:04
    • Location: 0
    • Status: offline
    RE: CCP PWM vs PWM SW with interrupts 2006/10/16 11:54:56 (permalink)
    0
    thanks dgiudici and K8LH, i got what you mean,

    @ K8LH:
    maybe a didnt get the point, but are you suggesting to use CCP "compare" ( RC2/CCP1 pin) instead of set and reser a normal pin?
    if yes, can you explain me the reasons?


    thanks a lot,
    Luigi
    #6
    K8LH
    Super Member
    • Total Posts : 1867
    • Reward points : 0
    • Joined: 2004/03/26 05:12:34
    • Location: Michigan, USA
    • Status: offline
    RE: CCP PWM vs PWM SW with interrupts 2006/10/16 14:20:07 (permalink)
    0
    Hi Luigi,

    Several advantages for using the CCP module "compare" mode for generating a Servo pulse are;

    (1) Unlike PWM module, the CCP module "compare" mode can easily provide a 20-msec period.
    (2) It's relatively easy to provide a very high resolution Pulse width.
    (3) There will be no jitter on the CCP1 output pin.

    Mike
    #7
    luigi.malago
    Starting Member
    • Total Posts : 34
    • Reward points : 0
    • Joined: 2006/08/16 04:24:04
    • Location: 0
    • Status: offline
    RE: CCP PWM vs PWM SW with interrupts 2006/10/16 16:50:01 (permalink)
    0
    Thanks K8LH, these are the kind of informations i'd like to learn about..

    ORIGINAL: K8LH
    Several advantages for using the CCP module "compare" mode for generating a Servo pulse are;
    (1) Unlike PWM module, the CCP module "compare" mode can easily provide a 20-msec period.


    Ok, so far so good. I know that i can't get 20msec perdiod with my 20Mhz, and that's why i started this thread.
    As a matter of fact i'm interested in comparing CCP module, CCP PWM and software interrupts with timer and a normal pin as output
    Point 1 is not about CCP compare VS software interrupts suggested (for example) by dgiudici.
    Correct my if i'm wrong.

    ORIGINAL: K8LH
    (2) It's relatively easy to provide a very high resolution Pulse width.

    Isn't it as easy as using interrupts with a normal pin?


    ORIGINAL: K8LH
    (3) There will be no jitter on the CCP1 output pin.

    This point is very important... what do you mean exactly by jitter? Does it affect "when" the trasition takes place (phase) or does it affect the amplitude (unwanted oscillations)?
    Can you tell me where i can find more information about this event as to PIC (in both pins and CCP1).
    This is the difference i'd like to explore more..

    Thanks again for joining the discussion.

    Luigi
    post edited by luigi.malago - 2006/10/17 06:29:35
    #8
    K8LH
    Super Member
    • Total Posts : 1867
    • Reward points : 0
    • Joined: 2004/03/26 05:12:34
    • Location: Michigan, USA
    • Status: offline
    RE: CCP PWM vs PWM SW with interrupts 2006/10/16 17:10:48 (permalink)
    0
    ORIGINAL: luigi.malago

    Thanks K8LH, these are the kind of informations i'd like to learn about..

    ORIGINAL: K8LH
    Several advantages for using the CCP module "compare" mode for generating a Servo pulse are;
    (1) Unlike PWM module, the CCP module "compare" mode can easily provide a 20-msec period.


    Ok, so far so good. I know that i can't get 20msec perdiod with my 20Mhz, and that's why i started this thread.
    As a matter of fact i'm interested in comparing CCP module, CCP PWM and software interrupts with timer and a normal pin as output
    Point 1 is not about CCP compare VS software interrupts suggested (for example) by dgiudici.
    Correct my if i'm wrong.

    You're correct, I was comparing CCP "compare" to CCP "pwm".  You can use timer interrupt code and a normal pin to achieve a good servo pulse and a 20.0-msec period.

    ORIGINAL: K8LH
    (2) It's relatively easy to provide a very high resolution Pulse width.

    Isn't it as easy as using interrupts with a normal pin?

    Yes, you should be able to get very good resolution using timer interrupt code and a normal pin.

    ORIGINAL: K8LH
    (3) There will be no jitter on the CCP1 output pin.

    This point is very important... what do you mena exactly by jitter? Does it affect "when" the trasition takes place (pahse) or does it affect the amplitude (unwanted oscillations)?
    Can you tell me where i can find more information about this event as to PIC (in both pins and CCP1).
    This is the difference i'd like to explore more..

    I understand jitter to be an unwanted variation of the pulse width.  You should be able to come up with timer interrupt code using a normal pin that only has a one cycle variation.  That's 200.0-nsecs with a 20.0-MHz clock.  I suspect that small amount of jitter wouldn't be a problem.

    Not sure where to direct you for Servo research.  Sorry.

    Mike
    #9
    luigi.malago
    Starting Member
    • Total Posts : 34
    • Reward points : 0
    • Joined: 2006/08/16 04:24:04
    • Location: 0
    • Status: offline
    RE: CCP PWM vs PWM SW with interrupts 2006/10/17 06:43:29 (permalink)
    0
    ORIGINAL: K8LH
    I understand jitter to be an unwanted variation of the pulse width. You should be able to come up with timer interrupt code using a normal pin that only has a one cycle variation. That's 200.0-nsecs with a 20.0-MHz clock. I suspect that small amount of jitter wouldn't be a problem.


    Just one more question: so why do you say that using CCP1 there wil be not jitter? As far as i know jitter can be caused in software based PWM when the routine interrupt that
    changes the value of the pin is delayed (for example when another interrupt is being handled). You say that using CCP1 there will be no jitter

    As to what i understood, the CCP1 pin will be set/reset or will remain unchanged OUTSIDE of the ruotine interrupt reised by CCP1IF, so no more delays...
    As a matter of fact i need the CCPIF1F interrupt to be handled since i have to leave timer1 untouched, but on the other hand i have to change the next value (when CPP1 will change state, for example if first i set it, next CCP-compare match i will now i have to unset it) so in this routine i have to change the setting of the compare module.

    Am i right?

    Luigi
    #10
    tunelabguy
    Super Member
    • Total Posts : 1639
    • Reward points : 0
    • Joined: 2005/04/03 08:30:19
    • Location: Hopkins, MN USA
    • Status: offline
    RE: CCP PWM vs PWM SW with interrupts 2006/10/17 08:46:23 (permalink)
    0
    If the interrupt routine has to set the output pin, then the exact time when that pin in set can have some jitter, unless there are no other interrupts in the system and interrupts are never disabled. The amount of jitter depends on how long interrupts are disabled.

    If the CCP interrupt is configured to change the state of the associated CCP pin on Compare, then the timing of that transition has no jitter - it does not depend on when the interrupt is serviced.

    With clever re-configuring of the CCP mode on each Compare it is possible to generate arbitrarily long pulses with no jitter. So yes, you are right if you intend to let the CCP module produce all the transitions by continually re-configuring the mode and resetting the Compare register. It works fine that way.

    Robert Scott
    Real-Time Specialties
    #11
    luigi.malago
    Starting Member
    • Total Posts : 34
    • Reward points : 0
    • Joined: 2006/08/16 04:24:04
    • Location: 0
    • Status: offline
    RE: CCP PWM vs PWM SW with interrupts 2006/10/17 10:43:14 (permalink)
    0
    ok, i think now i have the point of the question.

    thanks again to everybody
    Luigi
    #12
    B_A_D
    New Member
    • Total Posts : 1
    • Reward points : 0
    • Joined: 2006/10/24 00:38:58
    • Location: 0
    • Status: offline
    RE: CCP PWM vs PWM SW with interrupts 2006/10/24 00:43:18 (permalink)
    0
    Nice code.
    Is there any possibility to control 2 servos simultaneously using only one CCP module ?
    Thanks.

    #13
    luigi.malago
    Starting Member
    • Total Posts : 34
    • Reward points : 0
    • Joined: 2006/08/16 04:24:04
    • Location: 0
    • Status: offline
    RE: CCP PWM vs PWM SW with interrupts 2006/10/30 18:16:43 (permalink)
    0
    You cant if you want to use CCP compare and "set on match" and "clear on match" (that's to say the adavantage of using CCP compare without delays in serving software interrupt)

    You can in you use CCP compare to generate interrupts and then handle pin values inside the routine (this means that you are not sure when the pin is enabled/disabled if you have other interrupts around)

    You can use a hybrid solution, one CCP with set and clear on match for one servo and generate PWM woth the same timer1 for the other servo.
    Of course you have to do some math to deterime all the intervals bewteen interrupts provided the two pwm duty cycles

    Luigi

    #14
    K8LH
    Super Member
    • Total Posts : 1867
    • Reward points : 0
    • Joined: 2004/03/26 05:12:34
    • Location: Michigan, USA
    • Status: offline
    RE: CCP PWM vs PWM SW with interrupts 2006/11/05 01:28:14 (permalink)
    0
    Ok, here's an untested example driver for 8 channels on PORTB.  As stated earlier in the thread this solution may exhibit one or two instruction cycle pulse width jitter and interrupts should not be disabled.  Other interrupt processing if required should be performed at the low priority vector.

    Your Main program simply sets the Pulse[0] through Pulse[7] array elements with values from 1000 to 2000 (usecs) or extended values from 600 to 2400 (usecs).  Pulse[0] is output on RB0, Pulse[1] is output on RB1, and so on through Pulse[7] which is output on RB7.  Pulse[8] is the end-of-period off time (20000 usecs minus the Pulse[0] through Pulse[7] on time values) where the Servo variable (and PORTB) = '00000000'.

    I'd love to hear back from anyone who might be able to test this example driver.  Please remember Timer 1 prescaler should be setup for 1.0-usec 'ticks' with whatever oscillator frequency you're using.

    Regards, Mike

    static unsigned char n = 0;
    static unsigned int Pulse [] = { 1500, 1500, 1500, 1500,
                                      1500, 1500, 1500, 1500,
                                      20000 };
    static unsigned char Servo = 1;

    /*****************************************************************
      *  setup interrupt vectors                                      *
      *****************************************************************/

    #pragma code hi_interrupt = 0x08

      void hi_interrupt (void)
      { _asm goto isr_hi _endasm
      }

    #pragma code

    /*****************************************************************
      *  ISR (high)                                                   *
      *****************************************************************/
    #pragma interrupt isr_hi

    void isr_hi ()
    {
      /****************************************************************
       *  K8LH Crazy-8 Hi-Rez Soft 8-channel (PORTB) Servo Algorithm  *
       ****************************************************************/
       if (PIR1bits.CCP1IF == 1)     // if CCP1 "compare" interrupt
       { LATB = Servo;               // output new Servo pulse and
         CCPR1 += Pulse[n];          // setup next "compare" value

         PIR1bits.CCP1IF = 0;        // clear CCP1 interrupt flag

         Pulse[8] -= Pulse[n++];     // adjust end-of-cycle off time
         Servo <<= 1;                // and prep for next channel

         if (n == 9)                 // if end of a 20-msec cycle
         { n = 0;                    // reset array index
           Pulse[8] = 20000;         // reset the 20.0-msec period
           Servo++;                  // reset Servo shadow to Servo 1
         }
       }
    }
    post edited by K8LH - 2007/05/27 03:30:19
    #15
    shami81
    New Member
    • Total Posts : 5
    • Reward points : 0
    • Joined: 2006/09/20 20:45:39
    • Location: 0
    • Status: offline
    RE: CCP PWM vs PWM SW with interrupts 2006/11/13 23:26:49 (permalink)
    0
    hi there, i like the solution of using ccp module in compare mode rather than pwm mode. But the problem is that i am using CCS c compiler so the syntax of the program will be a bit different can any one please tell me how to write a program for this PWM control application. I want to control the speed and direction of a DC motor by using a pwm of 20KHz. I want to use pic16F877 so please help me in this regard.
    thanks in advance to all who reply this.

    Engineering is the art of making things with the things you can get.

    Ehtisham.
    #16
    tunelabguy
    Super Member
    • Total Posts : 1639
    • Reward points : 0
    • Joined: 2005/04/03 08:30:19
    • Location: Hopkins, MN USA
    • Status: offline
    RE: CCP PWM vs PWM SW with interrupts 2006/11/14 07:36:15 (permalink)
    0

    ORIGINAL: shami81

    hi there, i like the solution of using ccp module in compare mode rather than pwm mode. But the problem is that i am using CCS c compiler so the syntax of the program will be a bit different...


    I can’t tell you exactly how to proceed because I don’t know what your performance requirements are. For example, what control resolution do you need? Can you tolerate a few instruction cycles of jitter in a software-controlled implementation? Do you need to approach 0% and 100% duty cycle? If so, how close? What is the PWM frequency?

    Of all the problems associated with Output Compare controlled PWM, I have found the most difficult to be the problem of approaching 0% and 100% duty cycle (This is not a problem if you use the PWM mode of the CCP). It is easy to control a mid-range duty cycle because after each event, the software has plenty of time to set up for the next event. But for very short pulses (duty cycle approaching 0%), the pulse width may be shorter than the needed setup time. What I have done to handle this problem is divided up the duty cycle range into special cases. For the mid-range duty cycle, I let each instance of the ISR perform one output transition. For pulse widths shorter than a certain threshold, I produce the entire pulse (2 transitions) within one ISR by using instruction timing (busy-waiting) to produce the pulse. This busy-waiting is itself divided into special cases. The longest of these short pulses are produced by a wait loop. For pulses down to 9 instruction times I use a computed goto jumping over no-ops. The very shortest pulse widths are handled each by their own code, right down to one instruction cycle (bsf followed immediately by bcf). Of course if you use that method you must ensure that your use of the rest of that I/O port is not going to be hurt by the read-modify-write problem, which has been discussed to great length in this forum. If you want to avoid bcf and bsf directly on I/O ports, than you can use shadow RAM and still make pulses that are down to 2 instruction cycles. To achieve these kinds of results you will have to use at least a little bit of assembly language programming, which is not too hard to do with the CCS compiler.

    Robert Scott
    Real-Time Specialties
    #17
    stagestar
    New Member
    • Total Posts : 6
    • Reward points : 0
    • Joined: 2006/12/07 07:04:51
    • Location: 0
    • Status: offline
    RE: CCP PWM vs PWM SW with interrupts 2006/12/08 02:49:54 (permalink)
    0
    I have the same problem, I am using CCS in PIC C and pic16F877.
     
    "I can’t tell you exactly how to proceed because I don’t know what your performance requirements are. For example, what control resolution do you need? Can you tolerate a few instruction cycles of jitter in a software-controlled implementation? Do you need to approach 0% and 100% duty cycle? If so, how close? What is the PWM frequency?"
     
    I just need to generate a square wave of 20 ms PWM period and 1 ms duty cycle (fixed).
    Should I use CCP1 and reset timer1 in the INTERRUPT FUNCTION or in the external code?
     
    Thanks.
    #18
    tunelabguy
    Super Member
    • Total Posts : 1639
    • Reward points : 0
    • Joined: 2005/04/03 08:30:19
    • Location: Hopkins, MN USA
    • Status: offline
    RE: CCP PWM vs PWM SW with interrupts 2006/12/08 06:07:22 (permalink)
    0
    ORIGINAL: stagestar
    I have the same problem, I am using CCS in PIC C and pic16F877.

    I just need to generate a square wave of 20 ms PWM period and 1 ms duty cycle (fixed).
    Should I use CCP1 and reset timer1 in the INTERRUPT FUNCTION or in the external code?
    Thanks.


    You don't ever need to reset the Timer1. Just leave it free-running. You can just keep track of the last CCP Compare value and construct the next CCP Compare value by adding a certain offset to it. That offset is your desired time until the next Compare event. It will be either 1 msec or 19 msec., depending. You can continue this way indefinitely, right throught the wrap-around of the Timer1.

    Robert Scott
    Real-Time Specialties
    #19
    future56k
    Senior Member
    • Total Posts : 160
    • Reward points : 0
    • Status: offline
    RE: CCP PWM vs PWM SW with interrupts 2006/12/25 18:34:30 (permalink)
    0
    K8LH:

    Hi,

    This method is the best I've ever seen for non overlaping pulses. Do you know any way to work around this and have them overlaped?

    Thank you.

    #20
    Page: 123 > Showing page 1 of 3
    Jump to:
    © 2014 APG vNext Commercial Version 4.5