phase shift PWM

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

phase shift PWM

1,725 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by williamjsell on Fri Sep 04 13:57:53 MST 2015
I want to create a phase shifting PWM output.   I have a master 50% duty cycle pulse, and another pulse with the same frequency and duty cycle, but to be able to shift the slave pulse with respect to the master pulse.  I have a LPC11U68.  Anyone done anything like this?  I am finding the manual hard to read!
Labels (1)
0 Kudos
8 Replies

1,321 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by williamjsell on Fri Nov 20 15:11:28 MST 2015
I was able to finally understand the SCT peripheral and this code will phase shift the PWM based on the SCT.  HTR_COM in our case is the output of the 32bit timer which generates the 1Khz/50% duty cycle PWM waveform...

/**-----------------------------------------------------------------------------
    @brief  FlowDrive_Init
    @details initializes the flow drive using the SCT timer module.  Description as follows:
    EVENT TRIGGERS
    event0: falling edge of SCT0_IN0 (driven by CT32B0_MAT2, HTRCOM)
    event1: rising edge of SCT0_IN0 (driven by CT32B0_MAT2, HTRCOM)
    event2: state0 and SCT0_MAT1
    event3: state1 and SCT0_MAT1
    event4: state0 and SCT0_MAT2
    event5: state1 and SCT0_MAT2

    STATE TRANSITIONS
    state0 event1
        reset timer
        go to state1
    state1 event0
        reset timer
        go to state0

    OUTPUT COMMANDS
    event2: set SCT0_OUT0 (HTR1) low
    event3: set SCT0_OUT0 (HTR1) high
    event4: set SCT0_OUT3 (HTR2) low
    event5: set SCT0_OUT3 (HTR2) high

    CONTROL INPUTS
    SCT0_MAT1: HTR1 duty cycle; ranges from 0 to half max for 0 to 100% duty cycle
    SCT0_RELOAD1: HTR1 duty cycle reload; ranges from 0 to half max for 0 to 100% duty cycle
    SCT0_MAT2: HTR2 duty cycle; ranges from 0 to half max for 0 to 100% duty cycle
    SCT0_RELOAD2: HTR2 duty cycle reload; ranges from 0 to half max for 0 to 100% duty cycle

*/
void FlowDrive_Init(void)
{
    //first start the 32-bit timer
    InitTimer32();
    //set the variables for test purposes only
    uint32_t match0 = 1000, match1 = 1500;
    //Enable timer to generate interrupts when time matches
    uint32_t timerFreq = Chip_Clock_GetSystemClockRate();
    //get the 1Khz pulse
    timerFreq /= _FLOW_DRIVE_FREQ;

    LPC_SCT_T* sct = LPC_SCT0;
    Chip_SCT_Init(sct); //init SCT0
    Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_IOCON );                      // enable clock for IOCON
    Chip_SCT_SetMatchCount(sct, SCT_MATCH_0,match0);                     //initial match point
    Chip_SCT_SetMatchReload(sct, SCT_MATCH_0, match0);                   //update this register for the next cycle
    Chip_SCT_SetMatchCount(sct, SCT_MATCH_1, match1);
    Chip_SCT_SetMatchReload(sct, SCT_MATCH_1, match1);
    Chip_SCT_Config(sct, SCT_CONFIG_32BIT_COUNTER);                         // unified timer

    //set the input pin for the SCT0 module
    Chip_IOCON_PinMuxSet(LPC_IOCON, IOP_GETPORTNUM(pindef_SCT0_IN1), IOP_GETPINNUM(pindef_SCT0_IN1), IOCON_FUNC2);
    Chip_IOCON_PinMuxSet(LPC_IOCON, IOP_GETPORTNUM(pindef_SCT0_OUT2), IOP_GETPINNUM(pindef_SCT0_OUT2), IOCON_FUNC2);
    Chip_IOCON_PinMuxSet(LPC_IOCON, IOP_GETPORTNUM(pindef_SCT0_OUT1), IOP_GETPINNUM(pindef_SCT0_OUT1), IOCON_FUNC3);
    //setup the SCT0 module

    /*********state 0 for SCT0 Module***********/
    //event 0 for state 0
    sct->EVENT[0].STATE =  (1 << 0);      // Only happens in state 0
    sct->EVENT[0].CTRL =   (1 << 6)  |    // set the input as the event trigger
                                (1 << 10)  |     //io condition is rise for this state
                                (2 << 12) |    // COMBMODE[13:12] = io condition only
                                (1 << 14) |    // STATELD[14] = STATEV is loaded into state
                                (1 << 15);     // STATEV[15] = 1 (new state is 1)
    //event2 for state0
    sct->EVENT[2].STATE =   (1 << 0);      // Only happens in state 0
    sct->EVENT[2].CTRL =    (0 << 0)  |    // Use Match0 register
                                 (1 << 12);    // COMBMODE[13:12] = match condition only
    //event4 for state0
    LPC_SCT0->EVENT[4].STATE =   (1 << 0);      // Only happens in state 0
    LPC_SCT0->EVENT[4].CTRL =    (1 << 0)  |    // Use Match1 register
                                 (1 << 12);    // COMBMODE[13:12] = match condition only
    /********state 1 for SCT0 Module************/
    sct->EVENT[1].STATE =  (1 << 1);      // Only happens in state 1
    sct->EVENT[1].CTRL =   (1 << 6)  |    // set the input as the event trigger
                                (2 << 10)  |     //io condition is fall for this state
                                (2 << 12) |    // COMBMODE[13:12] = io condition only
                                (1 << 14) |    // STATELD[14] = STATEV is loaded into state
                                (0 << 15);     // STATEV[15] = 1 (new state is 1)
   //event3 for state1
    sct->EVENT[3].STATE =   (1 << 1);      // Only happens in state 1
    sct->EVENT[3].CTRL =    (0 << 0)  |    // Use Match0 register
                                 (1 << 12);    // COMBMODE[13:12] = match condition only
    //event5 for state1
    LPC_SCT0->EVENT[5].STATE =   (1 << 1);      // Only happens in state 1
    LPC_SCT0->EVENT[5].CTRL =    (1 << 0)  |    // Use Match1 register
                                (1 << 12);    // COMBMODE[13:12] = match condition only
    /*********end state setup ************/

    //reset the counter when event 0 or 1 fires (rise or falling edge)
    sct->LIMIT_L = SCT_EVT_0 | SCT_EVT_1;
    //set the i/o
    LPC_SCT0->OUT[1].CLR = SCT_EVT_2;            // event2 clears OUT1
    LPC_SCT0->OUT[2].CLR = SCT_EVT_4;            // event3 sets OUT1
    LPC_SCT0->OUT[1].SET = SCT_EVT_3;            // event4 clears OUT2
    LPC_SCT0->OUT[2].SET = SCT_EVT_5;            // event5 sets OUT2
    //start the SCT
    LPC_SCT0->CTRL_L          &= ~(1 << 2);     // unhalt by clearing bit 2 of CTRL register
}
0 Kudos

