0
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ The least amount you can measure is 0. Do you mean highest Resolution (smallest \$\Delta t\$)? \$\endgroup\$ – Curd Mar 23 '17 at 14:28
  • \$\begingroup\$ The title of your question doesn't match the description. Are you trying to use your STM32F107 to measure a pulse or are you trying to use it to make a pulse? \$\endgroup\$ – brhans Mar 23 '17 at 14:51
  • \$\begingroup\$ I want to know the resolution and I am trying to make a pulse. \$\endgroup\$ – user10170 Mar 23 '17 at 15:08
  • 1
    \$\begingroup\$ You aren't measuring time . instead you are using the timer to generate a pulse. Two different things. \$\endgroup\$ – dannyf Mar 23 '17 at 15:11
  • 1
    \$\begingroup\$ To get exactly 1µs you need to generate the pulse directly from the timer. A general-purpose timer should be able to do that, though you may be limited in the choice of the output pin. \$\endgroup\$ – starblue Mar 23 '17 at 19:37
1
\$\begingroup\$

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.

\$\endgroup\$
  • 3
    \$\begingroup\$ Why use a software delay when you have hardware timers? \$\endgroup\$ – Colin Mar 26 '17 at 8:35
  • \$\begingroup\$ Yes, this method is also feasible. But I was looking for a way to achieve this with a timer. \$\endgroup\$ – user10170 Mar 26 '17 at 14:02
  • 1
    \$\begingroup\$ The interrupt system is not fast enough for this kind of accuracy. Interrupt entry takes about 12 cycles under ideal conditions. With flash prefetch, possibly interrupting an unaligned access, etc, it could easily reach 18. That's already 0.25 µs late, before you even start loading the registers necessary to get any real work done. The latency can also become substantially lower, down to about 6 cycles, or 0.08 µs, when the inetrrupt occurs at the "lucky spots" before or after another interrupt (late arriving or tail chaining cases) \$\endgroup\$ – berendi Mar 27 '17 at 12:22
  • 1
    \$\begingroup\$ To generate a pulse you could probably do without an interrupt and just get the timer hardware to do it, depending on the part and pins available. \$\endgroup\$ – Colin Mar 27 '17 at 20:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.