cancel
Showing results for 
Search instead for 
Did you mean: 

Output Compare Formula [STM32H7]

bnguy.1
Associate III

I'm using TIM5CH3 to toggle an I/O, but AN4013 doesn't list a formula for the Output Compare, so I'm using the Timer Base Generator in Section 2.2:

Update_event = TIM_CLK/((PSC + 1)*(ARR + 1)*(RCR + 1))

With TIM5 CLK of 60Mhz, Prescaler 60-1, and ARR 10-1 (I don't see any Repetition Counter so I'll assume that's 0.) I would expect this to toggle every 1.2usec (857k), however the actual output toggle every 5usec (200khz).

I've been playing with the numbers, but can't for the life of me see how the above can result in that frequency. Not sure if related, but if I set the 32-bit Pulse register to above 10 the output does not toggle.

  htim5.Instance = TIM5;
  htim5.Init.Prescaler = 60-1;
  htim5.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim5.Init.Period = 10-1;
  htim5.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim5.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim5) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim5, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_OC_Init(&htim5) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim5, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_TOGGLE;
  sConfigOC.Pulse = 0x00000001;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  if (HAL_TIM_OC_ConfigChannel(&htim5, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
  {
    Error_Handler();
  }
  __HAL_TIM_ENABLE_OCxPRELOAD(&htim5, TIM_CHANNEL_3);
 

0693W000001rdUeQAI.png

4 REPLIES 4
TDK
Guru

> With TIM5 CLK of 60Mhz, Prescaler 60-1, and ARR 10-1 (I don't see any Repetition Counter so I'll assume that's 0.) I would expect this to toggle every 1.2usec (857k)

How are you getting that? I get 60 MHz / 60 / 10 = 100 kHz.

> however the actual output toggle every 5usec (200khz).

So actual rate is off by 2. Likely your timer clock is twice what you think it is. If your APB prescaler is not 1, then the timer clock is double what the APB clock is.

> Not sure if related, but if I set the 32-bit Pulse register to above 10 the output does not toggle.

The output will toggle when TIM->CNT equals sConfigOC.Pulse which never happens when TIM->ARR < sConfigOC.Pulse.

If you feel a post has answered your question, please click "Accept as Solution".
bnguy.1
Associate III

Thanks, the clock configuration for TIM3,4,5 looks correct at 60Mhz. What else could be causing it to be off by 2x?

0693W000001reTcQAI.png

TIM5 is in APB1 domain. Don't confuse TIM5 with LPTIM5, that's an entirely different timer.

APB1 Timers are clocked by rcc_timx_ker_ck , see Ratio between clock timer and pclk table in RM.

JW

Thanks, the clock was 120Mhz, so the timer output is good! Maybe a little TOO good, I can't seem to stop it. I have an adc configured to trigger based on the Timer 5's Trigger event, and I see the dma update the memory with new adc data.. however, despite stopping the Timer's base and OC, I still see new data coming into the buffer! Any insight what might be happening?

memset(&ADC_DATA[0], 0xff, sizeof(ADC_DATA));
//    SCB_InvalidateDCache_by_Addr((uint32_t*)&ADC_DATA[0], sizeof(ADC_DATA));
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)&ADC_DATA[0], ADC_CONVERTED_DATA_BUFFER_SIZE);
HAL_TIM_OC_Start_IT(&htim5 , TIM_CHANNEL_3 );
while ( 1 )
{
                HAL_Delay(100);
 		if ( 1 == HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin ) )
 		{
 		 	HAL_TIM_Base_Stop(&htim5); 
 		 	HAL_TIM_OC_Stop_IT(&htim5, TIM_CHANNEL_3);  	 
 		}
 	}