• AVR Freaks

Hot!Trying to create a phase shift between two PWM signals on different timers

Page: 12 > Showing page 1 of 2
Author
dvtronic
Starting Member
  • Total Posts : 56
  • Reward points : 0
  • Joined: 2018/10/19 05:51:28
  • Location: 0
  • Status: offline
2020/01/27 12:18:26 (permalink)
0

Trying to create a phase shift between two PWM signals on different timers

I need to create a variable phase shift between two PWM signals -- one running off of Timer 2 on a PIC24FJ256GB100, and another one driven by Timer 4. Right now, they look like the signals in the attached image.

I tried setting TMR2 to 0 and TMR4 to various non-zero values, but this doesn't seem to have any effect. The two signals remain in lock-step -- or more precisely, offset by 180 degrees because the second signal is inverted.  Shouldn't changing TMR4's initial value change the phase difference between them?  What could be going wrong?

Attached Image(s)

#1

20 Replies Related Threads

    crosland
    Super Member
    • Total Posts : 2041
    • Reward points : 0
    • Joined: 2005/05/10 10:55:05
    • Location: Warks, UK
    • Status: offline
    Re: Trying to create a phase shift between two PWM signals on different timers 2020/01/27 13:45:19 (permalink)
    0
    Line 43 of the code that you didn't show us.
    #2
    dvtronic
    Starting Member
    • Total Posts : 56
    • Reward points : 0
    • Joined: 2018/10/19 05:51:28
    • Location: 0
    • Status: offline
    Re: Trying to create a phase shift between two PWM signals on different timers 2020/01/27 13:50:37 (permalink)
    0
    I was hoping that there was a simple answer that wouldn't involve a lot of extensive code scrutiny -- a simple flag, for example. If it would help though, here's how things are set up:
     
    T2CON = 0; // Timer 2 is clock for OC9.
    T2CONbits.TCKPS = 0; // Timer Input Clock Prescale is 1:1
    T4CON = 0;
    T4CONbits.TCKPS = 0;
    OC1CON1 = 0; 
    OC1CON2 = 0;
    OC1CON2bits.SYNCSEL = 0x1F; // synchronized by itself
    OC1CON1bits.OCTSEL = 0x0; // Timer 2 is the clock source for output Compare
    OC1CON1bits.OCFLT = 0; // No PWM Fault condition has occurred (this bit is only used when OCM<2:0> = 111)
    OC1CON2bits.OCINV = 0; // OCx output is not inverted
    OC1CON1bits.OCM = 0x6; // Edge-aligned PWM mode on OC
    TMR2 = 0;
    OC6CON1 = 0; 
    OC6CON2 = 0;
    OC6CON2bits.SYNCSEL = 0x1F; // synchronized by itself
    OC6CON1bits.OCTSEL = 0x2; // Timer 4 is the clock source for output compare
    OC6CON1bits.OCFLT = 0; // No PWM Fault condition has occurred (this bit is only used when OCM<2:0> = 111)
    OC6CON2bits.OCINV = 0; // OCx output is inverted
    OC6CON1bits.OCM = 0x6; // Edge-aligned PWM mode on OC
    TMR4 = 2000;  // Was expecting this to introduce a phase difference. It doesn't, though. Why?
    RPOR1bits.RP3R = OC1_IO; // RP3 pin #70
    RPOR6bits.RP12R = OC6_IO; // RP12 pin #71

    OC1CON1 |= 0x0006; /* Mode 6, Edge-aligned PWM Mode */
    OC6CON1 |= 0x0006;
     
    T2CONbits.TON = 1;
    T4CONbits.TON = 1;
     
    #3
    NKurzman
    A Guy on the Net
    • Total Posts : 18901
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: offline
    Re: Trying to create a phase shift between two PWM signals on different timers 2020/01/27 15:19:32 (permalink)
    0
    If you start timer 4 at a fixed time after timer 2, it should maintain that difference.
    Preloading TMR4 would achieve the same result.
    #4
    dvtronic
    Starting Member
    • Total Posts : 56
    • Reward points : 0
    • Joined: 2018/10/19 05:51:28
    • Location: 0
    • Status: offline
    Re: Trying to create a phase shift between two PWM signals on different timers 2020/01/27 15:22:44 (permalink)
    0
    NKurzman
    If you start timer 4 at a fixed time after timer 2, it should maintain that difference.
    Preloading TMR4 would achieve the same result.




    The first approach that you mentioned works, but it's less precise.

    The second approach doesn't work, for some reason. I'm baffled.
    #5
    ric
    Super Member
    • Total Posts : 28363
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: Trying to create a phase shift between two PWM signals on different timers 2020/01/27 15:28:53 (permalink)
    0
    Out there guess.
    Does writing to TMR4 actually work when T4CONbits.TON == 0 ?
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #6
    dvtronic
    Starting Member
    • Total Posts : 56
    • Reward points : 0
    • Joined: 2018/10/19 05:51:28
    • Location: 0
    • Status: offline
    Re: Trying to create a phase shift between two PWM signals on different timers 2020/01/27 15:32:49 (permalink)
    0
    I compared the contents of TMR2 and TMR4 as the code executes. Sure enough, their values remain offset by the same value.  There is no phase difference between their corresponding PWM signals, though.
     
    Is there something that could be forcing the two PWM signals to be started at the same time?
    #7
    ric
    Super Member
    • Total Posts : 28363
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: Trying to create a phase shift between two PWM signals on different timers 2020/01/27 15:40:00 (permalink)
    0
    I agree that your code appears to select T4 as the OC6 source, but the behaviour suggests it is still using T2.
    What happens if you leave T4 off?
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #8
    dvtronic
    Starting Member
    • Total Posts : 56
    • Reward points : 0
    • Joined: 2018/10/19 05:51:28
    • Location: 0
    • Status: offline
    Re: Trying to create a phase shift between two PWM signals on different timers 2020/01/27 16:07:56 (permalink)
    0
    ric
    I agree that your code appears to select T4 as the OC6 source, but the behaviour suggests it is still using T2.
    What happens if you leave T4 off?

    If I leave TMR4 off, I only get the top waveform --that is, only the PWM output from OC1. Conversely, if I leave TMR2 off, I only get the bottom waveform -- only the PWM output from OC6.  So I'm puzzled.
    #9
    dan1138
    Super Member
    • Total Posts : 3840
    • Reward points : 0
    • Joined: 2007/02/21 23:04:16
    • Location: 0
    • Status: offline
    Re: Trying to create a phase shift between two PWM signals on different timers 2020/01/27 16:38:39 (permalink)
    5 (3)
    The Output Compare modules of the PIC24FJ256GB110 do not use the count register of the TIMER modules.
     
    Each OC has its own count register. The OC modules use the pre-scaler from a TIMER module to get a lower frequency input clock.
     
    To get the offset you are looking for try initializing the count registers in the OC modules, not the ones in the TIMER modules.
     
    The OCnRS register of the OC module is used to set the PWM period.
     
    The OCnR register selects the OCnTMR count when the OC output is changed from one to zero.
     
    It seems likely that any delay between starting the TIMER modules will appear as an addition offset from the leading edge of one PWM and the next PWM. You may need to account for this in the values written to the count registers.
     
    <EDIT>
    This suggestion does not work.
    Writes to the OCxTMR registers do no seem to work when the OC is in PWM mode.
     
    post edited by dan1138 - 2020/01/28 19:18:48

    Attached Image(s)

    #10
    dvtronic
    Starting Member
    • Total Posts : 56
    • Reward points : 0
    • Joined: 2018/10/19 05:51:28
    • Location: 0
    • Status: offline
    Re: Trying to create a phase shift between two PWM signals on different timers 2020/01/28 08:13:40 (permalink)
    0
    Many thanks, @dan1138!  This looks logical. I tried to initialize OC1TMR and OC6TMR though, and I found that they're read-only registers.  Is there a nifty way to preset their values somehow?
    #11
    dvtronic
    Starting Member
    • Total Posts : 56
    • Reward points : 0
    • Joined: 2018/10/19 05:51:28
    • Location: 0
    • Status: offline
    Re: Trying to create a phase shift between two PWM signals on different timers 2020/01/28 15:50:09 (permalink)
    0
    I have a possible solution in mind, but it would require clearing one of the OCxTMR registers, i.e. setting it to zero.  Is there a good way to do that?  I haven't found any so far.
    #12
    dan1138
    Super Member
    • Total Posts : 3840
    • Reward points : 0
    • Joined: 2007/02/21 23:04:16
    • Location: 0
    • Status: offline
    Re: Trying to create a phase shift between two PWM signals on different timers 2020/01/28 18:58:51 (permalink)
    0
    You are correct.  I cannot get writes to the OCxTMR registers to cause a phase offset in the PWM outputs.

    This code:
    void PWM_Init(void)
    {
    /* Disable OC module */
    OC1CON1 = 0x00;
    OC1CON2 = 0x00;
    OC2CON1 = 0x00;
    OC2CON2 = 0x00;

    OC1CON1bits.OCTSEL = 0b111; /* Clock source is FOSC/2 */
    OC1CON2bits.SYNCSEL = 0b11111;
    OC2CON1bits.OCTSEL = 0b111; /* Clock source is FOSC/2 */
    OC2CON2bits.SYNCSEL = 0b11111;

    /* Set PWM period */
    OC1RS = 4000;
    /* Set PWM duty cycle */
    OC1R = 2000;

    /* Set PWM period */
    OC2RS = 4000;
    /* Set PWM duty cycle */
    OC2R = 2000;

    /* Start PWM mode */
    __asm( " mov OC1CON1,W0\n"
    " bclr w0,#0\n"
    " bset w0,#1\n"
    " bset w0,#2\n"
    " mov w0,OC1CON1\n"
    " repeat %0\n nop\n" /* minimum delay is 2 instruction cycles for input of 0 or 1 */
    " mov w0,OC2CON1\n"
    : /* no outputs */
    : "r" (999) /* phase delay (range 0 to 16383) results in delay of (2 to 16383 plus one) instruction cycles between PWM leading edge */
    : "w0" /* clobbers w0 */
    );

    /* Enable PWM output driver */
    OC1CON2bits.OCTRIS = 0b0;
    OC2CON2bits.OCTRIS = 0b0;
    }


    Does this for me:
    post edited by dan1138 - 2020/01/30 18:20:20

    Attached Image(s)

    #13
    ric
    Super Member
    • Total Posts : 28363
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: Trying to create a phase shift between two PWM signals on different timers 2020/01/28 19:02:30 (permalink)
    0
    You have set and reset registers in the peripheral, so you can keep the timers in sync, and just set the rising and falling edges to whatever phase you like.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #14
    dvtronic
    Starting Member
    • Total Posts : 56
    • Reward points : 0
    • Joined: 2018/10/19 05:51:28
    • Location: 0
    • Status: offline
    Re: Trying to create a phase shift between two PWM signals on different timers 2020/01/28 20:24:17 (permalink)
    0
     
    The set and reset registers govern the PWM period and duty cycle. What I need is a way to introduce a phase difference between the two PWM signals, i.e. to set a variable delay between the rising edge of one PWM signal and the rising edge of another.

    This can be done by introducing a fixed delay between the times that the two timers are activated, which is what dan1138 did (and what I have done in earlier approaches).  However, what I really need is a variable delay, and it would take a lot of code to introduce a delay that's both variable and precise.  It gets more complicated if we have to change the PWM parameters (frequency, duty cycle, and phase) on the fly.  Being able to set OCxTMR -- or even just clear it -- would help a lot.

    If there is no way, I might have to settle for coding up a routine that produces a variable delay that's sufficiently accurate. If there is no other solution, I will have to see how that goes.
     
    post edited by dvtronic - 2020/01/28 20:27:48
    #15
    ric
    Super Member
    • Total Posts : 28363
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: Trying to create a phase shift between two PWM signals on different timers 2020/01/28 20:42:15 (permalink)
    5 (1)
    Drag your eyes away from "14.3 Pulse-Width Modulation (PWM) Mode" and have a look at "14.2 Compare Operations".
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #16
    dan1138
    Super Member
    • Total Posts : 3840
    • Reward points : 0
    • Joined: 2007/02/21 23:04:16
    • Location: 0
    • Status: offline
    Re: Trying to create a phase shift between two PWM signals on different timers 2020/01/28 21:12:38 (permalink)
    5 (1)
    @dvtronic,
     
    Try to understand ric's suggestion. There are a lot of ways to configure the Output Compare modules to produce multiple overlapping outputs that do not involve the PWM mode.
     
    The PWM mode is convenient because it has double buffering for the period and duty cycle registers.
     
    It is possible to get the PIC to make the wave forms you are asking for, but a complete and detailed description is required to be able to comment if the PIC24FJ256GB110 can meet your timing requirements.
     
    If your timing budget is tight expect that inline assembly code will be needed.
    post edited by dan1138 - 2020/01/28 21:14:04
    #17
    T Yorky
    Super (Thick) Member
    • Total Posts : 563
    • Reward points : 0
    • Joined: 2012/08/28 02:07:35
    • Location: UK
    • Status: offline
    Re: Trying to create a phase shift between two PWM signals on different timers 2020/01/29 07:40:32 (permalink)
    0
    @dvtronic,
    I gather you have a PIC24 with the later dedicated timer OC peripheral. These differ slightly on the PIC24 chips so check your data sheet. To get the phase delay you are looking for, you need to understand and implement the SYNCH of the OC modules. You need to create a 'ripple' of triggers that cascade the OC modules or a timer. Note timers have an external gate input that can be tied to the OC pin output. One soln is OC1 triggers OC2 that in turn triggers OC3. You use OC1 and OC3 as your signals, the OC2 is not used and merely provides the time between 1 and 3.
    #18
    dvtronic
    Starting Member
    • Total Posts : 56
    • Reward points : 0
    • Joined: 2018/10/19 05:51:28
    • Location: 0
    • Status: offline
    Re: Trying to create a phase shift between two PWM signals on different timers 2020/01/30 16:04:47 (permalink)
    0
    Thanks, folks. I was able to code a delay function that seems to be sufficiently precise for our purposes. If we need more precision, I will try the approach that ric suggested.  (I'd prefer to use the built-in PWM functionality to help keep the code more intuitive, but his proposed solution does make sense.)
    #19
    ric
    Super Member
    • Total Posts : 28363
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: Trying to create a phase shift between two PWM signals on different timers 2020/01/30 16:12:33 (permalink)
    0
    To my mind, what I suggested is still a "built-in PWM functionality", just a more powerful version of it under a slightly different name. It's still the same peripheral, with more functionality enabled.
     
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #20
    Page: 12 > Showing page 1 of 2
    Jump to:
    © 2020 APG vNext Commercial Version 4.5