I've configured my STM32F407VG (STM32F4Discovery) TIM4 timer using the following code:

void TIM4_Init(void)
    // Configure TIM4 for PWM
    hTim4.Instance = TIM4;
    hTim4.Init.Prescaler= 42000 - 1; // (84MHz / 42000 = 2KHz)
    hTim4.Init.CounterMode = TIM_COUNTERMODE_UP;
    hTim4.Init.Period = 2000 - 1; // Period = 2000 -> 1 second
    hTim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

    // Configure channels 1-4 for TIM4,
    // each channel is mapped to a GPIO pin
    TIM_OC_InitTypeDef oc_config;
    oc_config.OCMode = TIM_OCMODE_PWM1;
    oc_config.Pulse = 1000;
    oc_config.OCNIdleState = TIM_OCNIDLESTATE_RESET;
    oc_config.OCIdleState = TIM_OCIDLESTATE_RESET;
    oc_config.OCFastMode = TIM_OCFAST_DISABLE;

    HAL_TIM_PWM_ConfigChannel(&hTim4, &oc_config, TIM_CHANNEL_1);
    HAL_TIM_PWM_ConfigChannel(&hTim4, &oc_config, TIM_CHANNEL_3);

    // Flip the OC polarity for channels 2 and 4
    oc_config.OCPolarity = TIM_OCPOLARITY_LOW;
    HAL_TIM_PWM_ConfigChannel(&hTim4, &oc_config, TIM_CHANNEL_2);
    HAL_TIM_PWM_ConfigChannel(&hTim4, &oc_config, TIM_CHANNEL_4);

    // I want to shift channel 1-4 90 degrees apart...
    HAL_TIM_PWM_Start(&hTim4, TIM_CHANNEL_1);
    HAL_TIM_PWM_Start(&hTim4, TIM_CHANNEL_2);
    HAL_TIM_PWM_Start(&hTim4, TIM_CHANNEL_3);
    HAL_TIM_PWM_Start(&hTim4, TIM_CHANNEL_4);

Each channel is mapped to a GPIO pin, with the intention of driving a stepper motor.

I would like to generate a signal, with a duty cycle of 25% each, where the phases have been shifted 90 degrees apart.

How do I go about shifting the phases on the 4 channels?

Should I setup another timer, and use it as an interrupt upon which I can call HAL_TIM_PWM_Start() for each channel at the appropriate timing?

  • 1
    \$\begingroup\$ It is feasible to get two phases from a timer, but IIRC, 4 will be tricky. Why do you want to use only one timer (STM32F4's have quite a lot)? Are you willing to take interrupts for some of the channels? Exactly which STM32F4 are you using? \$\endgroup\$ – gbulmer Oct 26 '15 at 11:35
  • \$\begingroup\$ I'm using a STM32F407VG, on the STM32F4 Discovery board. \$\endgroup\$ – josef.van.niekerk Oct 26 '15 at 15:11
  • \$\begingroup\$ My understanding is that three-phase PWM is possible with "advanced timers", TIM1 and TIM8, but I don't thing 4-phase is with simple PWM use \$\endgroup\$ – Scott Seidman Oct 26 '15 at 15:26
  • \$\begingroup\$ Spent last night looking deeper into this, and it doesn't seem phase shifting on all 4 channels on a single timer is possible at all. Except for flipping the OC polarity, there's nothing more to be done, so this seems to be a dead end. \$\endgroup\$ – josef.van.niekerk Oct 27 '15 at 6:21

My understanding is that three-phase PWM is possible with "advanced timers", TIM1 and TIM8, but I don't think 4-phase is with simple PWM use. That said, isn't 180 degrees simply the negative of your 0 degree, and similar with 270 and 90? Thus, you need to generate TWO phases, and just change the OC active state for two of your four channels on any four-channel timer.


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.