cancel
Showing results for 
Search instead for 
Did you mean: 

stm32 timer taking longer than expected

VYoun
Associate III

Hello,

I am using STM32H753 and STM32CubeMX. In my application I use four timers timers. Two timers are used to generate PWM signaly, and the other two are used to generate time base interrupt. All four timers are synced together using the internal triggers.

From the two timers, which generate time base interrupt one of them is used to control sampling rate of an ADC and the other is used to turn of all four timers after a specific time.

I run the above process, running the two PWMs and the other two timers, multiple times. The first time everything works perfectly. Timers start together and run the adc and PWMS, and the last timers turns everything off at the right time.

The problem is that the second time that I run the process, the timer that runs the ADC works longer than expected. In other words, when the last timer turns all timers off, the timer that controls the ADC has worked longer than expected (some milli seconds, but in my application this produces a problem)

My code is relatively long, so I include the setup code for the timers, the code to start the timers, and the interrupt handler code.

Any help is greatly appreciated, since I am new in this field and require help for my work project.

Thank you in advance for your help.

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 = 9999;
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim1.Init.Period = 16799;
  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_ENABLE;
  sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 8399;
  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();
  }
  sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW;
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != 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.Break2State = TIM_BREAK2_DISABLE;
  sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH;
  sBreakDeadTimeConfig.Break2Filter = 0;
  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);
 
}
  
static void MX_TIM3_Init(void)
{
 
  /* USER CODE BEGIN TIM3_Init 0 */
 
  /* USER CODE END TIM3_Init 0 */
 
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_SlaveConfigTypeDef sSlaveConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
 
  /* USER CODE BEGIN TIM3_Init 1 */
 
  /* USER CODE END TIM3_Init 1 */
  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 9999;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 16799;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sSlaveConfig.SlaveMode = TIM_SLAVEMODE_TRIGGER;
  sSlaveConfig.InputTrigger = TIM_TS_ITR0;
  if (HAL_TIM_SlaveConfigSynchro(&htim3, &sSlaveConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM3_Init 2 */
 
  /* USER CODE END TIM3_Init 2 */
 
}
 
static void MX_TIM4_Init(void)
{
 
  /* USER CODE BEGIN TIM4_Init 0 */
 
  /* USER CODE END TIM4_Init 0 */
 
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_SlaveConfigTypeDef sSlaveConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
 
  /* USER CODE BEGIN TIM4_Init 1 */
 
  /* USER CODE END TIM4_Init 1 */
  htim4.Instance = TIM4;
  htim4.Init.Prescaler = 41999;
  htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim4.Init.Period = 19;
  htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim4) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sSlaveConfig.SlaveMode = TIM_SLAVEMODE_TRIGGER;
  sSlaveConfig.InputTrigger = TIM_TS_ITR0;
  if (HAL_TIM_SlaveConfigSynchro(&htim4, &sSlaveConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM4_Init 2 */
 
  /* USER CODE END TIM4_Init 2 */
 
}
  
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
 
	if (htim->Instance == TIM4) {
 
		HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_13);
 
 
		sdWriteMatrixFloat [adcReadingNo][0] = __HAL_TIM_GET_COUNTER(&htim1);
 
		timer_reg_Val = __HAL_TIM_GET_COUNTER(&htim1);
 
		ad7124_run_continuous_measurement ();
 
 
		adcFloatVal [0] =  ad7124_convert_sample_to_voltage(pAd7124_dev, 4, channel_samples[4]);
		adcFloatVal [1] =  ad7124_convert_sample_to_voltage(pAd7124_dev, 5, channel_samples[5]);
		adcFloatVal [2] =  ad7124_convert_sample_to_voltage(pAd7124_dev, 6, channel_samples[6]);
		adcFloatVal [3] =  ad7124_convert_sample_to_voltage(pAd7124_dev, 7, channel_samples[7]);
 
		adcFloatVal [4] =  ad7124_convert_sample_to_voltage(pAd7124_dev, 11, channel_samples[11]);
		adcFloatVal [5] =  ad7124_convert_sample_to_voltage(pAd7124_dev, 8, channel_samples[8]);
		adcFloatVal [6] =  ad7124_convert_sample_to_voltage(pAd7124_dev, 9, channel_samples[9]);
		adcFloatVal [7] =  ad7124_convert_sample_to_voltage(pAd7124_dev, 10, channel_samples[10]);
 
		tim4Counter = tim4Counter + 1;
 
 
		sdWriteMatrixFloat [adcReadingNo][1] = (adcFloatVal [0]);
		sdWriteMatrixFloat [adcReadingNo][2] = (adcFloatVal [1]);   
		sdWriteMatrixFloat [adcReadingNo][3] = (adcFloatVal [2]);   
		sdWriteMatrixFloat [adcReadingNo][4] = (adcFloatVal [3]);  
 
 
		sdWriteMatrixFloat [adcReadingNo][5] = (adcFloatVal [4]);   
		sdWriteMatrixFloat [adcReadingNo][6] = (adcFloatVal [5]);   
		sdWriteMatrixFloat [adcReadingNo][7] = (adcFloatVal [6]);  
		sdWriteMatrixFloat [adcReadingNo][8] = (adcFloatVal [7]);  
 
		adcReadingNo +=1;
 
		}
	}
 
 
 
 
	if (htim->Instance == TIM3) {
 
 
		HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_14);
 
		if ( doFilterCalibration && filter_is_valid ) { 
 
			HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_14);
 
			HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);
			HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2);
 
 
			HAL_TIM_Base_Stop_IT(&htim4);
 
			HAL_TIM_Base_Stop_IT(&htim3);
 
			doFilterCalibration = false;
 
			if (doRestartFlag == 1) {
				doRestartFlag = 0;
			}
 
			if (doCyclicMsrmnt == 1) {
				setAlarms();
			}
 
			if (doOnetimeMsrmnt == 1) {
 
				timerAdcSwitch = 1;
			}
 
		}
 
		if ((tim3Counter == 16) && (!doFilterCalibration) ) { 
 
			HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_14);
			HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);
			HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2);
 
			HAL_TIM_Base_Stop_IT(&htim4);
			HAL_TIM_Base_Stop_IT(&htim3);
 
			measPerFinSwitch = 1;
 
			}
 
		}
 
		if (!performCalibration) {
 
			tim3Counter = tim3Counter +1;
		}
 
	}
 
}

1 ACCEPTED SOLUTION

Accepted Solutions

Without attempting to understand the details of a problem which is lost in the mist of Cube/HAL, try to generate an update (by setting UG bit in TIMx_EGR) before you enable the timer, or use the reset+trigger slave mode, if your mcu has that.

JW

View solution in original post

2 REPLIES 2

Without attempting to understand the details of a problem which is lost in the mist of Cube/HAL, try to generate an update (by setting UG bit in TIMx_EGR) before you enable the timer, or use the reset+trigger slave mode, if your mcu has that.

JW

Thank you very much for your answer, I reviewed the code and it turned out that the problem was in some of the flags and their initial values. I appreciate your help.

Best regards,

Vouria