cancel
Showing results for 
Search instead for 
Did you mean: 

Nucleo F411: 3 synchronized PWM with different number of pulses

algis
Associate II
Posted on August 14, 2015 at 15:22

Hello,

is there a way to make 3 synchronous PWM outputs of 100kHzthat each of output would generate particular amount of pulses and then stop?

I saw:  https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2Fcortex_mx_stm32%2FStop%20PWM%20output%20after%20N%20steps&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=2411

However I noticed that only advanced timers are able to do repetitions and in F411 there are just two of them. I also tried to find any F4 series MC with 3 advanced timers but I couldn't find any example or F7 series, only F3 series, which might be too slow. It would be the best to find any microcontrollers already on Discovery or Nucleo boards.

8 REPLIES 8
Posted on August 14, 2015 at 17:18

Yeah, I think you'd just want to use ONE timer (@ 100 KHz) and manage the pulse width modulation under interrupt (CCRx = 0 = OFF)

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
algis
Associate II
Posted on August 14, 2015 at 18:56

Just to be sure, what I meant was that each channel would generate different number of pulses and then stop, but all outputs would start at once. 

Posted on August 14, 2015 at 20:33

Ok, and you've got 4 channels outputting with exact the same periodicity, so the ONE timebase is programmed at 100 KHz, and the FOUR channels (CCR1,CCR2,CCR3,CCR4) values get modulated between 0% (OFF) and 50% (ON 50/50) at your discretion. You get to count off the number you want. I'd perhaps use a down count, non-zero count fires the pulse in the next iteration.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
algis
Associate II
Posted on August 14, 2015 at 23:49

You mean to use additional programmatic counter which increments in each Timer counter overflow interupt? And once it was counted enough pulses, particular PWM output will be turned off programmatically?

Posted on August 15, 2015 at 00:46

Yes, managed, in software, in the update interrupt, occurring at 100 KHz periodicity.. The same interrupt can handle all 3-4 channels. With the shadow registers (no preload) the new values will be adopted at the NEXT update, and thus won't glitch based on interrupt latency.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
algis
Associate II
Posted on August 15, 2015 at 14:06

I see. And what if I have to change frequencies of each PWM channel? And also it would be good to count repetitions of the PWM ''packets'' probably in Interrupt with software counter as you suggested. Then I have to use separate timers and synchronize them all?

Posted on August 15, 2015 at 18:06

Different, independent, frequencies? Yes, you'd need different timers for that, synchronizing them will be a challenge. You'd want to find slave timers that have a common master.

Maybe you can nail down a specification that defines the range of frequencies, the combinations of different frequencies on different channels, and the range in the number of pulses, and anticipated repetition or rate of change in those signals.

Consider if custom logic would be a more effective solution.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
algis
Associate II
Posted on September 07, 2015 at 09:00

Hello, thank you for your answers.

What I am doing right now is using one timer to mask the other in example timer 2 is enabled if external signal is high. I am also using both outputs of the timer2 to generate PWM with one of the outputs inverted. The timer2 initialization.

/* TIM2 init function */

void MX_TIM2_Init(void)

{

  TIM_ClockConfigTypeDef sClockSourceConfig;

  TIM_SlaveConfigTypeDef sSlaveConfig;

  TIM_MasterConfigTypeDef sMasterConfig;

  TIM_OC_InitTypeDef sConfigOC;

  htim2.Instance = TIM2;

  htim2.Init.Prescaler = 0;

  htim2.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED1;

  htim2.Init.Period = 104;

  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

  HAL_TIM_Base_Init(&htim2);

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;

  HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig);

  HAL_TIM_PWM_Init(&htim2);

  sSlaveConfig.SlaveMode = TIM_SLAVEMODE_GATED;

  sSlaveConfig.InputTrigger = TIM_TS_TI1FP1;

  sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_RISING;// Polarity

  sSlaveConfig.TriggerFilter = 0;

  HAL_TIM_SlaveConfigSynchronization(&htim2, &sSlaveConfig);

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

  HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig);

  sConfigOC.OCMode = TIM_OCMODE_PWM1;

  sConfigOC.Pulse = 53;

  sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW;

  sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;

  HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2);

  sConfigOC.Pulse = 51;

    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

  HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_3);

}

The desired goal would be to put both timer2 outputs to low if external signal is low and generate PWM if the external signal is high.

The way it is now implemented is due to the fact that I am using several timers (with different frequencies and different amount of pulses) and it would be good to keep the synchronization of all timers with external signal. So the question is if there could be any timer configuration which would automatically disable (turn to low) both of PWM outputs if timer enable signal is low (in the manner with this external signal which I am using)?