Skip to main content
Matt Blessinger
Associate III
March 17, 2017
Question

STM32F446 inverse PWM duty cycle?!?

  • March 17, 2017
  • 3 replies
  • 1467 views
Posted on March 17, 2017 at 02:59

The original post was too long to process during our migration. Please click on the attachment to read the original post.
    This topic has been closed for replies.

    3 replies

    nichtgedacht
    Associate III
    March 17, 2017
    Posted on March 17, 2017 at 16:04

    Hi

    GB_H_Pin GA_L_Pin  GA_H_Pin  GC_L_Pin  GC_H_Pin  GB_L_Pin

    GA_H_GPIO_Port GC_L_GPIO_Port

    are looking special.

    Was it generated with CubeMX?

    The names do not match for one member each.

    Dieter

    Matt Blessinger
    Associate III
    March 17, 2017
    Posted on March 17, 2017 at 16:37

     ,

     ,

    Hi,

    Yes, I generated the initial code with CubeMX. I've since then modified the timer initialization functions to what I previously tested on the Nucleo. The names are defined in main.h and shown below.

    ♯ define

    GC_L_Pin GPIO_PIN_7

    ♯ define

    GC_L_GPIO_Port GPIOC

    ♯ define

    GC_L TIM_CHANNEL_2

    ♯ define

    GC_H_Pin GPIO_PIN_8

    ♯ define

    GC_H_GPIO_Port GPIOC

    ♯ define

    GC_H TIM_CHANNEL_3

    ♯ define

    GB_L_Pin GPIO_PIN_9

    ♯ define

    GB_L_GPIO_Port GPIOC

    ♯ define

    GB_L TIM_CHANNEL_4

    ♯ define

    GB_H_Pin GPIO_PIN_9

    ♯ define

    GB_H_GPIO_Port GPIOA

    ♯ define

    GB_H TIM_CHANNEL_2

    ♯ define

    GA_L_Pin GPIO_PIN_10

    ♯ define

    GA_L_GPIO_Port GPIOA

    ♯ define

    GA_L TIM_CHANNEL_3

    ♯ define

    GA_H_Pin GPIO_PIN_11

    ♯ define

    GA_H_GPIO_Port GPIOA

    ♯ define

    GA_H TIM_CHANNEL_4
    S.Ma
    Principal
    March 17, 2017
    Posted on March 17, 2017 at 18:35

    In an old code, the PWM generation was setup like this:

    void SetTimerOutputCC_SingleEdge(Timer_t* Timer, u32 n, u32 Value_lsb) {

    Timer->EdgesSize[n] = 0; // Non zero triggers the DMA mode for multiple pulses

    Timer->EdgesTableAdr[n] = 0;

    TIM_OCInitTypeDef OC;

    TIM_OCStructInit(&OC);

    OC.TIM_OCMode = TIM_OCMode_PWM2;

    OC.TIM_OutputState = TIM_OutputState_Enable;

    OC.TIM_Pulse = Value_lsb;

    OC.TIM_OCPolarity = TIM_OCPolarity_Low;

    TIM_OCnInit(Timer->TIM, n, &OC);

    }

    Or when starting the code, after enabling the timer clock, force a

    __HAL_RCC_TIM1_FORCE_RESET();

    __HAL_RCC_TIM1_RELEASE_RESET();

    This should make the peripheral closer to the HW Power on reset.

    Or the PWM depends on the initial pin level?

    Matt Blessinger
    Associate III
    March 18, 2017
    Posted on March 18, 2017 at 20:06

    I tried the force reset and release to no success. In fact, it made it so channels 2 & 3 were always inverted instead of randomly inverting.

    waclawek.jan
    Super User
    March 17, 2017
    Posted on March 17, 2017 at 23:27

     

    TIM_OC_InitTypeDef

    sConfigOC;

    [...]

      sConfigOC.

    OCMode

    = TIM_OCMODE_PWM1;

      sConfigOC.

    Pulse

    = 10;

      sConfigOC.

    OCPolarity

    = TIM_OCPOLARITY_HIGH;

      sConfigOC.

    OCFastMode

    = TIM_OCFAST_DISABLE;

     

    if

    (HAL_TIM_PWM_ConfigChannel(&htim, &sConfigOC, TIM_CHANNEL_2)

    You have to have initialized *all* members of

     

    TIM_OC_InitTypeDef struct before calling HAL_TIM_PWM_ConfigChannel. This for Advanced timers (i.e. TIM1 and TIM8) among others includes the polarity of the inverted output. You surely already know this from the concise and detailed 'library' manual.

    JW

    Matt Blessinger
    Associate III
    March 18, 2017
    Posted on March 18, 2017 at 20:09

    Well, that did it! The CubeMX code has the inverted output config calls as well, but I deleted them since I didn't have them during my testing. Thank you!

    This is the code that works:

      sConfigOC.

    OCMode

    = TIM_OCMODE_PWM1;

      sConfigOC.

    Pulse

    = 100;

      sConfigOC.

    OCPolarity

    = TIM_OCPOLARITY_HIGH;

      sConfigOC.

    OCNPolarity

    = TIM_OCNPOLARITY_HIGH;

      sConfigOC.

    OCFastMode

    = TIM_OCFAST_DISABLE;

      sConfigOC.

    OCIdleState

    = TIM_OCIDLESTATE_RESET;

      sConfigOC.

    OCNIdleState

    = TIM_OCNIDLESTATE_RESET;