Skip to main content
mboua
Associate
February 10, 2020
Solved

how to turn off both complementary pwm at the same time

  • February 10, 2020
  • 3 replies
  • 2114 views

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 

This topic has been closed for replies.
Best answer by mboua

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

3 replies

waclawek.jan
Super User
February 10, 2020

> 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
mbouaAuthorBest answer
Associate
February 10, 2020

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

waclawek.jan
Super User
February 11, 2020

Forcing commutation in EGR is a nice touch.

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

JW