cancel
Showing results for 
Search instead for 
Did you mean: 

how to turn off both complementary pwm at the same time

mboua
Associate

I am using STM32F4 to drive a 3 phase BLDC motor and i'm using TIM1 peripheral to 

generate 6-step PWM(complementary pwm) but when i change the configuration and i disable 1 channel it takes some time to go low which causing problems (you can check the photos in the links below )

https://ibb.co/fv3PGJ0

https://ibb.co/6sTsYDM

https://ibb.co/MkFLttv

also here is my configuration:

  TIM1->PSC=0;

TIM1->ARR=800;      

TIM1->CCR1=400;

TIM1->CCR2=400;

TIM1->CCR3=400;

TIM1->CCMR1 |= TIM_CCMR1_OC1PE | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC2PE | TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2; 

  TIM1->CCMR2 |= TIM_CCMR2_OC3PE | TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2 ;

TIM1->CCER |= TIM_CCER_CC1E | TIM_CCER_CC1NE | TIM_CCER_CC2E | TIM_CCER_CC2NE | TIM_CCER_CC3E | TIM_CCER_CC3NE ;//!CH and CH

TIM1->CR2 |= TIM_CR2_OIS1N | TIM_CR2_OIS2N | TIM_CR2_OIS3N | TIM_CR2_CCPC ;

TIM1->BDTR |= TIM_BDTR_MOE | TIM_BDTR_OSSR;

TIM1->CR1 |= TIM_CR1_DIR; // DOWN COUNTER

TIM1->EGR |= TIM_EGR_UG;

TIM1->CR1 |= TIM_CR1_CEN; 

and this the code to change the config:

  TIM1->EGR |= TIM_EGR_UG;

TIM1->CCER &=~ ( TIM_CCER_CC2E | TIM_CCER_CC3E | TIM_CCER_CC3NE);

TIM1->CCER |= TIM_CCER_CC1NE | TIM_CCER_CC1E; //AH + !AH

TIM1->CCER |= TIM_CCER_CC2NE;//BL

is there a way to turn off both complementary pwm at the same time 

1 ACCEPTED SOLUTION

Accepted Solutions
mboua
Associate

thank you for your answer but setting the pull down will not solve the problem ( link 1 in my post shows the result where the GPIO configured with pull down)

but i found a better solution :

it's better to change CCxM than disabling the output, updating CCxM bits to 0b100 or 0b101, which forces them to inactive or active levels but there is a case where you need the 2 channels (complentary pwm )to be low. so the solution for this is to change the polarity of one channel by setting CCxNP bit in the CCER register here is the modification in the code ( this part is only for 1 step)

TIM1->CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 ; 
TIM1->CCMR1 |=  TIM_CCMR1_OC2M_2 ;
TIM1->CCMR1 &=~  TIM_CCMR1_OC2M_1 ;
 
TIM1->CCMR2 |= TIM_CCMR2_OC3M_2 ;
TIM1->CCMR2 &=~ TIM_CCMR2_OC3M_1 ;
TIM1->CCER |= TIM_CCER_CC3NP;
TIM1->EGR |= TIM_EGR_COMG; // this is only for 1 step

or you can do this instead

TIM1->CCMR1=0x00004868;
TIM1->CCMR2=0x00000048;
TIM1->CCER=0x00000D55 ;
TIM1->EGR |= TIM_EGR_COMG; // this is only for 1 step

View solution in original post

3 REPLIES 3

> TIM1->CCER &=~ ( TIM_CCER_CC2E | TIM_CCER_CC3E | TIM_CCER_CC3NE);

> TIM1->CCER |= TIM_CCER_CC1NE | TIM_CCER_CC1E; //AH + !AH

> TIM1->CCER |= TIM_CCER_CC2NE;//BL

Don't do this in two steps, as there's a moment when the outputs are floating. Read in CCER into a temporary variable, change it, and then write it back.

> is there a way to turn off both complementary pwm at the same time

By clearing both CCER.CCxE and CCER.CCxNE you "turn them off"; but the exact behaviour depends on other register bits, see Output control bits for complementary OCx and OCxN channels with break feature table in RM. Unfortunately that table is not very clear; particularly "output disabled" means, that the pins are no longer driven by the timer, but the pullups/pulldowns set in GPIO are still active (and this may be the answer to your initial question, too).

JW

mboua
Associate

thank you for your answer but setting the pull down will not solve the problem ( link 1 in my post shows the result where the GPIO configured with pull down)

but i found a better solution :

it's better to change CCxM than disabling the output, updating CCxM bits to 0b100 or 0b101, which forces them to inactive or active levels but there is a case where you need the 2 channels (complentary pwm )to be low. so the solution for this is to change the polarity of one channel by setting CCxNP bit in the CCER register here is the modification in the code ( this part is only for 1 step)

TIM1->CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 ; 
TIM1->CCMR1 |=  TIM_CCMR1_OC2M_2 ;
TIM1->CCMR1 &=~  TIM_CCMR1_OC2M_1 ;
 
TIM1->CCMR2 |= TIM_CCMR2_OC3M_2 ;
TIM1->CCMR2 &=~ TIM_CCMR2_OC3M_1 ;
TIM1->CCER |= TIM_CCER_CC3NP;
TIM1->EGR |= TIM_EGR_COMG; // this is only for 1 step

or you can do this instead

TIM1->CCMR1=0x00004868;
TIM1->CCMR2=0x00000048;
TIM1->CCER=0x00000D55 ;
TIM1->EGR |= TIM_EGR_COMG; // this is only for 1 step

Forcing commutation in EGR is a nice touch.

Please select your post as Best so that the thread is resolved.

JW