Skip to main content
Associate
July 24, 2025
Question

STM32U585: Generate two separate PWM signals

  • July 24, 2025
  • 3 replies
  • 308 views

Hello,

 

I have a STM32U585CIUA and generate a PWM with 125Hz 2ms high and 6ms low phase on TIM1 on PA2.

I would like to start another PWM with TIM2 50Khz 1us high and 19us low on the falling edge of PA2, which is then stopped after 200 cycles.

In all my setting attempts, however, TIM2 starts before TIM no matter how it is configured and even if I set the HAL for TIM2 after TIM1 in the code...

Can anyone help me with this?

Dave

 

static void MX_TIM1_Init(void)
{

 /* USER CODE BEGIN TIM1_Init 0 */

 /* USER CODE END TIM1_Init 0 */

 TIM_ClockConfigTypeDef sClockSourceConfig = {0};
 TIM_MasterConfigTypeDef sMasterConfig = {0};
 TIM_OC_InitTypeDef sConfigOC = {0};
 TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};

 /* USER CODE BEGIN TIM1_Init 1 */

 /* USER CODE END TIM1_Init 1 */
 htim1.Instance = TIM1;
 htim1.Init.Prescaler = 319;
 htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
 htim1.Init.Period = 3999;
 htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
 htim1.Init.RepetitionCounter = 0;
 htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
 if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
 {
 Error_Handler();
 }
 sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
 if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
 {
 Error_Handler();
 }
 sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC1REF;
 sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_OC1REF;
 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
 if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
 {
 Error_Handler();
 }
 sConfigOC.OCMode = TIM_OCMODE_PWM1;
 sConfigOC.Pulse = 1000;
 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;
 if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
 {
 Error_Handler();
 }
 sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
 sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
 sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
 sBreakDeadTimeConfig.DeadTime = 0;
 sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
 sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
 sBreakDeadTimeConfig.BreakFilter = 0;
 sBreakDeadTimeConfig.BreakAFMode = TIM_BREAK_AFMODE_INPUT;
 sBreakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE;
 sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH;
 sBreakDeadTimeConfig.Break2Filter = 0;
 sBreakDeadTimeConfig.Break2AFMode = TIM_BREAK_AFMODE_INPUT;
 sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
 if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN TIM1_Init 2 */

 /* USER CODE END TIM1_Init 2 */
 HAL_TIM_MspPostInit(&htim1);

}

/**
 * @brief TIM2 Initialization Function
 * None
 * @retval None
 */
static void MX_TIM2_Init(void)
{

 /* USER CODE BEGIN TIM2_Init 0 */

 /* USER CODE END TIM2_Init 0 */

 TIM_ClockConfigTypeDef sClockSourceConfig = {0};
 TIM_SlaveConfigTypeDef sSlaveConfig = {0};
 TIM_MasterConfigTypeDef sMasterConfig = {0};
 TIM_OC_InitTypeDef sConfigOC = {0};

 /* USER CODE BEGIN TIM2_Init 1 */

 /* USER CODE END TIM2_Init 1 */
 htim2.Instance = TIM2;
 htim2.Init.Prescaler = 159;
 htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
 htim2.Init.Period = 19;
 htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
 htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
 if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
 {
 Error_Handler();
 }
 sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
 if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)
 {
 Error_Handler();
 }
 sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET;
 sSlaveConfig.InputTrigger = TIM_TS_ITR2;
 if (HAL_TIM_SlaveConfigSynchro(&htim2, &sSlaveConfig) != HAL_OK)
 {
 Error_Handler();
 }
 sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
 if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
 {
 Error_Handler();
 }
 sConfigOC.OCMode = TIM_OCMODE_PWM1;
 sConfigOC.Pulse = 1;
 sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
 sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
 if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN TIM2_Init 2 */

 /* USER CODE END TIM2_Init 2 */
 HAL_TIM_MspPostInit(&htim2);

}

 

 

3 replies

TDK
Super User
July 24, 2025

I don't see any code actually starting the timers.

You could set one timer as a slave that gets started when the first timer starts.

 

"If you feel a post has answered your question, please click ""Accept as Solution""."
ProNet36Author
Associate
July 24, 2025

Hi,

attached function hows start the PWM's...

No matter what I do or set, Timer 2 always starts first... :(

 

void LEDDecay_CaptureAndAverage(void)
{
 // 1) Summen-Puffer löschen
 for (uint16_t i = 0; i < DECAY_POINTS; i++) {
 sumBuffer[i] = 0;
 }

 for (uint8_t rep = 0; rep < DECAY_REPEATS; rep++) {
 decayDone = false;

 // 2) LEDs via TIM1-PWM einschalten (erster OC1REF → TRGO2)
 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_SET);
 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
 HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);

 // 3) TIM2 als Slave-Reset & Sampling starten
 __HAL_TIM_SET_COUNTER(&htim2, 0);
 HAL_TIM_Base_Start(&htim2);
 HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_3); // Debug-Puls auf PA2

 // 4) ADC1 + DMA starten (200 Samples via TIM2_TRGO)
 HAL_ADC_Start_DMA(&hadc1, (uint32_t*)decayBuffer, DECAY_POINTS);

 // 5) Warten auf DMA-Complete
 while (!decayDone) {
 __WFI();
 }
 decayDone = false;

 // 6) Cleanup nach Messreihe
 HAL_ADC_Stop_DMA(&hadc1);
 HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_3);
 HAL_TIM_Base_Stop(&htim2);
 HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);
 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_RESET);
 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);

 // 7) Werte aufsummieren
 for (uint16_t i = 0; i < DECAY_POINTS; i++) {
 sumBuffer[i] += decayBuffer[i];
 }
 }

 // 8) Durchschnitt berechnen
 for (uint16_t i = 0; i < DECAY_POINTS; i++) {
 avgBuffer[i] = (uint16_t)(sumBuffer[i] / DECAY_REPEATS);
 }
 decayDone = true;
}

Hi 

Associate II
July 25, 2025

You need to call HAL_TIM_Base_Start(&htim1) before HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1).

Technical Moderator
July 29, 2025
"To give better visibility on the answered topics, please click on ""Accept as Solution"" on the reply which solved your issue or answered your question.Saket_Om"