Page 1 of 2

how to PWM Frequency stm32duino and resolution

Posted: Thu Jun 11, 2020 3:36 pm
by navanod
First time post here for me so hi:)

I am looking on any tips to set up PWM frequency with a blue pill in the current arduino stm32duino release. I was throw a little by trying to get pwmWrite to work.

I can see that this basic example works

Code: Select all

 analogWrite(A1, 127); // Start PWM on A1, at 1000 Hz with 50% duty cycle
  analogWriteFrequency(200000); // Set PMW period to 2000 Hz instead of 1000
and to set resolution I am using

Code: Select all

analogWriteResolution (16);
Any other tips for making nice PWM with the stm32?

Re: how to PWM Frequency stm32duino and resolution

Posted: Thu Jun 11, 2020 4:30 pm
by fpiSTM

Re: how to PWM Frequency stm32duino and resolution

Posted: Fri Jun 12, 2020 8:31 am
by navanod
Thank you fpiSTM that pretty much answers everything:) - Not sure how I missed those examples

Re: how to PWM Frequency stm32duino and resolution

Posted: Fri Jun 12, 2020 8:40 am
by fpiSTM
welcome ;)

Re: how to PWM Frequency stm32duino and resolution

Posted: Sat Jun 13, 2020 12:43 pm
by mrburnette
navanod wrote:
Fri Jun 12, 2020 8:31 am
Thank you fpiSTM that pretty much answers everything:) - Not sure how I missed those examples
When you install board/library support in the ArduinoIDE, you often get examples too.

Image

Good luck,

Ray

Re: how to PWM Frequency stm32duino and resolution

Posted: Fri Jul 10, 2020 1:22 pm
by navanod
Thanks Ray, I had not installed them..still getting used to using the stm32 but now loving that hardware PWM:)

Re: how to PWM Frequency stm32duino and resolution

Posted: Sun Jul 19, 2020 6:49 pm
by seandepagnier
This is working great, but how do I use the library to set complementary outputs with adjustable deadtime?

Re: how to PWM Frequency stm32duino and resolution

Posted: Mon Jul 20, 2020 3:19 am
by dannyf
rather than waiting for someone to write the code for you, take a look at the reference manual and see how it can be done (easily as well).

Re: how to PWM Frequency stm32duino and resolution

Posted: Wed Jul 22, 2020 4:12 pm
by seandepagnier
it seems deadtime is not supported and complementary output is not working either.

So I have now:

Code: Select all

  
  pwm_handle.Instance = TIM1;
  pwm_handle.Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
  pwm_handle.hdma[0] = NULL;
  pwm_handle.hdma[1] = NULL;
  pwm_handle.hdma[2] = NULL;
  pwm_handle.hdma[3] = NULL;
  pwm_handle.hdma[4] = NULL;
  pwm_handle.hdma[5] = NULL;
  pwm_handle.hdma[6] = NULL;
  pwm_handle.Lock = HAL_UNLOCKED;
  pwm_handle.State = HAL_TIM_STATE_RESET;

  /* Configure timer with some default values */
  pwm_handle.Init.Prescaler = 0;
  pwm_handle.Init.Period = 400;
  pwm_handle.Init.CounterMode = TIM_COUNTERMODE_UP;
  pwm_handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  pwm_handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;

  TIM_HandleTypeDef *h = &pwm_handle;
  enableTimerClock(h);
  HAL_TIM_Base_Init(h);

  /* Configure some default values. Maybe overwritten later */
  TIM_OC_InitTypeDef channelOC;
  channelOC.OCMode = TIMER_NOT_USED;
  channelOC.Pulse = __HAL_TIM_GET_COMPARE(h, TIM_CHANNEL_1);
  channelOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  channelOC.OCFastMode = TIM_OCFAST_DISABLE;
  channelOC.OCIdleState = TIM_OCIDLESTATE_RESET;
  channelOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
  channelOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
  channelOC.OCMode = TIM_OCMODE_PWM1;

  HAL_TIM_PWM_ConfigChannel(h, &channelOC, TIM_CHANNEL_1);

  /* Set the Break feature & Dead time */
  TIM_BreakDeadTimeConfigTypeDef sBreakConfig;
  sBreakConfig.BreakState       = TIM_BREAK_DISABLE;
  sBreakConfig.DeadTime         = 14;
  sBreakConfig.OffStateRunMode  = TIM_OSSR_ENABLE;
  sBreakConfig.OffStateIDLEMode = TIM_OSSI_ENABLE;
  sBreakConfig.LockLevel        = 0;//TIM_LOCKLEVEL_1;  
  sBreakConfig.BreakPolarity    = TIM_BREAKPOLARITY_LOW;  // does matter?
  sBreakConfig.AutomaticOutput  = TIM_AUTOMATICOUTPUT_ENABLE;
  
  HAL_TIMEx_ConfigBreakDeadTime(h, &sBreakConfig);
  LL_TIM_SetPrescaler(TIM1, 0);
  
  
  
  __HAL_TIM_SET_AUTORELOAD(&pwm_handle, 400); // switch to 20khz
    __HAL_TIM_SET_COMPARE(&pwm_handle, TIM_CHANNEL_1, 400-65);
    
    
    pinmap_pinout(digitalPinToPinName(PA8), PinMap_PWM);  
   HAL_TIM_PWM_Start(&pwm_handle, TIM_CHANNEL_1);

  pinmap_pinout(digitalPinToPinName(PB13), PinMap_PWM);
  HAL_TIMEx_PWMN_Start(&pwm_handle, TIM_CHANNEL_1);
  
  

