about s32k144 pwm phase shift

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

about s32k144 pwm phase shift

6,970件の閲覧回数
alice_th
Contributor III

in independent mode , how to set different channel with phase shift, like 10, 20, 30degree phase shift,

i see there is dead time setting, but phase shift setting,

so i enable the deadtime, but no delay between the two channel waveform

could you help to check how to set phase **bleep**ft with tool and attached project, thanks a lot! 

 

alice_thanks_0-1728703682983.png

alice_thanks_1-1728703986719.png

 

 

0 件の賞賛
返信
13 返答(返信)

6,941件の閲覧回数
Senlent
NXP TechSupport
NXP TechSupport

Hi@alice_thanks

Please do not create the same question, you must read the datasheet so that you are familiar

with this mode.


For Phase Shift, you need to use Modified Combine PWM Mode, which meets your needs.

 

I made a three Pairs phase shift demo for your reference

 

RTM 4.0.1 + Modified Combine PWM + Insert Dead Time + Same Duty Cycle

Senlent_2-1728728826532.png

 

Senlent_1-1728728808200.png

 

 

0 件の賞賛
返信

6,913件の閲覧回数
alice_th
Contributor III

hello @Senlent 

thanks a lot!, in combine mode , it use first edge and second edge to shift phase in the init state, is that correct ?

that's means PB13 and PTE6 can't don't phase shift ?

alice_thanks_0-1728876232621.png

 

0 件の賞賛
返信

6,901件の閲覧回数
Senlent
NXP TechSupport
NXP TechSupport

Hi@alice_thanks

Please refer to the data sheet, which explains it in detail.
PTB13 and PTE6 belong to two different FTM instances, but this does not mean that phase shifting cannot be achieved. If the counters of FTM0 and FTM3 can be guaranteed to start at the same time, this is still possible.

0 件の賞賛
返信

6,897件の閲覧回数
alice_th
Contributor III

hello @Senlent 

ok, got it.

i changed it t0 100Hz, and modify below, why the demo doesn't work ?

alice_thanks_0-1728886853002.pngalice_thanks_1-1728886886812.png

 

 

 

0 件の賞賛
返信

6,889件の閲覧回数
Senlent
NXP TechSupport
NXP TechSupport

Hi@alice_thanks

change below setting and try again.

Senlent_0-1728888753316.png

 

0 件の賞賛
返信

6,884件の閲覧回数
alice_th
Contributor III

hello @Senlent 

why 10kHz can use FTM_UPDATE_NOW, 100Hz need FTM_WAIT_LOADING_POINTS ?

i see the chart when software trigger use WAIT_LOADING_POINTS

alice_thanks_0-1728891009448.png

 

 

 

0 件の賞賛
返信

6,879件の閲覧回数
Senlent
NXP TechSupport
NXP TechSupport

Hi@alice_thanks

This is just because the currently executed API (FTM_DRV_UpdatePwmChannel) has not succeeded, and this API is executed again.


You can leave the above configuration unchanged and add a longer extension time to achieve the same effect.

Senlent_0-1728891872564.png

 

0 件の賞賛
返信

6,875件の閲覧回数
alice_th
Contributor III

hello @Senlent 

There should have some problem, ch0-ch1 is dutyCycle = 0x6000,

ch4-ch5 already 0x8000 which means 100% duty cycle, then ch4-ch5 have no pahse shift 

same ch0-ch1 is dutyCycle = 0x7000, ch2-ch3 already 0x8000, 100% duty cycle

/* Update PWM channels */
FTM_DRV_UpdatePwmChannel(INST_FLEXTIMER_PWM_1, 1U, FTM_PWM_UPDATE_IN_DUTY_CYCLE, 0, dutyCycle, true);

FTM_DRV_UpdatePwmChannel(INST_FLEXTIMER_PWM_1, 3U, FTM_PWM_UPDATE_IN_DUTY_CYCLE, 0, dutyCycle+0x1000, true);

FTM_DRV_UpdatePwmChannel(INST_FLEXTIMER_PWM_1, 5U, FTM_PWM_UPDATE_IN_DUTY_CYCLE, 0, dutyCycle+0x2000, true);
//delayCycles(0x1FFFU);

alice_thanks_0-1728896045290.png

 

0 件の賞賛
返信

6,870件の閲覧回数
Senlent
NXP TechSupport
NXP TechSupport

Hi@alice_thanks

Don't waste my time anymore.

Test the demo I provided and read the data sheet before asking questions.

0 件の賞賛
返信

6,813件の閲覧回数
alice_th
Contributor III

@Senlent 

the output waveform is your demo test result, if you observe longer time, 2 circle time, you will see the problem, i attached the vedio

i just double wether is below cause, maybe seems not .

when the dutyCycle < 0x6000, 

all the waveform is correct with phase shift, 

but dutyCycle > 0x6000

ch5 secondEdge dutyCycle+0x2000 > 0x8000, that will cause ch4-ch5 will not update 

if ((firstEdge <= FTM_MAX_DUTY_CYCLE) && (secondEdge <= FTM_MAX_DUTY_CYCLE))

look at here FTM_MAX_DUTY_CYCLE = 0x8000, that means

 retStatus = STATUS_ERROR;

it will not update the hwSecondEdge
FTM_DRV_SetChnCountVal(ftmBase, (uint8_t)((chnlPairNum * 2U) + 1U), hwSecondEdge);

