0
\$\begingroup\$

I was using STM32F4 and i had created a microsecond delay function using DWT register. And now, i'm using STM32F030F4P6. And this MCU has not DWT register. So, i tried to create another delay function.

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

when i try to set delay to 1 second, i get 8 seconds. And when i try to set delay to 500 miliseconds i get 4 seconds. There is always a 1:8 ratio

note: the VAL register is automatically loaded with the value of the LOAD register when the timer is enabled.

EDIT: I added these lines of code to choose HCLK as a source and now it works. (HCLK/8 is default value. so i need this configuration):

SysTick->CTRL &= ~SYSTICK_CLKSOURCE_HCLK_DIV8;

SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK;
\$\endgroup\$
3
  • 1
    \$\begingroup\$ github.com/pyrohaz/STM32F0-Discovery-SysTick-Tutorial/blob/… asm volatile("nop"); would be the call you want to look at \$\endgroup\$
    – Sorenp
    Oct 17, 2019 at 11:15
  • 2
    \$\begingroup\$ @Sorenp see static.docs.arm.com/ddi0419/d/DDI0419D_armv6m_arm.pdf page A6-146, " The timing effects of including a NOP instruction in code are not guaranteed. It can increase execution time, leave it unchanged, or even reduce it. NOP instructions are therefore not suitable for timing loops.". Nops are not a good way to create a delay, especially in a microcontroller with 11 timers. \$\endgroup\$
    – Colin
    Oct 17, 2019 at 13:32
  • \$\begingroup\$ Thanks for the info @Colin much appreciated :) \$\endgroup\$
    – Sorenp
    Oct 18, 2019 at 5:57

1 Answer 1

1
\$\begingroup\$

System Clock is clocked by AHB bus divided by 8. So simply divide the result by 8. Or better yet, when you currently multiply by 8000, multiply only by 1000.

\$\endgroup\$
1
  • \$\begingroup\$ thanks i made some changes and now it works \$\endgroup\$ Oct 18, 2019 at 11:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.