Конфигурация входной частоты таймера STM32 (PCLKx_Timer) - PullRequest
0 голосов
/ 09 мая 2020

У меня проблема с настройкой частотного входа таймера. Я пару раз прочитал справочное руководство, а затем поискал в Интернете решение.

template <uintptr_t BASE>
void hsi_config(Config config) {
    auto base = reinterpret_cast<volatile RCC_TypeDef *>(BASE);
    base->CR |= RCC_CR_HSION;
    while (!(base->CR & RCC_CR_HSIRDY))
        ;

    // config flash latency
    FLASH->ACR |= config.ahb_flash_latency;

    // for now always use TIMPRE = 0
    base->DCKCFGR1 &= ~RCC_DCKCFGR1_TIMPRE;
    base->CFGR |= (config.ahb_prescaler << 4U) | (config.apb1_prescaler << 10U) | (config.apb2_prescaler << 13U);

    // config PLL
    base->PLLCFGR = 0;
    base->PLLCFGR |= (config.pllm << 0U) | (config.plln << 6U) | (RCC_PLLCFGR_PLLSRC_HSI << 22U) | (config.pllp << 16U) | (config.pllq << 24U);

    // activate PLL
    base->CR |= RCC_CR_PLLON;
    while (!(base->CR & RCC_CR_PLLRDY))
        ;

    // Change HSI to PLL
    base->CFGR &= ~RCC_CFGR_SW;
    base->CFGR |= RCC_CFGR_SW_PLL;
    while ((base->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL)
        ;
}

Например, следующие значения:

hsi = 16MHz
pllm = 8 
plln = 96
pllp = 2

=> sysclk = ((16MHz / 8) * 96) / 2 = 96MHz

ahb_prescaler = 1 
=> hclk = 96MHz

apb1_prescaler = 2 
=> pckl1 = 48MHz
=> pclk1_timer = pclk1 * 2 (As apb1 != 1 and TIMPRE = 0) (Rule from TIMPRE Register)

Как простое приложение для проверки частоты я использовал таймер, который просто считает до 1000, а затем перезагружается.

Input 96MHz 
PSC = 47999 => 2KHz frequency
ARR = 2000 => Overflow once a second

Однако я получаю переполнение через 3 секунды => таймер работает не на 96 МГц, а на 32 МГц.

Я также проверил, что с другими конфигурациями, такими как pclk1_timer = 48MHz, всегда кажется, что вход таймера находится на 32MHz. (Через 1,5 с происходит переполнение)

Я что-то упустил в своей конфигурации?

...