2024-03-21 12:33 PM - last edited on 2024-04-09 06:18 AM by Amel NASRI
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.
2024-03-21 02:48 PM
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.
2024-10-28 12:37 PM
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));
}
2024-10-28 02:43 PM - edited 2024-10-28 02:50 PM
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.
2024-10-28 10:12 PM - edited 2024-10-28 10:15 PM
/* 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;
}