cancel
Showing results for 
Search instead for 
Did you mean: 

What is the problem with this delay function?

ahmetgunduz
Associate III

Hi,

i'm trying to create a delay function for microsecond delays. But it doesn't work. I couldn't understand where the problem is. Could you please let me know?

(i'm using stmf030f4)

edit: To understand where the problem is i'm trying to create a milisecond delay function. And i set delay to 1000 miliseconds. But i see 8 seconds as a result. (and if set delay to 500 i see 4 seconds delay )

void delay_ticks(uint32_t ticks)
 
{
 
SysTick->LOAD = ticks;
 
SysTick->VAL = 0;
 
SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;
 
// COUNTFLAG is a bit that is set to 1 when counter reaches 0.
 
// It's automatically cleared when read.
 
while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0);
 
SysTick->CTRL = 0;
 
}
 
 
 
static inline void delay_ms(uint32_t ms)
 
{
 
delay_ticks((ms * 8000)); // number of ms*8000000 can overflow so i use 8000 instead of (ms * 8000000) / 1000)
 
}

 0690X00000AqQO3QAN.png0690X00000AqQNyQAN.png

1 ACCEPTED SOLUTION

Accepted Solutions

thank you now it works fine. i added these.

SysTick->CTRL &= ~SYSTICK_CLKSOURCE_HCLK_DIV8;
SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK;

View solution in original post

6 REPLIES 6
berendi
Principal

The subexpression (us * 8000000) would overflow whenever us > 536 (2^32 / 8000000), because us is a 32 bit integer. Try

delay_ticks(us * 8);

instead.

Thanks, i edited post. Can you take a look again please?

turboscrew
Senior III

Note that systick is 24-bit. And with 8 MHz systick clock, 8000 = 1 ms. One second (0x7A1200) _should_ fit, though.

You should cast the 64-bit uint to 32-bit before writing it into the reload register.

i changed uint64_t to uint32_t. But still i see the same thing. When i change

delay_ticks((ms * 8000))

this line with

delay_ticks((ms * 8000))

this, it works properly. But i don't understand why there is a 1/8 ratio

turboscrew
Senior III

Maybe you should check from the generated code, that the clocks ate, indeed, set up the way the picture shows. Especially check the systick clock divisor selection bit.

I recall that bit defines whether the systick runs in the bus clock speed or if the clock is divided by 8. At least Atollic debugger shows the HW registers.

thank you now it works fine. i added these.

SysTick->CTRL &= ~SYSTICK_CLKSOURCE_HCLK_DIV8;
SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK;