cancel
Showing results for 
Search instead for 
Did you mean: 

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

YSall.1
Senior

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?

26 REPLIES 26
Uwe Bonnes
Principal III

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.

MM..1
Chief II

Try change delay func to inline

I tried but there is no effect

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 ?

Uwe Bonnes
Principal III

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);
}

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?

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

Enable compiler optimization.

JW

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