I am controlling a bldc motor with 3 sct ouptuts. This works fine until one of the thrree duty cycles reach 50-60%. After this point strange things happen and it might be that pulses get missing (see attached red curve) The SCTIMER_UpdatePwmDutycycle function is called every 50us. (PWM Frequency is 20kHz). If I increase the frequency to 50kHz it gets even worse. If I choose frequency 10kHz it gets better but this frequency is not suitable for my application.
sctimer_config_t sctimerInfo;
sctimer_pwm_signal_param_t pwmParam;
uint32_t sctimerClock;
s_PWMcallback = NoOp;
sctimerClock = CLOCK_GetFreq(kCLOCK_BusClk);
SCTIMER_GetDefaultConfig(&sctimerInfo);
sctimerInfo.enableBidirection_l = TRUE;
SCTIMER_Init(SCT0, &sctimerInfo);
// Configure PWM params with frequency 20kHZ from output
pwmParam.output = PWM_OUT_A;
pwmParam.level = kSCTIMER_HighTrue;
pwmParam.dutyCyclePercent = 0;
if (SCTIMER_SetupPwm(SCT0, &pwmParam, kSCTIMER_CenterAlignedPwm, PWM_FREQ_HZ, sctimerClock, &s_eventNumberOutputA) == kStatus_Fail)
{
SetDeviceStatusWithErrorNumber(ERR_BIT_INIZIALISATION, 2);
return ;
}
pwmParam.output = PWM_OUT_B;
pwmParam.level = kSCTIMER_HighTrue;
pwmParam.dutyCyclePercent = 0;
if (SCTIMER_SetupPwm(SCT0, &pwmParam, kSCTIMER_CenterAlignedPwm, PWM_FREQ_HZ, sctimerClock, &s_eventNumberOutputB) == kStatus_Fail)
{
SetDeviceStatusWithErrorNumber(ERR_BIT_INIZIALISATION, 3);
return ;
}
pwmParam.output = PWM_OUT_C;
pwmParam.level = kSCTIMER_HighTrue;
pwmParam.dutyCyclePercent = 0;
if (SCTIMER_SetupPwm(SCT0, &pwmParam, kSCTIMER_CenterAlignedPwm, PWM_FREQ_HZ, sctimerClock, &s_eventNumberOutputC) == kStatus_Fail)
{
SetDeviceStatusWithErrorNumber(ERR_BIT_INIZIALISATION, 4);
return ;
}
// Enable interrupt flag for event associated with out 4, we use the interrupt to update dutycycle
EnableInterruptPWM();
// Receive notification when event is triggered
SCTIMER_SetCallback(SCT0, SCTIMER_HANDLER, s_eventNumberOutputA);
NVIC_SetPriority(SCT0_IRQn, IRQPRIO_MOTOR_PWM); // prio[0..7] 0 is highest // Enable at the NVIC
EnableIRQ(SCT0_IRQn);
// Start the 32-bit unify timer
SCTIMER_StartTimer(SCT0, kSCTIMER_Counter_U);
And this is how I Update the pulse width(called from interrupt):
DisableInterruptPWM();
SCTIMER_UpdatePwmDutycycle(SCT0, PWM_OUT_A, (UInt8)(pwmA*100), s_eventNumberOutputA);
SCTIMER_UpdatePwmDutycycle(SCT0, PWM_OUT_B, (UInt8)(pwmB*100), s_eventNumberOutputB);
SCTIMER_UpdatePwmDutycycle(SCT0, PWM_OUT_C, (UInt8)(pwmC*100), s_eventNumberOutputC);
EnableInterruptPWM();
For any ideas I am very thankful.
Rico