about s32k144 pwm phase shift

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

about s32k144 pwm phase shift

6,967 次查看
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,938 次查看
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,910 次查看
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,898 次查看
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,894 次查看
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,886 次查看
Senlent
NXP TechSupport
NXP TechSupport

Hi@alice_thanks

change below setting and try again.

Senlent_0-1728888753316.png

 

0 项奖励
回复

6,881 次查看
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,876 次查看
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,872 次查看
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,867 次查看
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,810 次查看
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,800 次查看
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,797 次查看
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,794 次查看
Senlent
NXP TechSupport
NXP TechSupport

Hi@alice_thanks

I think you're kidding me.

0 项奖励
回复