1,321 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by williamjsell on Thu Sep 10 14:10:28 MST 2015
yup, I got this and went through the cookbook.  There is actually a deadband example which sorta is a phase shift, but still not quite what I need...thanks for the heads up though
0 Kudos

1,321 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by starblue on Thu Sep 10 01:17:57 MST 2015
Did you see the SCT Cookbook (AN11538)?
http://www.nxp.com/documents/application_note/AN11538.zip

It doesn't contain a phase shift example, but the other SCT examples may still help you.
0 Kudos

1,321 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by williamjsell on Wed Sep 09 08:48:29 MST 2015
As the SCtimer is what I was looking to use, I will have to keep on trying to get a solution.  I am beginning to understand the SCTimer, it would have been helpful if NXP could have created a clearer tutorial, but once you get the concept of the events and states it is not too bad...thanks for helping
0 Kudos

1,321 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by williamjsell on Tue Sep 08 13:35:57 MST 2015
great, I will go over the code and see how it works.  Thanks for effort...!
0 Kudos

1,321 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Badman on Tue Sep 08 11:52:11 MST 2015
I  never used LPC11U68, this uC has SCT timer...
Hmm, in LPC1114 i use to timers with with the same frequency

This code not tested:
#include "LPC11xx.h"

// frequency 3 kHz
#define FREQUENCY 3000

// duty 1,5 kHz
#define DUTY 1500

// shift 25 %
#define SHIFT 25

#define TIME_SHIFT ((FREQUENCY/SHIFT)/100)

void TIMER32_0_IRQHandler (void)
{
if ( LPC_TMR32B0->IR & 0x1 )
{
LPC_TMR32B0->IR = 1;// clear interrupt flag
LPC_TMR16B1->TCR = 1;// start timer CT16B1
}

}

int main(void) {

LPC_SYSCON->SYSAHBCLKCTRL |= 1<<16;// enable clock to IOCONFIG block

// CT16B0
LPC_SYSCON->SYSAHBCLKCTRL |= 1<<7;// enable clock to timer CT16B0
LPC_IOCON->PIO0_8 &= ~0x7;
LPC_IOCON->PIO0_8 |= 0x02;// CT16B0_MAT0
LPC_TMR16B0->MR3 = (SystemCoreClock / FREQUENCY) - 1;// set frequency
LPC_TMR16B0->MR0 = (SystemCoreClock / DUTY) - 1;// set duty
LPC_TMR16B0->MCR = 1<<10;// reset on MR3
LPC_TMR16B0->PWMC = 1<<0;// enable PWM channel on CT16B0_MAT0

// CT16B1
LPC_SYSCON->SYSAHBCLKCTRL |= 1<<8;// enable clock to timer CT16B1
LPC_IOCON->PIO1_9 &= ~0x7;
LPC_IOCON->PIO1_9 |= 0x01;// CT16B1_MAT0
LPC_TMR16B1->MR3 = (SystemCoreClock / FREQUENCY) - 1;// set frequency
LPC_TMR16B1->MR0 = (SystemCoreClock / DUTY) - 1;// set duty
LPC_TMR16B1->MCR = 1<<10;// reset on MR3
LPC_TMR16B1->PWMC = 1<<0;// enable PWM channel on CT16B1_MAT0


// CTB32B0
LPC_SYSCON->SYSAHBCLKCTRL |= 1<<9;// enable clock to timer CT32B0
LPC_TMR32B0->MR0 = (SystemCoreClock / TIME_SHIFT) - 1;
LPC_TMR32B0->MCR = (1<<0) | (1<<2);// generate innterupt when MR0 matches the value in the TC and stop timer

LPC_TMR16B0->TCR = 1;// start timer CT16B0
LPC_TMR32B0->TCR = 1;// start timer CT32B0

while(1) {
    }

    return 0 ;
}
0 Kudos

1,321 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by williamjsell on Tue Sep 08 10:33:47 MST 2015
see attachment
0 Kudos

1,321 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Badman on Tue Sep 08 09:45:08 MST 2015
Show on the graph how you want it.
0 Kudos