cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_DELAY_Microsecond

Lex Trc
Associate II
Posted on July 31, 2017 at 15:40

Hi,

I have a Nucleo L053R8, I need of delay of 2 microseconds, but HAL_Delay_Microsecond in NucleoWorkspace not exist.

I changed:

   HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

in

   HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000000);

for use HAL_Delay but the process is blocced.

How is can resolved?

7 REPLIES 7
Posted on July 31, 2017 at 15:55

You can't interrupt at 1 MHz, it just causes the processor to saturate with useless work.

Use a TIM that you have free running at 1 MHz or higher to get some level of precision/granularity, and then delta the TIM->CNT over the period of interest.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
William Warnots
Associate III
Posted on August 03, 2017 at 10:32

is strange , if you are not able to use a TIM or HAL_Delay();  use a simply For(i=0,I<65000,i++) according with your MCU Frequency , not a asmart solution make the STM work for that, but might be work.

Muhammad Moiz khan
Associate II
Posted on August 03, 2017 at 10:46

You cannot have a delay of 1 us using Systick timer reason as mentioned above by Clive, maximum that I was able to achieve was 10us using 48Mhz HSE on STM32F0 series. You can use NOP statement and then check the delay on oscilloscope or use TIM.

Regards,

Muhammad Moiz khan.
Posted on August 03, 2017 at 19:06

Hello!

I use it with no problems

Try it..You can change the resolution or change timer to TIM7

APB1_FREQ is the frequency of APB1 timers clock

Init the timer first ..

Not for multithread use

//##############################################################################

void TIM6Init()//as counter only.

{    

    RCC->APB1ENR |= RCC_APB1ENR_TIM6EN;//enable clock    

    TIM6->CR2=0;//slave reset

    TIM6->DIER=0;//interrupts and DMA disable

    TIM6->SR=0;//clear flag

    TIM6->EGR=0;//No generate trigger

    TIM6->CNT=0;//Clear counter

    TIM6->PSC=APB1_FREQ/1000000-1;// 1 microsecond counter resolution

    TIM6->ARR=65535;//reload counter full range

    TIM6->CR1=1;//enable timer    

}

//##############################################################################

void DelayMicrosecond(unsigned short microsecond)

{

    TIM6->EGR=1;//reinitialize time counter , prescaler

    while(TIM6->CNT<microsecond);//wait...

}

//##############################################################################   
Posted on August 03, 2017 at 19:40

My preference would be for a free-running counter, at higher frequency, not reset/restarted, as this would be both interrupt and thread safe. In non-CM0 cases DWT_CYCCNT is also very effective, being 32-bit and at high rate, and can span multiple seconds (close to a minute at 72 MHz as I recall).

The NOP or for() spin-loops also won't shorten post-interrupt service, and can also be dependent on compiler and optimization selections.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
S.Ma
Principal
Posted on August 03, 2017 at 22:21

It depends the purpose of the microsecond delay, and if it is a min value or not.

For example, a SW delay can easily be tuned using a static variable, you run the SW delay with biggest number within a Systick 1 msec which enables you to calculate the right unit for 2 us. This of course is resource free and has limitations.

HW assisted delays can be done with either timer or even SPI by the time it takes to push a byte without any GPIO wired to it. Numerous solutions exist. If the microsecond delay is used to toggle GPIOs, Timers and their output compare function would make more sense. So... it depends what's for...

Lex Trc
Associate II
Posted on September 12, 2017 at 14:16

thanks everybody