cancel
Showing results for 
Search instead for 
Did you mean: 

How to setting TIM CHx/CHxN for six step BLDC motor control?

Kenji1
Senior

I want to control BLDC motor in six step method using STM32G474RE (nucleo board). 

I'm using TIM1 CHx/CHxN complementary PWM output for 6 pwm signal, like below:

 0693W000008zFe0QAE.pngThe problem I have is that the PWM output does not switch synchronously when switching steps, like below:

0693W000008zFePQAU.pngThe desired switch looks like this:

0693W000008zFhdQAE.pngHow can I synchronaize the PWM when switching the steps, with STM32G474 MPU?

Please give me some advice.

My setting for TIM1 PWM:

 0693W000008zFtqQAE.png0693W000008zG5VQAU.pngAnd, a part of code for six step:

void MC_NEXT_step(mc_six_step_t *p)

{

    switch (p->step_count)

    {

    case 0:

        HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_3);

        HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_3);

        __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, p->compare_value);

        HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);

        HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1);

        break;

    case 1:

        HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_2);

        __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, p->pwm.period);

        HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_3);

        break;

    case 2:

        HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);

        HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_1);

        __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, p->compare_value);

        HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);

        HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_2);

        break;

    case 3:

        HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_3);

        __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, p->pwm.period);

        HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1);

        break;

    case 4:

        HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2);

        HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_2);

        __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, p->compare_value);

        HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);

        HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_3);

        break;

    case 5:

        HAL_TIMEx_PWMN_Stop(&htim1, TIM_CHANNEL_1);

        __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, p->pwm.period);

        HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_2);

        break;

    default:

        break;

    }

}

15 REPLIES 15

Hi Javier-san

#.1 The way to set low both PWM-UL and PWM-UH is to write code like this:

    htim1.Instance->CCER &= (uint16_t) ~TIM_CCER_CC1E;
    htim1.Instance->CCER &= (uint16_t) ~TIM_CCER_CC1NE;

​But this code not not switch properly like below:

0693W000008zvUWQAY.png#2. To switch properly, I can use this code.

      TIM1->CCMR1 &= TIM_CCMR1_OC2M;
      TIM1->CCMR1 |= TIM_OCMODE_FORCED_INACTIVE;

But when use this code, the PWM output cannot be restarted as shown in the figure.

@Kenji​  what if you use TIM_OCMODE_INACTIVE?

This would not force the channel inactive untill next commutation event.

we dont need to firmware by ourselves, lets talk

Javier-san

I use for PWM-UH/HL

for off:

      TIM1->CCMR1 &= TIM_CCMR1_OC2M;
      TIM1->CCMR1 |= TIM_OCMODE_INACTIVE;

for on:

      TIM1->CCMR1 |= TIM_OCMODE_ACTIVE;

and the result is as bellow. It works correctly only in the two steps of starting the drive.

0693W000008zvvIQAQ.png

sorry @Kenji​ thats all i remember without getting my hands in bldc again.

Hope you break trough this issues ;)

i would play a bit with the enable/disable and force inactives....

we dont need to firmware by ourselves, lets talk
Karthik DM
Associate III

I think your triggering the required channel for every case. you need to stop the third floating channel in every case.

Kenji1
Senior

Hi Karthik-san

The combination of these registers in TIM1 and the functions used for commutation updates changes the situation.

I don't know the best combination for now. PWMs are not synchronized.

0693W00000AM3F8QAL.png

/***************************************/
/*   Disabling OCx and OCNx outputs    */
/***************************************/
	
/* Disable the Channel: Reset the CC1E Bit */
 TIM1->CCER &= (uint16_t) ~TIM_CCER_CC1E;
	
/* Disable the Channel: Reset the CC1E Bit */
 TIM1->CCER &= (uint16_t) ~TIM_CCER_CC1NE;
	
#elif defined (SET_CHANNEL_TO_INACTIVE_STATE)  /* not DISABLING_CHANNELS_OUTPUTS */
	
/****************************************/
/*  Using OCxM bits to inactive channel */
/****************************************/
	
/* Reset the OC1M bits in the CCMR1 register */
TIM1->CCMR1 &= TIM_CCMR1_OC2M;
   
/* Configure the OC2M bits in the CCMRx register to inactive mode*/
TIM1->CCMR1 |= TIM_OCMODE_FORCED_INACTIVE;

I just want to do this, using STM32 MPU.

That all PWMs are synchronized on commutation timing.

0693W00000AM3GpQAL.png