У меня проблема с настройкой частотного входа таймера. Я пару раз прочитал справочное руководство, а затем поискал в Интернете решение.
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 с происходит переполнение)
Я что-то упустил в своей конфигурации?