Electrical – the least amount of time that I can measure using STM32F1x Timers

armcortex-m3stm32stm32f10x

I am working with STM32F107 on a custom board, the board has 12MHz crystal. I want to measure 1 micro second precisely, but I am unable to do so.
I have used STM32CubeMX to set the core clock at 72MHz which is it's maximum speed.
Trying to use Timer 3 in upcounting mode and toggling a GPIO in the ISR of the Timer.
These are my settings

void MX_TIM3_Init(void)
{
  TIM_ClockConfigTypeDef sClockSourceConfig;
  TIM_MasterConfigTypeDef sMasterConfig;

  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 0;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 72-1;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  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();
  }

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  HAL_TIM_Base_Start(&htim3);
  HAL_TIM_Base_Start_IT(&htim3);
}

I get a approximate 2 micro second pulse on the scope.
Tried fiddling around with the prescaler and period values but I am unable to get a 1 micro second pulse.

Best Answer

Since your controller is running at 72 MHz, the minimum delay between two consecutive instructions is 1/72 µs. The internal flash is not fast enough for that, you must run your program from the internal RAM to achieve this.

To obtain a delay of exactly 1 µs, create a sequence of assembly instructions that takes exactly 71 cycles to complete. Get rid of HAL, it's too complicated and hence unpredictable for this kind of work. The trivial approach would be a sequence of 71 NOP instructions, but that's a bit wasteful. In order to construct some loop in inline assembly, you'd have to consult the cycle counts of processor instructions and addressing modes. To run it from flash, take flash latency and prefetch buffer behavior into account, as described in chapter 3.3.3 of the reference manual.