cancel
Showing results for 
Search instead for 
Did you mean: 

Is there a way to make microsecond delay in freertos

Mijta
Associate

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

 

 

 

4 REPLIES 4

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
Up vote any posts that you find helpful, it shows what's working..

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

 

 

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
Up vote any posts that you find helpful, it shows what's working..
QLiu.6
Associate II

 

/* 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;
}