2
votes

I am a little bit confused regarding Cortex system timer on Cortex-M4 CPU.

Let's say, we have following configuration:

  • 16MHz HSI as a clock source;
  • AHB1 prescaler sets to 1 (i.e. HSI divided by 1);

It means that main system bus (i.e. AHB1 or AHB) runs with the speed of 16 000 000 ticks per second. As far as I am concerned, system timer (so called SysTick) runs with the speed of main system bus, so it should count up to 16 000 000 each second. That seems obvious, but when I look at the Clock tree diagram in STM32F407xx reference manual I see this:

enter image description here

It looks like the system timer runs with the speed: (main system bus speed) / 8.

Is it true? I have configured system timer to generate interrupt each 16 000 000 ticks. Based on the configuration provided above (i.e. HSI as a clock source and AHB1 prescaler = 1) it generates interrupt each second, which toggles LED on and off. I have tried to measure the time between "blinks" and it seems to be exactly 1s. If there would be this prescaler (i.e. /8) then LED should toggle each 8s.

Below You can find code, which configures system clock source and system timer.

  • HSI frequency = 16 [MHz]
  • SYSTICKS_COUNT = 16 000 000
void system_clock_init(void)
{
    LL_RCC_HSI_Enable();
    while (LL_RCC_HSI_IsReady() != 1) {
        ;
    }

    LL_FLASH_SetLatency(LL_FLASH_LATENCY_0);

    LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
    LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI);
    while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI) {
        ;
    }

    LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
    LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
}



void system_clock_systick_config_init(void)
{
    SysTick_Config(SYSTICKS_COUNT);
}



void SysTick_Handler(void)
{
    led_toggle(LED_PIN_BOARD_GREEN);
}

1
"I have configured system timer to generate interrupt each 16 000 000 ticks." How? You include no code, and it's quite possible that it's somehow misconfigured, or that configuration is not what you assume it to be (e.g. takes into account that /8 divider).domen
Sure, I have not included any code, because it seemed to be obvious for me. Let me edit that :)JStand Jakub Standarski
What happens if you change LL_RCC_SYSCLK_DIV_1 to LL_RCC_SYSCLK_DIV_8? At what frequency does the LED blink? Does it answer your question?Codo
Look at the below answer, problem is hidden there :)JStand Jakub Standarski

1 Answers

3
votes

The Reference Manual states at the end of the section "6.2 Clocks":

The RCC feeds the external clock of the Cortex System Timer (SysTick) with the AHB clock (HCLK) divided by 8. The SysTick can work either with this clock or with the Cortex clock (HCLK), configurable in the SysTick control and status register.

According to the STM32 Cortex-M4 programming manual Bit 2 of the SysTick control register (STK_CTRL) selects the clock source:

Bit 2 CLKSOURCE: Clock source selection
0: AHB/8
1: Processor clock (AHB)

According to the same manual, the default value should be 0 (using AHB/8). Apparently somewhere in your code this bit is set to 1 !?!