2
\$\begingroup\$

I'm making locked antiphase drive for motor control on STM32F4 board. Im configuring Timer4's 4 channels to be in pairs, ch2 inverse of ch1 and ch4 inverse of ch3. Each pair will control its own motor.

    TIM_TimeBaseInitTypeDef TIM_BaseStruct;
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
    TIM_BaseStruct.TIM_Prescaler = 0;
    TIM_BaseStruct.TIM_CounterMode = TIM_CounterMode_CenterAligned1;
    TIM_BaseStruct.TIM_Period = 3999;
    TIM_BaseStruct.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_BaseStruct.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM4, &TIM_BaseStruct);
    TIM_Cmd(TIM4, ENABLE);

    GPIO_InitTypeDef GPIO_InitStruct;

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

    GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_TIM4);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_TIM4);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_TIM4);

    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_Init(GPIOD, &GPIO_InitStruct);

    TIM_OCInitTypeDef TIM_OCStruct;

    TIM_OCStruct.TIM_OCMode = TIM_OCMode_PWM2;
    TIM_OCStruct.TIM_OutputState = TIM_OutputState_Enable;

    // Channel 1
    TIM_OCStruct.TIM_OCPolarity = TIM_OCPolarity_Low;
    TIM_OCStruct.TIM_Pulse = 1999;
    TIM_OC1Init(TIM4, &TIM_OCStruct);
    TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);

    // Channel 2
    TIM_OCStruct.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OCStruct.TIM_Pulse = 1999;
    TIM_OC2Init(TIM4, &TIM_OCStruct);
    TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);

    // Channel 3
    TIM_OCStruct.TIM_OCPolarity = TIM_OCPolarity_Low;
    TIM_OCStruct.TIM_Pulse = 1999;
    TIM_OC3Init(TIM4, &TIM_OCStruct);
    TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);

    // Channel 4
    TIM_OCStruct.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OCStruct.TIM_Pulse = 1999;
    TIM_OC4Init(TIM4, &TIM_OCStruct);
    TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);

For changing duty cycle I will use

void changePulseCH1_2(uint32_t pulse)
{
    uint32_t prim;
    prim = __get_PRIMASK();
    __disable_irq();

    TIM4->CCR1 = pulse + DEADTIME;
    TIM4->CCR2 = pulse - DEADTIME;

    if (!prim) __enable_irq();
}

As I understand, TIM_OCPolarity_Low will make channel output be first low and then high, while TIM_OCPolarity_High will be exactly opposite, thus making locked antiphase. Testing on LEDs seems to confirm that setting same pulse for both of them makes one LED dimmer and other LED brighter, if pulse isn't 50%. What I don't understand is the significance of the line

TIM_OCStruct.TIM_OCMode = TIM_OCMode_PWM2;

What is the difference between the PWM1 and PWM2? I can't seem to find reliable source of information on this, what is its purpose?

Also, what is the difference between three possible Center Aligned modes? There are

TIM_CounterMode_CenterAligned1
TIM_CounterMode_CenterAligned2
TIM_CounterMode_CenterAligned3

Standard Peripheral Library is very vague about it:

TIM_CounterMode : specifies the Counter Mode to be used This parameter can be one of the following values:

  • TIM_CounterMode_Up : TIM Up Counting Mode
  • TIM_CounterMode_Down : TIM Down Counting Mode
  • TIM_CounterMode_CenterAligned1 : TIM Center Aligned Mode1
  • TIM_CounterMode_CenterAligned2 : TIM Center Aligned Mode2
  • TIM_CounterMode_CenterAligned3 : TIM Center Aligned Mode3

Thank you!

\$\endgroup\$
0
\$\begingroup\$

Quotes from the reference manual:

PWM mode 1
In upcounting, channel is active as long as TIMx_CNT < TIMx_CCR1 else inactive.
In downcounting, channel is inactive as long as TIMx_CNT > TIMx_CCR1 else active.

PWM mode 2
In upcounting, channel is inactive as long as TIMx_CNT < TIMx_CCR1 else active.
In downcounting, channel is active as long as TIMx_CNT > TIMx_CCR1 else inactive.

and

Center-aligned mode 1
The counter counts up and down alternatively.
Output compare interrupt flags of channels configured in output (CCxS=00 in TIMx_CCMRx register) are set only when the counter is counting down.

Center-aligned mode 2
The counter counts up and down alternatively.
Output compare interrupt flags of channels configured in output (CCxS=00 in TIMx_CCMRx register) are set only when the counter is counting up.

Center-aligned mode 3
The counter counts up and down alternatively.
Output compare interrupt flags of channels configured in output (CCxS=00 in TIMx_CCMRx register) are set both when the counter is counting up or down

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.