cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F446 inverse PWM duty cycle?!?

Matt Blessinger
Associate III
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.
7 REPLIES 7
nichtgedacht
Senior
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

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
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?

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

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.

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;
Posted on April 07, 2017 at 03:30

I had the exactly same problem as OP, and I fixed the problem too. OCNPolarity was problem. I only missed that field in the previous code.