Showing results for 
Search instead for 
Did you mean: 

Six step using timer synchronization for sensorless BLDC motor control


Hi All

I hope someone of ST Micro's engineer show this.

I'm working on for sensorless BLDC motor control using six step method. 

I use STM32G474 Nucleo board for test.

To realize the six step control, I use TIM1 and TIM2 synchronization for commutation. The modulation I use is high side sync rectification PWM modulation. Approximately, six step control works. However, there are some problems that timing at the time of commutation is not match as below figure.. I will upload the waveform of the PWM signal recorded by Saleae Logic.


In my application, not use Hall sensor. The target output is that the PWM switches correctly during commutation as shown in the figure below.


In the figure is writen that "write CCxE, CCxNE, and OCxM for next step" after a COM event for the next step.

I wrote the code according to this, but it cannot be improved by any combination of settings.

So, I want to ask to ST Micro engineer, if possible please show me a simple sample code.

My code for set the next step is like this,

void MC_SixStep_SetNextStep(MC_SixStep_t *p)
  switch (p->sixStepCount)
  case 0:
    /* UH, VL */
    htim1.Instance->CCER &= (uint16_t) ~TIM_CCER_CC2NE;
    __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, p->pwm.period);
    htim1.Instance->CCER |= (uint16_t) TIM_CCER_CC3NE;
  case 1:
    /* UH, WL */
    htim1.Instance->CCER &= (uint16_t) ~TIM_CCER_CC1E;
    htim1.Instance->CCER &= (uint16_t) ~TIM_CCER_CC1NE;
    __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, p->pwm.width - 1);
    htim1.Instance->CCER |= (uint16_t) TIM_CCER_CC2E;
    htim1.Instance->CCER |= (uint16_t) TIM_CCER_CC2NE;
  case 2:
    /* VH, WL */
    htim1.Instance->CCER &= (uint16_t) ~TIM_CCER_CC3NE;
    __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, p->pwm.period);
    htim1.Instance->CCER |= (uint16_t) TIM_CCER_CC1NE;
  case 3:
    /* VH, UL */
    htim1.Instance->CCER &= (uint16_t) ~TIM_CCER_CC2E;
    htim1.Instance->CCER &= (uint16_t) ~TIM_CCER_CC2NE;
    __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, p->pwm.width - 1);
    htim1.Instance->CCER |= (uint16_t) TIM_CCER_CC3E;
    htim1.Instance->CCER |= (uint16_t) TIM_CCER_CC3NE;
  case 4:
    /* WH, UL */
    htim1.Instance->CCER &= (uint16_t) ~TIM_CCER_CC1NE;
    __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, p->pwm.period);
    htim1.Instance->CCER |= (uint16_t) TIM_CCER_CC2NE;
  case 5:
    /* WH, VL */
    __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, p->pwm.width - 1);
    htim1.Instance->CCER |= (uint16_t) TIM_CCER_CC1E;
    htim1.Instance->CCER |= (uint16_t) TIM_CCER_CC1NE;
    htim1.Instance->CCER &= (uint16_t) ~TIM_CCER_CC3E;
    htim1.Instance->CCER &= (uint16_t) ~TIM_CCER_CC3NE;
  p->sixStepCount %= 6;

Laurent Ca...
Lead II

Dear  @Kenji​ 

Sorry for the late answer.

Do you have still this problem to solve?

And just in case, if not, do not hesitate to share the final solution you found. Thanks by advance.

Best regards

Laurent Ca...

Dear Laurent-san

I haven't solved it. I also referred to the MCSDK code, but since it was written in the same way, I think it's not a code problem. Is it the limit of the device?

Apart of this, the problem I have now is that the PWM duty is less than 10%, it will not be output as expected. I am using STM32G474RE in commutation PWM mode. The PWM frequency is 28kHz. Is there a known problem with this device?

Kenji I'm having a similar issue with the PWM not working correctly when < 15% duty where it looks good most of the time and then every so often (every 10 - 30 secs) It doesn't not commutate correctly. Has anyone else run into this? I can't find any errata related to it. Very strange that it is not consistent and only happens with very low duty cycles. STM32G491.

Issue where it doesn't commutate correctlyIssue where it doesn't commutate correctlyClose up view of the glitchClose up view of the glitch