Hello,
My team is attempting to apply spread spectrum to a 3-phase BLDC motor via PWM outputs, which are driven through the FTM0 peripheral. We are investigating the PWM modulation option to achieve this as mentioned in the reference manual:
It is still unclear to us the exact affect the modulation will have on the PWM output. Ideally, we are looking for something that will sweep(oscillate) the PWM frequency between a low limit (say 20KHz), and a high limit (say 22KHz). We would look into dithering as another option, but unfortunately we need to used FTM0 for our layout, and dithering is not supported on FTM0.
Can someone please explain how the PWM would behave if we applied a modulation of 2Khz on FTM0? Would it jump from 20KHz to 22KHz every few period cycles? Or will it randomly run at a frequency in between that range? Any clarification would be appreciated.
We have attempted to model this ourselves, but the instructions for setting up modulation are a bit unclear. I enabled the SIM->FTMOPT1 register to apply modulation on each of the 3 output channels
I also set up FTM1 channel 1 to output a PWM at 50% duty cycle at a frequency of 22KHz (2KHz higher than the FTM0 pwms). I applied a 10 tick deadtime and 1/16 deadtime pre-scale to match the FTM0 driver. This is the results I am getting (Yellow is the PWM output on FTM0, blue is the FTM1 output):
Here are the configurations for each FTM module:
FTM0
/* Fault configuration structure for FTM0 */
ftm_pwm_fault_param_t flexTimer_pwm0_FaultConfig = {
false, /* Output pin state on fault */
false, /* PWM fault interrupt state */
20U, /* Fault filter value */
FTM_FAULT_CONTROL_MAN_ALL, /* Fault mode */
{
{
false, /* Fault channel state (Enabled/Disabled) */
false, /* Fault channel filter state (Enabled/Disabled) */
FTM_POLARITY_LOW, /* Channel output state on fault */
},
{
false, /* Fault channel state (Enabled/Disabled) */
false, /* Fault channel filter state (Enabled/Disabled) */
FTM_POLARITY_LOW, /* Channel output state on fault */
},
{
true, /* Fault channel state (Enabled/Disabled) */
true, /* Fault channel filter state (Enabled/Disabled) */
FTM_POLARITY_LOW, /* Channel output state on fault */
},
{
false, /* Fault channel state (Enabled/Disabled) */
false, /* Fault channel filter state (Enabled/Disabled) */
FTM_POLARITY_LOW, /* Channel output state on fault */
},
}
};
/* Independent channels configuration structure for flexTimer_pwm0 */
ftm_independent_ch_param_t flexTimer_pwm0_IndependentChannelsConfig[3] = {
{
0U, /* hwChannelId */
FTM_POLARITY_HIGH, /* Edge mode */
0U, /* Duty cycle percent 0-0x8000 */
false, /* External Trigger */
FTM_LOW_STATE, /* The selection of the channel (n) mode */
true, /* Enabled/disabled the channel (n+1) output */
FTM_MAIN_INVERTED, /* Select channel (n+1) output relative to channel (n) */
true, /* Dead time enabled/disabled */
},
{
2U, /* hwChannelId */
FTM_POLARITY_HIGH, /* Edge mode */
0U, /* Duty cycle percent 0-0x8000 */
false, /* External Trigger */
FTM_LOW_STATE, /* The selection of the channel (n) mode */
true, /* Enabled/disabled the channel (n+1) output */
FTM_MAIN_INVERTED, /* Select channel (n+1) output relative to channel (n) */
true, /* Dead time enabled/disabled */
},
{
4U, /* hwChannelId */
FTM_POLARITY_HIGH, /* Edge mode */
0U, /* Duty cycle percent 0-0x8000 */
false, /* External Trigger */
FTM_LOW_STATE, /* The selection of the channel (n) mode */
true, /* Enabled/disabled the channel (n+1) output */
FTM_MAIN_INVERTED, /* Select channel (n+1) output relative to channel (n) */
true, /* Dead time enabled/disabled */
},
};
/* PWM configuration for flexTimer_pwm0 */
ftm_pwm_param_t flexTimer_pwm0_PwmConfig = {
3U, /* Number of independent PWM channels */
0U, /* Number of combined PWM channels */
FTM_MODE_CEN_ALIGNED_PWM, /* PWM mode */
10U, /* Dead time value */
FTM_DEADTIME_DIVID_BY_16, /* Dead time prescaler */
20000U, /* PWM frequency */
flexTimer_pwm0_IndependentChannelsConfig,
/* Independent PWM channels configuration structure */
NULL, /* Combined PWM channels configuration structure */
&flexTimer_pwm0_FaultConfig /* PWM fault configuration structure */
};
/* Global configuration of flexTimer_pwm0 */
ftm_user_config_t flexTimer_pwm0_InitConfig = {
{
true, /* Software trigger state */
false, /* Hardware trigger 1 state */
false, /* Hardware trigger 2 state */
false, /* Hardware trigger 3 state */
false, /* Max loading point state */
true, /* Min loading point state */
FTM_PWM_SYNC, /* Update mode for INVCTRL register */
FTM_PWM_SYNC, /* Update mode for SWOCTRL register */
FTM_PWM_SYNC, /* Update mode for OUTMASK register */
FTM_PWM_SYNC, /* Update mode for CNTIN register */
true, /* Automatic clear of the trigger*/
FTM_WAIT_LOADING_POINTS, /* Synchronization point */
},
FTM_MODE_CEN_ALIGNED_PWM, /* Mode of operation for FTM */
FTM_CLOCK_DIVID_BY_1, /* FTM clock prescaler */
FTM_CLOCK_SOURCE_SYSTEMCLK, /* FTM clock source */
FTM_BDM_MODE_00, /* FTM debug mode */
false, /* Interrupt state */
false /* Initialization trigger */
};
FTM1
/* Global configuration of flexTimer_pwm_1 InitConfig */
ftm_user_config_t flexTimer_pwm_MOD_InitConfig =
{
{
true, /* Software trigger state */
false, /* Hardware trigger 1 state */
false, /* Hardware trigger 2 state */
false, /* Hardware trigger 3 state */
false, /* Max loading point state */
true, /* Min loading point state */
FTM_PWM_SYNC, /* Update mode for INVCTRL register */
FTM_PWM_SYNC, /* Update mode for SWOCTRL register */
FTM_PWM_SYNC, /* Update mode for OUTMASK register */
FTM_PWM_SYNC, /* Update mode for CNTIN register */
true, /* Automatic clear of the trigger*/
FTM_WAIT_LOADING_POINTS, /* Synchronization point */
},
FTM_MODE_CEN_ALIGNED_PWM, /* Mode of operation for FTM */
FTM_CLOCK_DIVID_BY_1, /* FTM clock prescaler */
FTM_CLOCK_SOURCE_SYSTEMCLK, /* FTM clock source */
FTM_BDM_MODE_00, /* FTM debug mode */
false, /* Interrupt state */
false /* Initialization trigger */
};
/* Fault configuration structure for flexTimer_pwm_1*/
ftm_pwm_fault_param_t flexTimer_pwm_MOD_FaultConfig =
{
false, /* Output pin state on fault */
false, /* PWM fault interrupt state */
0U, /* Fault filter value */
FTM_FAULT_CONTROL_DISABLED, /* Fault mode */
{
{
false, /* Fault channel state (Enabled/Disabled) */
false, /* Fault channel filter state (Enabled/Disabled) */
FTM_POLARITY_LOW, /* Fault channel state (Enabled/Disabled) */
},
{
false, /* Fault channel state (Enabled/Disabled) */
false, /* Fault channel filter state (Enabled/Disabled) */
FTM_POLARITY_LOW, /* Fault channel state (Enabled/Disabled) */
},
{
false, /* Fault channel state (Enabled/Disabled) */
false, /* Fault channel filter state (Enabled/Disabled) */
FTM_POLARITY_LOW, /* Fault channel state (Enabled/Disabled) */
},
{
false, /* Fault channel state (Enabled/Disabled) */
false, /* Fault channel filter state (Enabled/Disabled) */
FTM_POLARITY_LOW, /* Fault channel state (Enabled/Disabled) */
},
}
};
/* The independent channels configuration structure for flexTimer_pwm_1_IndependentChannelsConfig */
ftm_independent_ch_param_t flexTimer_pwm_MOD_IndependentChannelsConfig[1] =
{
{
1, /* Hardware channel Id */
FTM_POLARITY_HIGH, /* Polarity of the PWM signal */
16384U, /* Duty cycle percent 0-0x8000 */
false, /* External Trigger */
FTM_LOW_STATE, /* Safe state of the PWM channel when faults are detected */
false, /* Enabled/disabled the channel (n+1) output */
FTM_MAIN_INVERTED, /* Select channel (n+1) output relative to channel (n) */
true, /* Dead time enabled/disabled */
}
};
/* PWM configuration for flexTimer_pwm_1 */
ftm_pwm_param_t flexTimer_pwm_MOD_PwmConfig =
{
1U, /* Number of independent PWM channels */
0U, /* Number of combined PWM channels */
FTM_MODE_CEN_ALIGNED_PWM, /* PWM mode */
10U, /* Dead time value */
FTM_DEADTIME_DIVID_BY_16, /* Dead time prescale */
22000U, /* PWM frequency */
flexTimer_pwm_MOD_IndependentChannelsConfig, /* The independent PWM channels configuration structure */
NULL, /* Combined PWM channels configuration structure */
&flexTimer_pwm_MOD_FaultConfig /* PWM fault configuration structure */
};
I set the FTMOPT1 register before initializing the FTM peripherals using the following lines of code:
SIM_Type * simeBase = SIM_BASE_PTRS;
simeBase->FTMOPT1 |= SIM_FTMOPT1_FTM0_OUTSEL(0x2A); /* 0b101010 channels 1, 3, and 5 */
Is there something I am initializing incorrectly? This behavior does not seem correct. I would expect a consistent duty cycle each period with alternating frequencies in the range of 20kHz-22kHz. To clarify, I am using an S32K142W MCU with the SDK RTM v4.0.3.
Thanks.
Solved! Go to Solution.
Hi,
Thank you so much for your interest in our products and for using our community.
The FTM Modulation Implementation for PWM mode using FTM0_OUTSEL register looks like this.
Without modulation:
Modulation with FTM1_CH1:
At the moment I only have on hand a S32K144-Q100 to test but it should be equal for the S32K142W.
I attach the project using S32 Design Studio for S32 Platform v.3.5 and RTD for S32K1 and S32M24x version 2.0.0 including patch P01.
Another way to perform modulation is using FAULT input signals, for more detail please refer to the following community posts:
https://community.nxp.com/t5/S32K/Modulated-PWM-waveform-Generation/m-p/656233
https://community.nxp.com/t5/S32K/FTM2-Output-Modulation/m-p/1056029
Hope it helps you.
Have a nice day!
Hi,
Thank you so much for your interest in our products and for using our community.
The FTM Modulation Implementation for PWM mode using FTM0_OUTSEL register looks like this.
Without modulation:
Modulation with FTM1_CH1:
At the moment I only have on hand a S32K144-Q100 to test but it should be equal for the S32K142W.
I attach the project using S32 Design Studio for S32 Platform v.3.5 and RTD for S32K1 and S32M24x version 2.0.0 including patch P01.
Another way to perform modulation is using FAULT input signals, for more detail please refer to the following community posts:
https://community.nxp.com/t5/S32K/Modulated-PWM-waveform-Generation/m-p/656233
https://community.nxp.com/t5/S32K/FTM2-Output-Modulation/m-p/1056029
Hope it helps you.
Have a nice day!