Skip to main content
YSall.1
Senior
June 13, 2022
Question

How can I get minimum nanosecond delay with a Nucleo F446RE using a Cortex M4 180 Mhz?

  • June 13, 2022
  • 5 replies
  • 4909 views

Hi everyone,

I am using a nucleo F446RE using a Cortex M4 180 Mhz, and I have a problem when I try to get nano second delays.

void delay (uint16_t delay)
 
{
 
	__HAL_TIM_SET_COUNTER(&htim1,0);
 
	while(__HAL_TIM_GET_COUNTER(&htim1)<delay);
 
 
 
}

In the main, while(1):

HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_1);
 
	 delay(1);

I used this function to set the delay according to the clock. I set up the APB2 clock corresponding to the timer 1 at 100 MHz, logically the function delay(1) would get me a delay of 10 ns, but the problem is that I only have a minimum value of 530 ns delay.

What would be a better method to get a minimum delay without using assembly language?

This topic has been closed for replies.

5 replies

Uwe Bonnes
Chief
June 13, 2022

You will not get reproducable delays. Flash prefetch for the called function, stack setup inside the called function, bus contention and code alignment will lead to substantial variance.

YSall.1
YSall.1Author
Senior
June 14, 2022

Even without a function called, for exemple using this inside the while doesn't get me results, the minimum I got was 460 ns:

timer_val=__HAL_TIM_GET_COUNTER(&htim1);
 
while (1)
{
if (__HAL_TIM_GET_COUNTER(&htim1)-timer_val>=1)
	 {
		HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_1);
		timer_val=__HAL_TIM_GET_COUNTER(&htim1);
	 }
}

So the best way to obtain what I want is in assembly ?

MM..1
Chief III
June 13, 2022

Try change delay func to inline

YSall.1
YSall.1Author
Senior
June 14, 2022

I tried but there is no effect

Uwe Bonnes
Chief
June 14, 2022

Multiple pin operations will prolong that operation in a much more controlled way. However the jump at the end of the loop will eat up a hard controllable number of cycles.

while(1) {
SetPin(pin);
SetPin(pin);
SetPin(pin);
ClearPin(pin);
ClearPin(pin);
}

YSall.1
YSall.1Author
Senior
June 14, 2022

Thank for your response but there is a deeper problem as I tried to see the resolution of the while loop using a LL-Driver instruction to get a more optimised way, but the minimum of the while loop is 344 ns (I saw it on a 100MHz Oscilloscope), I used this code:

LL_GPIO_TogglePin(GPIOA, LL_GPIO_PIN_1);

So how can I increase the while loop frequency?

YSall.1
YSall.1Author
Senior
June 14, 2022

To precise that there is a net performance between LL and HAL as for HAL instruction I got around 500ns

waclawek.jan
Super User
June 14, 2022

Enable compiler optimization.

JW

Bob S
Super User
June 14, 2022

And disable interrupts. Any interrupt occurring during your tight loop (including SysTick) will ruin your tightly coded delays.

MM..1
Chief III
June 15, 2022

STM F4 can do your job explained generator with 11,1ns granularity and use timer + pwm + DMA

For perfect timing you need HSE.

YSall.1
YSall.1Author
Senior
June 16, 2022

I will try, knowing that my goal is to reach a 100 ns resolution delay