Re: how to PWM Frequency stm32duino and resolution

Posted: Thu Nov 26, 2020 6:16 pm
by alfrond
Hi!

I am too trying to get pwm/compl outuputs/dead time to run on the STM32.
I'm not very experienced, but I see in the timer.h (if I remember correctly) that some timer/pwm functions doesn't seem implemented.
I have thouroughly read the STM32 reference manual, and it is quite clearly stated what registers to set and how to get it running. My problem now is that I'm not sure how to correctly write directly to registers using arduino IDE with the STM32dino..

Did you make progress?
Anyone who can help out? I know all the registers to use, I get bit arithmetics, but what is the syntax?


seandepagnier wrote:
Wed Jul 22, 2020 4:12 pm
it seems deadtime is not supported and complementary output is not working either.

So I have now:

Code: Select all

  
  pwm_handle.Instance = TIM1;
  pwm_handle.Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
  pwm_handle.hdma[0] = NULL;
  pwm_handle.hdma[1] = NULL;
  pwm_handle.hdma[2] = NULL;
  pwm_handle.hdma[3] = NULL;
  pwm_handle.hdma[4] = NULL;
  pwm_handle.hdma[5] = NULL;
  pwm_handle.hdma[6] = NULL;
  pwm_handle.Lock = HAL_UNLOCKED;
  pwm_handle.State = HAL_TIM_STATE_RESET;

  /* Configure timer with some default values */
  pwm_handle.Init.Prescaler = 0;
  pwm_handle.Init.Period = 400;
  pwm_handle.Init.CounterMode = TIM_COUNTERMODE_UP;
  pwm_handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  pwm_handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;

  TIM_HandleTypeDef *h = &pwm_handle;
  enableTimerClock(h);
  HAL_TIM_Base_Init(h);

  /* Configure some default values. Maybe overwritten later */
  TIM_OC_InitTypeDef channelOC;
  channelOC.OCMode = TIMER_NOT_USED;
  channelOC.Pulse = __HAL_TIM_GET_COMPARE(h, TIM_CHANNEL_1);
  channelOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  channelOC.OCFastMode = TIM_OCFAST_DISABLE;
  channelOC.OCIdleState = TIM_OCIDLESTATE_RESET;
  channelOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
  channelOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
  channelOC.OCMode = TIM_OCMODE_PWM1;

  HAL_TIM_PWM_ConfigChannel(h, &channelOC, TIM_CHANNEL_1);

  /* Set the Break feature & Dead time */
  TIM_BreakDeadTimeConfigTypeDef sBreakConfig;
  sBreakConfig.BreakState       = TIM_BREAK_DISABLE;
  sBreakConfig.DeadTime         = 14;
  sBreakConfig.OffStateRunMode  = TIM_OSSR_ENABLE;
  sBreakConfig.OffStateIDLEMode = TIM_OSSI_ENABLE;
  sBreakConfig.LockLevel        = 0;//TIM_LOCKLEVEL_1;  
  sBreakConfig.BreakPolarity    = TIM_BREAKPOLARITY_LOW;  // does matter?
  sBreakConfig.AutomaticOutput  = TIM_AUTOMATICOUTPUT_ENABLE;
  
  HAL_TIMEx_ConfigBreakDeadTime(h, &sBreakConfig);
  LL_TIM_SetPrescaler(TIM1, 0);
  
  
  
  __HAL_TIM_SET_AUTORELOAD(&pwm_handle, 400); // switch to 20khz
    __HAL_TIM_SET_COMPARE(&pwm_handle, TIM_CHANNEL_1, 400-65);
    
    
    pinmap_pinout(digitalPinToPinName(PA8), PinMap_PWM);  
   HAL_TIM_PWM_Start(&pwm_handle, TIM_CHANNEL_1);

  pinmap_pinout(digitalPinToPinName(PB13), PinMap_PWM);
  HAL_TIMEx_PWMN_Start(&pwm_handle, TIM_CHANNEL_1);