if (STATUS_SUCCESS == retStatus)
{
if (true == FTM_DRV_GetDualChnCombineCmd(ftmBase, chnlPairNum))
{
if (true == FTM_DRV_GetDualChnMofCombineCmd(ftmBase, chnlPairNum))
{
/* Check the clock source for FTM counter is disabled or not */
if (FTM_DRV_GetClockSource(ftmBase) == 0U)
{
FTM_DRV_SetChnCountVal(ftmBase, (uint8_t)(chnlPairNum * 2U), hwFirstEdge);
}
}
else
{
FTM_DRV_SetChnCountVal(ftmBase, (uint8_t)(chnlPairNum * 2U), hwFirstEdge);
}

/* Modify the initial value in the channel (n+1) match edge */
FTM_DRV_SetChnCountVal(ftmBase, (uint8_t)((chnlPairNum * 2U) + 1U), hwSecondEdge);
}
else
{
/* Channel value is divided by 2 for up down counter mode to keep same duty */
if (true == FTM_DRV_GetCpwms(ftmBase))
{
FTM_DRV_SetChnCountVal(ftmBase, channel, (uint16_t)(hwFirstEdge >> 1U));
}
else
{
FTM_DRV_SetChnCountVal(ftmBase, channel, hwFirstEdge);
}
}

 

 

/* Check the type of update for PWM */
if (FTM_PWM_UPDATE_IN_DUTY_CYCLE == typeOfUpdate)
{
if ((firstEdge <= FTM_MAX_DUTY_CYCLE) && (secondEdge <= FTM_MAX_DUTY_CYCLE))
{
/* Calculate DutyCycle based of the previously calculated frequency*/
/* For greater resolution the DutyCycle values are in the range [0. FTM_MAX_DUTY_CYCLE]
* where 0 = 0% or PWM always at Low and FTM_MAX_DUTY_CYCLE = 100% or PWM always HIGH;
* a value of 0x4000 is equivalent of 50% DutyCycle. */
hwFirstEdge = (uint16_t)((ftmPeriod * firstEdge) >> FTM_DUTY_TO_TICKS_SHIFT);
hwSecondEdge = (uint16_t)((ftmPeriod * secondEdge) >> FTM_DUTY_TO_TICKS_SHIFT);
/* adjust DutyCycle if 100% value is to be achieved. */
if (FTM_MAX_DUTY_CYCLE == firstEdge)
{
/* If expected duty is 100% then increase by 1 the value that is to be written
* to Hardware so it will exceed value of period */
hwFirstEdge = (uint16_t)(hwFirstEdge + 1U);
}
}
else
{
retStatus = STATUS_ERROR;
}
}

0 件の賞賛
返信

6,803件の閲覧回数
Senlent
NXP TechSupport
NXP TechSupport

Hi@alice_thanks

 

Senlent_0-1728974937277.png

int main(void)
{
    /* Write your local variable definition here */
    ftm_state_t ftmStateStruct;
    bool increaseDutyCycle = true;
    uint32_t dutyCycle  = 0UL;

    /* Initialize clock module */
    CLOCK_SYS_Init(g_clockManConfigsArr, CLOCK_MANAGER_CONFIG_CNT, g_clockManCallbacksArr, CLOCK_MANAGER_CALLBACK_CNT);
    CLOCK_SYS_UpdateConfiguration(0U, CLOCK_MANAGER_POLICY_AGREEMENT);

    /* Initialize pins */
    PINS_DRV_Init(NUM_OF_CONFIGURED_PINS0, g_pin_mux_InitConfigArr0);

    /* Initialize FTM */
    FTM_DRV_Init(INST_FLEXTIMER_PWM_1, &flexTimer_pwm_1_InitConfig, &ftmStateStruct);

    /* Initialize FTM PWM */
    FTM_DRV_InitPwm(INST_FLEXTIMER_PWM_1, &flexTimer_pwm_1_PwmConfig);

    unsigned int FTM0_MOD = FTM0->MOD;
    unsigned int Ch0_1_phase_shift = FTM0->CONTROLS[0].CnV;
    dutyCycle = Ch0_1_phase_shift;

    /* Infinite loop
     *  -   increment or decrement duty cycleU
     *  -   Update channel duty cycle
     *  -   Wait for a number of cycles to make
     *      the change visible
     */
    for ( ;; )
    {
		if (dutyCycle > (FTM0_MOD))

			dutyCycle = 0;
		else
			dutyCycle++;


        FTM0->CONTROLS[1].CnV = FTM_CnV_VAL(dutyCycle);
        FTM0->CONTROLS[3].CnV = FTM_CnV_VAL(dutyCycle);
        FTM0->CONTROLS[5].CnV = FTM_CnV_VAL(dutyCycle);


        delayCycles(0x2FFFU);
    }

    return exit_code;
}

 

0 件の賞賛
返信

6,800件の閲覧回数
alice_th
Contributor III

@Senlent 

FTM0->CONTROLS[1].CnV = FTM_CnV_VAL(dutyCycle);
FTM0->CONTROLS[3].CnV = FTM_CnV_VAL(dutyCycle);
FTM0->CONTROLS[5].CnV = FTM_CnV_VAL(dutyCycle);

there is no phase shift, only dutyCycle different as c(n)V is different 

dutyCycle = c(n+1)V - c(n)V

alice_thanks_0-1728982544488.png

when modify 

FTM0->CONTROLS[1].CnV = FTM_CnV_VAL(dutyCycle);
FTM0->CONTROLS[3].CnV = FTM_CnV_VAL(dutyCycle-0x1000);
FTM0->CONTROLS[5].CnV = FTM_CnV_VAL(dutyCycle-0x2000);

no output

0 件の賞賛
返信

6,797件の閲覧回数
Senlent
NXP TechSupport
NXP TechSupport

Hi@alice_thanks

I think you're kidding me.

0 件の賞賛
返信