Skip to main content
danny2
Associate
August 31, 2015
Question

STM32F303 - Changing PWM mode on the fly

  • August 31, 2015
  • 2 replies
  • 888 views
Posted on August 31, 2015 at 17:45

Hi,

I use TIM1 PWM in asymmetric mode. I need to switch between 2 software modes : Mode A - CH1/1N asym mode 2, CH3/3N asym mode 2 Mode B - CH1 asym mode 1, CH3 asym mode 2, CH1N/3N off I use HAL for initialization but I need the transition between these 2 modes to be as quick as possible (and HAL is troubling me a bit) : Transition to mode A :

// disable PWMs
htim1.Instance->CCER &= ~( TIM_CCER_CC1E
| TIM_CCER_CC1NE
| TIM_CCER_CC3E
| TIM_CCER_CC3NE );
htim1.Instance->BDTR&= ~TIM_BDTR_MOE;
htim1.Instance->CR1 &= ~TIM_CR1_CEN;
// configure
htim1.Instance->BDTR |= TIM_BDTR_DTG & TIM1_FREQ / DEAD_TIME_INVERSE;
htim1.Instance->CCMR1 |= TIM_CCMR1_OC1M & TIM_OCMODE_ASSYMETRIC_PWM2
| TIM_CCMR1_OC2M & TIM_OCMODE_ASSYMETRIC_PWM2 << 8;
htim1.Instance->CCR1= 0;
htim1.Instance->CCR2= htim1.Instance->ARR;
htim1.Instance->CCR3= x;
htim1.Instance->CCR4= y;
// enable PWMs
htim1.Instance->CCER |= TIM_CCER_CC1E
| TIM_CCER_CC1NE
| TIM_CCER_CC3E
| TIM_CCER_CC3NE;
htim1.Instance->BDTR|= TIM_BDTR_MOE;
htim1.Instance->CR1 |= TIM_CR1_CEN;

Transition to mode B :

// disable PWMs
htim1.Instance->CCER &= ~( TIM_CCER_CC1E
| TIM_CCER_CC1NE
| TIM_CCER_CC3E
| TIM_CCER_CC3NE );
htim1.Instance->BDTR&= ~TIM_BDTR_MOE;
htim1.Instance->CR1 &= ~TIM_CR1_CEN;
// configure
htim1.Instance->BDTR &= ~TIM_BDTR_DTG; 
// remove deadtime
htim1.Instance->CCMR1 |= TIM_CCMR1_OC1M & TIM_OCMODE_ASSYMETRIC_PWM1
| TIM_CCMR1_OC2M & TIM_OCMODE_ASSYMETRIC_PWM1 << 8;
htim1.Instance->CCR1= 300;
htim1.Instance->CCR2= 0;
htim1.Instance->CCR3= htim1.Instance->ARR;
htim1.Instance->CCR4= htim1.Instance->ARR - htim1.Instance->CCR1;
// enable PWMs
htim1.Instance->CCER |= TIM_CCER_CC1E
| TIM_CCER_CC3E;
htim1.Instance->BDTR|= TIM_BDTR_MOE;
htim1.Instance->CR1 |= TIM_CR1_CEN;

The problem is : mode A looks ok, but when in mode B channel 1 stays in asymmetric PWM mode 2. I tried a lot of things, including trying similar code with HAL_PWM_Start/Stop and other things. Sometimes channel 1 switches to asym mode 1 as needed, but it looks like chance. One more thing : I initialize all channels in PWM asym mode 2 with HAL. But when I initialize CH1/2 in mode 1 and CH3/4 in mode 2, it works better, I don't know why. Thanks in advance.
    This topic has been closed for replies.

    2 replies

    waclawek.jan
    Super User
    August 31, 2015
    Posted on August 31, 2015 at 22:19

    htim1.Instance->CCMR1 |= TIM_CCMR1_OC1M & TIM_OCMODE_ASSYMETRIC_PWM1
    | TIM_CCMR1_OC2M & TIM_OCMODE_ASSYMETRIC_PWM1 << 8;

    The

    TIM_CCMR1_OC1M

    bits are already all set from being set for PWM2 in previous step. You perhaps wanted to use = rather than |=. Also, aren't the channel3 bits in CCMR2? (I personally woldn't mix in the constants defined in CUBE (e.g.

    TIM_OCMODE_ASSYMETRIC_PWM1

    ) and would stick to the constants defined in the basic CMSIS device header stm32f3xx.h, but that's me.) JW
    danny2
    danny2Author
    Associate
    September 1, 2015
    Posted on September 01, 2015 at 08:47

    Indeed, the problem was the operator...

    Thank you very much ! I feel a bit stupid x)