Skip to main content
Associate
March 21, 2024
Question

Is there a way to make microsecond delay in freertos

  • March 21, 2024
  • 4 replies
  • 3552 views

I need 40 us delay. I made my own function using timers, which works on NUCLEO, just using it in main. Now that I put my program my circuit, I moved that SPI part on freertos, but now I have problem, because that delay doesnt work anymore. I would use osDelay, but that is only ms and I need us. Why my delay using timers doesnt work and is there any other way to make it. Thank you for help. 

Mijta_0-1711049470365.png

Mijta_1-1711049524663.png

 

 

 

This topic has been closed for replies.

4 replies

Tesla DeLorean
Guru
March 21, 2024

Well resetting at every entry isn't exactly thread safe.

Read the value at entry, and compare the delta, I'd cut-n-paste-n-edit but hard to do with bitmaps.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Visitor II
October 28, 2024

Have exactly same issue when need precise timing in us for SPI communications in RTOS (STM32H743 + HAL). 

have this timDelay_us function in timer 1 but still cant get it working.

 

 

void timDelay_us(uint16_t us){
 uint16_t entryPoint = __HAL_TIM_GET_COUNTER(&htim1);
 //__HAL_TIM_SET_COUNTER(&htim1,0); // set the counter value a 0
 while ((uint16_t)__HAL_TIM_GET_COUNTER(&htim1) < (us + entryPoint)); 
}

 

 

Tesla DeLorean
Guru
October 28, 2024

You have the math backward, compute the delta (now - start), and then compare with the elapsed time delay you're looking for

 

void timDelay_us(uint16_t us){
 uint16_t entryPoint = __HAL_TIM_GET_COUNTER(&htim1);
 while (((uint16_t)__HAL_TIM_GET_COUNTER(&htim1) - entryPoint) < us); 
}

 

The unsigned math should then manage the wrapping transparently.

Here TIM would be maximal (0 .. 0xFFFF), clocking at 1 MHz

Interrupts and context changes will make the time the delay takes a little more complicated, but should be at least as long as requested +/- 1us depending on when you enter. For finer granularity, clock faster.

But you can't use an interrupt at 1 MHz, you'll just saturate the processor.

 

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
QLiu.6
Associate II
October 29, 2024

 

/* timer for nona second, need a hardware 32-bit timer */
#define MY_NS_TIM TIM5
#define MY_NS_TIM_HANDLER htim5

	// nsTmr_t should use 32-bit timer
	typedef uint32_t ns_t;
	typedef struct nsTmr_t
	{
		ns_t tickstart;
		ns_t wait;
	} nsTmr_t;

 

extern TIM_HandleTypeDef MY_NS_TIM_HANDLER;
#define NS_SCALE (1000 / TIM_MHZ) // 1MHZ = 1us = 1000ns
void InitNsTmr()
{
	HAL_TIM_Base_Start(&MY_NS_TIM_HANDLER);
}

void SetNsTmr(nsTmr_t *tmr, ns_t delay)
{
	tmr->tickstart = (ns_t)MY_NS_TIM->CNT;
	tmr->wait = (delay != 0 && delay < NS_SCALE) ? 1 : (ns_t)(delay / NS_SCALE);
}

void ClrNsTmr(nsTmr_t *tmr)
{
	tmr->tickstart = (ns_t)MY_NS_TIM->CNT;
	tmr->wait = 0;
}

int IsNsTmrExpired(nsTmr_t *tmr)
{
	return (tmr->wait != 0) && ((ns_t)((ns_t)MY_NS_TIM->CNT - tmr->tickstart) >= tmr->wait);
}

int IsNsTmrSet(nsTmr_t *tmr)
{
	return tmr->wait;
}

void Delay_ns(ns_t delay)
{
	nsTmr_t tmr;
	SetNsTmr(&tmr, delay);
	while ((ns_t)((ns_t)MY_NS_TIM->CNT - tmr.tickstart) < tmr.wait)
		;
}

ns_t GetNsTmrCnt(nsTmr_t *tmr)
{
	return MY_NS_TIM->CNT - tmr->tickstart;
}